From 040f077faf0b71fe507e303ed0f208ba5ffff483 Mon Sep 17 00:00:00 2001 From: Philipp Hoenisch Date: Wed, 25 Mar 2020 13:32:51 +1100 Subject: [PATCH 01/88] Add GitHub Action CI Workflow --- .github/workflows/ci.yml | 128 +++++++++++++++++++++++++++++++++++++++ Makefile | 3 + api_tests/package.json | 1 + 3 files changed, 132 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..650fe5be2c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,128 @@ +name: CI + +on: + push: + branches-ignore: + - 'staging.tmp' + - 'trying.tmp' + +jobs: + static_analysis: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v1 + + - name: Extract toolchain version from rust-toolchain + run: echo "::set-env name=RUST_TOOLCHAIN::$(cat rust-toolchain)" + + - name: Install ${{ env.RUST_TOOLCHAIN }} toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ env.RUST_TOOLCHAIN }} + override: true + + - name: Cache ~/.cargo/bin directory + uses: actions/cache@v1 + with: + path: ~/.cargo/bin + key: ubuntu-rust-${{ env.RUST_TOOLCHAIN }}-cargo-bin-directory + + - name: Check formatting + run: make check_format + + - name: Run linter + run: make clippy + + build: + strategy: + matrix: + os: [macos-latest, ubuntu-latest] + include: + - os: ubuntu-latest + binary-suffix: "" + - os: macos-latest + binary-suffix: "" + runs-on: ${{ matrix.os }} + steps: + - name: Checkout sources + uses: actions/checkout@v1 + + - name: Extract toolchain version from rust-toolchain + run: echo "::set-env name=RUST_TOOLCHAIN::$(cat rust-toolchain)" + + - name: Install ${{ env.RUST_TOOLCHAIN }} toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ env.RUST_TOOLCHAIN }} + override: true + + - name: Cache target directory + uses: actions/cache@v1 + with: + path: target + key: ${{ matrix.os }}-rust-${{ env.RUST_TOOLCHAIN }}-target-directory-${{ hashFiles('Cargo.lock') }} + + - name: Cache ~/.cargo/registry directory + uses: actions/cache@v1 + with: + path: ~/.cargo/registry + key: ${{ matrix.os }}-rust-${{ env.RUST_TOOLCHAIN }}-cargo-registry-directory-${{ hashFiles('Cargo.lock') }} + + - name: Build ${{ matrix.os }} binary + run: make build + + # Ignore tests on macos due to missing docker + - name: Run unit tests + if: matrix.os != 'macos-latest' + run: make test + + - name: Upload cnd ${{ matrix.os }} binary + if: matrix.os == 'ubuntu-latest' + uses: actions/upload-artifact@v1 + with: + name: cnd + path: target/debug/cnd + + + e2e_test: + runs-on: ubuntu-latest + needs: build + steps: + - name: Checkout sources + uses: actions/checkout@v1 + + - name: Download cnd binary + uses: actions/download-artifact@v1 + with: + name: cnd + path: target/debug/ + + - name: Fix missing executable permission + run: | + chmod a+x target/debug/cnd + + - name: Install NodeJS 12.x + uses: actions/setup-node@v1 + with: + node-version: '12.x' + + - name: Install Go 1.13.3. + uses: actions/setup-go@v1 + with: + go-version: '1.13.3' + + - name: Install LND v0.9.0-beta + run: | + go get -d github.com/lightningnetwork/lnd + cd ~/go/src/github.com/lightningnetwork/lnd + git checkout v0.9.0-beta + make tags=invoicesrpc + make tags=invoicesrpc install + + - name: Run e2e tests + run: | + export PATH=$HOME/.cargo/bin:$HOME/.local/bin:$HOME/go/bin:$PATH + make ci_gha diff --git a/Makefile b/Makefile index ffc4cc8260..dc3cfea4b8 100644 --- a/Makefile +++ b/Makefile @@ -85,6 +85,9 @@ doc: e2e: download_bc_nodes build (cd ./api_tests; yarn install; yarn test) +ci_gha: download_bc_nodes + (cd ./api_tests; yarn install; yarn ci) + check_format: check_rust_format check_toml_format check_ts_format MODIFIED_FILES = $(shell git status --untracked-files=no --short) diff --git a/api_tests/package.json b/api_tests/package.json index dc62f2ec72..2b869761b1 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -9,6 +9,7 @@ "dry": "jest --config jest.config-dry.js --maxWorkers=4", "e2e": "yarn jest --config jest.config-e2e.js --runInBand --forceExit --bail", "test": "yarn dry && yarn e2e", + "ci": "tsc && yarn dry && yarn e2e", "fix": "tslint --project . --fix && prettier --write '**/*.{ts,js,json,yml}'" }, "engines": { From a3e860a60d9922c877655c62371b0888e98e5814 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 26 Mar 2020 15:06:03 +1100 Subject: [PATCH 02/88] Create a separate OutEvent enum for the oneshot_protocol This allows us to change the NetworkBehaviour's OutEvent type to include the PeerId. Otherwise we would loose this information. --- cnd/src/network/oneshot_behaviour.rs | 55 ++++++++++++++-------------- cnd/src/network/oneshot_protocol.rs | 23 +++++++++--- 2 files changed, 45 insertions(+), 33 deletions(-) diff --git a/cnd/src/network/oneshot_behaviour.rs b/cnd/src/network/oneshot_behaviour.rs index 942828f55a..c542ca4947 100644 --- a/cnd/src/network/oneshot_behaviour.rs +++ b/cnd/src/network/oneshot_behaviour.rs @@ -28,28 +28,13 @@ impl Default for Behaviour { } } -/// Event generated by the NetworkBehaviour and that the swarm will report back. -#[derive(Clone, Copy, Debug)] +/// Events emitted from the NetworkBehaviour up to the swarm. +#[derive(Debug)] pub enum OutEvent { - /// Emitted once we receive a message from the other peer. - Received(M), - /// Emitted once we successfully sent a message to the other peer. - Sent, -} - -impl From for OutEvent -where - M: oneshot_protocol::Message, -{ - fn from(msg: M) -> Self { - OutEvent::Received(msg) - } -} - -impl From<()> for OutEvent { - fn from(_: ()) -> Self { - OutEvent::Sent - } + /// We received the message M from the given peer. + Received { peer: PeerId, message: M }, + /// We sent the message M to given peer. + Sent { peer: PeerId, message: M }, } impl NetworkBehaviour for Behaviour @@ -59,7 +44,7 @@ where type ProtocolsHandler = OneShotHandler< oneshot_protocol::InboundConfig, oneshot_protocol::OutboundConfig, - OutEvent, + oneshot_protocol::OutEvent, >; type OutEvent = OutEvent; @@ -79,23 +64,37 @@ where // Do nothing, announce protocol is going to take care of connections. } - fn inject_node_event(&mut self, peer_id: PeerId, event: OutEvent) { + fn inject_node_event(&mut self, peer: PeerId, event: oneshot_protocol::OutEvent) { match event { - OutEvent::Received(message) => { + oneshot_protocol::OutEvent::Received(message) => { trace!( "Received message from {} on protocol {}: {:?}", - peer_id, + peer, M::INFO, message ); // Add the message to be dispatched to the user. self.events - .push_back(NetworkBehaviourAction::GenerateEvent(OutEvent::Received( + .push_back(NetworkBehaviourAction::GenerateEvent(OutEvent::Received { + peer, + message, + })); + } + oneshot_protocol::OutEvent::Sent(message) => { + trace!( + "Sent message {:?} to {} on protocol {}", + message, + peer, + M::INFO + ); + + self.events + .push_back(NetworkBehaviourAction::GenerateEvent(OutEvent::Sent { + peer, message, - ))); + })); } - OutEvent::Sent => trace!("Sent message to {} on protocol {}", peer_id, M::INFO), } } diff --git a/cnd/src/network/oneshot_protocol.rs b/cnd/src/network/oneshot_protocol.rs index 3bc71a88f6..d5ed475dc7 100644 --- a/cnd/src/network/oneshot_protocol.rs +++ b/cnd/src/network/oneshot_protocol.rs @@ -25,6 +25,19 @@ pub struct OutboundConfig { msg: M, } +/// Events that are produced as part of the connection upgrade. +/// +/// The oneshot protocol is push-based, meaning the outbound upgrade will +/// generate the `Sent` event whereas the inbound upgrade will generate the +/// `Received` event. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum OutEvent { + /// Emitted once we receive a message from the other peer. + Received(M), + /// Emitted once we successfully sent a message to the other peer. + Sent(M), +} + impl UpgradeInfo for OutboundConfig where M: Message, @@ -42,7 +55,7 @@ where C: AsyncWrite + Unpin + Send + 'static, M: Serialize + Message + Send + 'static, { - type Output = (); + type Output = OutEvent; type Error = Error; type Future = BoxFuture<'static, Result>; @@ -55,7 +68,7 @@ where let bytes = serde_json::to_vec(&self.msg)?; upgrade::write_one(&mut socket, &bytes).await?; - Ok(()) + Ok(OutEvent::Sent(self.msg)) }) } } @@ -94,7 +107,7 @@ where C: AsyncRead + Unpin + Send + 'static, M: DeserializeOwned + Message, { - type Output = M; + type Output = OutEvent; type Error = Error; type Future = BoxFuture<'static, Result>; @@ -108,7 +121,7 @@ where let mut de = serde_json::Deserializer::from_slice(&message); let info = M::deserialize(&mut de)?; - Ok(info) + Ok(OutEvent::Received(info)) }) } } @@ -176,6 +189,6 @@ mod tests { let config = InboundConfig::::default(); let received_msg = upgrade::apply_inbound(conn, config).await.unwrap(); - assert_eq!(received_msg, sent_msg) + assert_eq!(received_msg, OutEvent::Received(sent_msg)) } } From 521fd522cd012db6c7d423edf9cafc4d8925f3f1 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2020 14:12:34 +0000 Subject: [PATCH 03/88] Bump testcontainers from 0.8.1 to 0.9.1 Bumps [testcontainers](https://github.com/testcontainers/testcontainers-rs) from 0.8.1 to 0.9.1. - [Release notes](https://github.com/testcontainers/testcontainers-rs/releases) - [Changelog](https://github.com/testcontainers/testcontainers-rs/blob/0.9.1/CHANGELOG.md) - [Commits](https://github.com/testcontainers/testcontainers-rs/compare/0.8.1...0.9.1) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- cnd/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6a96e83f1c..a2e78f100c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3625,9 +3625,9 @@ dependencies = [ [[package]] name = "testcontainers" -version = "0.8.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aacbbd75f3df9b76dcb5ef222594e94780d5da271d2e533e2e00d4b001877c5" +checksum = "af06783709f5254b087f0a1ea4557e372a5c2c597ca4a1157fbe536b1de2fb19" dependencies = [ "derivative 1.0.4", "hex 0.4.2", diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index db189bb33d..95aa778e45 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -70,4 +70,4 @@ regex = "1.3" serde_urlencoded = "0.6" spectral = { version = "0.6", default-features = false } tempfile = "3.1.0" -testcontainers = "0.8" +testcontainers = "0.9" From 161d2c734b8e7904ff5370430da786b166d5c86c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2020 15:41:17 +0000 Subject: [PATCH 04/88] Bump jest from 25.1.0 to 25.2.1 in /api_tests Bumps [jest](https://github.com/facebook/jest) from 25.1.0 to 25.2.1. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/compare/v25.1.0...v25.2.1) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 887 +++++++++++++++++++---------------------- 2 files changed, 402 insertions(+), 487 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index a5808d1bc2..ef2c9786eb 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -45,7 +45,7 @@ "comit-sdk": "^0.15.1", "ethers": "^4.0.46", "get-port": "^5.1.1", - "jest": "^25.1.0", + "jest": "^25.2.1", "js-sha256": "^0.9.0", "log4js": "^6.1.2", "prettier": "^2.0.2", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 95005212bf..fb2d71d0ee 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -179,81 +179,80 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== -"@jest/console@^25.1.0": - version "25.1.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-25.1.0.tgz#1fc765d44a1e11aec5029c08e798246bd37075ab" - integrity sha512-3P1DpqAMK/L07ag/Y9/Jup5iDEG9P4pRAuZiMQnU0JB3UOvCyYCjCoxr7sIA80SeyUCUKrr24fKAxVpmBgQonA== +"@jest/console@^25.2.1": + version "25.2.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-25.2.1.tgz#63b35b6a2b67f26866f8dcbb9725452a1c8c0d3b" + integrity sha512-v3tkMr5AeVm6R23wnZdC5dzXdHPFa6j2uiTC15iHISYkGIilE9O1qmAYKELHPXZifDbz9c8WwzsqoN8K8uG4jg== dependencies: - "@jest/source-map" "^25.1.0" + "@jest/source-map" "^25.2.1" chalk "^3.0.0" - jest-util "^25.1.0" + jest-util "^25.2.1" slash "^3.0.0" -"@jest/core@^25.1.0": - version "25.1.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-25.1.0.tgz#3d4634fc3348bb2d7532915d67781cdac0869e47" - integrity sha512-iz05+NmwCmZRzMXvMo6KFipW7nzhbpEawrKrkkdJzgytavPse0biEnCNr2wRlyCsp3SmKaEY+SGv7YWYQnIdig== - dependencies: - "@jest/console" "^25.1.0" - "@jest/reporters" "^25.1.0" - "@jest/test-result" "^25.1.0" - "@jest/transform" "^25.1.0" - "@jest/types" "^25.1.0" +"@jest/core@^25.2.1": + version "25.2.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-25.2.1.tgz#05191bada9ec5d322775454342cbd7b13dd3a691" + integrity sha512-Pe7CVcysOmm69BgdgAuMjRCp6vmcCJy32PxPtArQDgiizIBQElHhE9P34afGwPgSb3+e3WC6XtEm4de7d9BtfQ== + dependencies: + "@jest/console" "^25.2.1" + "@jest/reporters" "^25.2.1" + "@jest/test-result" "^25.2.1" + "@jest/transform" "^25.2.1" + "@jest/types" "^25.2.1" ansi-escapes "^4.2.1" chalk "^3.0.0" exit "^0.1.2" graceful-fs "^4.2.3" - jest-changed-files "^25.1.0" - jest-config "^25.1.0" - jest-haste-map "^25.1.0" - jest-message-util "^25.1.0" - jest-regex-util "^25.1.0" - jest-resolve "^25.1.0" - jest-resolve-dependencies "^25.1.0" - jest-runner "^25.1.0" - jest-runtime "^25.1.0" - jest-snapshot "^25.1.0" - jest-util "^25.1.0" - jest-validate "^25.1.0" - jest-watcher "^25.1.0" + jest-changed-files "^25.2.1" + jest-config "^25.2.1" + jest-haste-map "^25.2.1" + jest-message-util "^25.2.1" + jest-regex-util "^25.2.1" + jest-resolve "^25.2.1" + jest-resolve-dependencies "^25.2.1" + jest-runner "^25.2.1" + jest-runtime "^25.2.1" + jest-snapshot "^25.2.1" + jest-util "^25.2.1" + jest-validate "^25.2.1" + jest-watcher "^25.2.1" micromatch "^4.0.2" p-each-series "^2.1.0" - realpath-native "^1.1.0" + realpath-native "^2.0.0" rimraf "^3.0.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^25.1.0": - version "25.1.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-25.1.0.tgz#4a97f64770c9d075f5d2b662b5169207f0a3f787" - integrity sha512-cTpUtsjU4cum53VqBDlcW0E4KbQF03Cn0jckGPW/5rrE9tb+porD3+hhLtHAwhthsqfyF+bizyodTlsRA++sHg== +"@jest/environment@^25.2.1": + version "25.2.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-25.2.1.tgz#d967f38c05accfb2dba325e93238684e8b1706bd" + integrity sha512-aeA3UlUmpblmv2CHBcNA7LvcXlcCtRpXaKKFVooRy9/Jk8B4IZAZMfrML/d+1cG5FpF17s4JVdu1kx0mbnaqTQ== dependencies: - "@jest/fake-timers" "^25.1.0" - "@jest/types" "^25.1.0" - jest-mock "^25.1.0" + "@jest/fake-timers" "^25.2.1" + "@jest/types" "^25.2.1" + jest-mock "^25.2.1" -"@jest/fake-timers@^25.1.0": - version "25.1.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.1.0.tgz#a1e0eff51ffdbb13ee81f35b52e0c1c11a350ce8" - integrity sha512-Eu3dysBzSAO1lD7cylZd/CVKdZZ1/43SF35iYBNV1Lvvn2Undp3Grwsv8PrzvbLhqwRzDd4zxrY4gsiHc+wygQ== +"@jest/fake-timers@^25.2.1": + version "25.2.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.2.1.tgz#caaaea22e810796d3538a77fdce6e554c864ae72" + integrity sha512-H1OC8AktrGTD10NHBauICkRCv7VOOrsgI8xokifAsxJMYhqoKBtJZbk2YpbrtnmdTUnk+qoxPUk+Mufwnl44iQ== dependencies: - "@jest/types" "^25.1.0" - jest-message-util "^25.1.0" - jest-mock "^25.1.0" - jest-util "^25.1.0" + "@jest/types" "^25.2.1" + jest-message-util "^25.2.1" + jest-mock "^25.2.1" + jest-util "^25.2.1" lolex "^5.0.0" -"@jest/reporters@^25.1.0": - version "25.1.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-25.1.0.tgz#9178ecf136c48f125674ac328f82ddea46e482b0" - integrity sha512-ORLT7hq2acJQa8N+NKfs68ZtHFnJPxsGqmofxW7v7urVhzJvpKZG9M7FAcgh9Ee1ZbCteMrirHA3m5JfBtAaDg== +"@jest/reporters@^25.2.1": + version "25.2.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-25.2.1.tgz#c5bc848393f48f3cf141957ba51fc4c1598ddb3a" + integrity sha512-jAnIECIIFVHiASKLpPBpZ9fIgWolKdMwUuyjSlNVixmtX6G83fyiGaOquaAU1ukAxnlKdCLjvH6BYdY+GGbd5Q== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^25.1.0" - "@jest/environment" "^25.1.0" - "@jest/test-result" "^25.1.0" - "@jest/transform" "^25.1.0" - "@jest/types" "^25.1.0" + "@jest/console" "^25.2.1" + "@jest/test-result" "^25.2.1" + "@jest/transform" "^25.2.1" + "@jest/types" "^25.2.1" chalk "^3.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" @@ -263,11 +262,10 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.0.0" - jest-haste-map "^25.1.0" - jest-resolve "^25.1.0" - jest-runtime "^25.1.0" - jest-util "^25.1.0" - jest-worker "^25.1.0" + jest-haste-map "^25.2.1" + jest-resolve "^25.2.1" + jest-util "^25.2.1" + jest-worker "^25.2.1" slash "^3.0.0" source-map "^0.6.0" string-length "^3.1.0" @@ -276,54 +274,54 @@ optionalDependencies: node-notifier "^6.0.0" -"@jest/source-map@^25.1.0": - version "25.1.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-25.1.0.tgz#b012e6c469ccdbc379413f5c1b1ffb7ba7034fb0" - integrity sha512-ohf2iKT0xnLWcIUhL6U6QN+CwFWf9XnrM2a6ybL9NXxJjgYijjLSitkYHIdzkd8wFliH73qj/+epIpTiWjRtAA== +"@jest/source-map@^25.2.1": + version "25.2.1" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-25.2.1.tgz#b62ecf8ae76170b08eff8859b56eb7576df34ab8" + integrity sha512-PgScGJm1U27+9Te/cxP4oUFqJ2PX6NhBL2a6unQ7yafCgs8k02c0LSyjSIx/ao0AwcAdCczfAPDf5lJ7zoB/7A== dependencies: callsites "^3.0.0" graceful-fs "^4.2.3" source-map "^0.6.0" -"@jest/test-result@^25.1.0": - version "25.1.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.1.0.tgz#847af2972c1df9822a8200457e64be4ff62821f7" - integrity sha512-FZzSo36h++U93vNWZ0KgvlNuZ9pnDnztvaM7P/UcTx87aPDotG18bXifkf1Ji44B7k/eIatmMzkBapnAzjkJkg== +"@jest/test-result@^25.2.1": + version "25.2.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.2.1.tgz#dc8d26d4329c055733bd5ad6dc4eda190fbacd3b" + integrity sha512-E0tlWh2iOELRLbbPEngs3Dsx88vGBQOs6O3w46YeXfMHlwwqzWrlvoeUq6kRlHRm1O8H+EBr60Wtrwh20C+zWQ== dependencies: - "@jest/console" "^25.1.0" - "@jest/transform" "^25.1.0" - "@jest/types" "^25.1.0" + "@jest/console" "^25.2.1" + "@jest/transform" "^25.2.1" + "@jest/types" "^25.2.1" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^25.1.0": - version "25.1.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-25.1.0.tgz#4df47208542f0065f356fcdb80026e3c042851ab" - integrity sha512-WgZLRgVr2b4l/7ED1J1RJQBOharxS11EFhmwDqknpknE0Pm87HLZVS2Asuuw+HQdfQvm2aXL2FvvBLxOD1D0iw== +"@jest/test-sequencer@^25.2.1": + version "25.2.1" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-25.2.1.tgz#b4e75d46aacabbf24cbf4b0a900253c899980856" + integrity sha512-yEhVlBRS7pg3MGBIQQafYfm2NT5trFa/qoxtLftQoZmyzKx3rPy0oJ+d/8QljK4X2RGY/i7mmQDxE6sGR9UqeQ== dependencies: - "@jest/test-result" "^25.1.0" - jest-haste-map "^25.1.0" - jest-runner "^25.1.0" - jest-runtime "^25.1.0" + "@jest/test-result" "^25.2.1" + jest-haste-map "^25.2.1" + jest-runner "^25.2.1" + jest-runtime "^25.2.1" -"@jest/transform@^25.1.0": - version "25.1.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-25.1.0.tgz#221f354f512b4628d88ce776d5b9e601028ea9da" - integrity sha512-4ktrQ2TPREVeM+KxB4zskAT84SnmG1vaz4S+51aTefyqn3zocZUnliLLm5Fsl85I3p/kFPN4CRp1RElIfXGegQ== +"@jest/transform@^25.2.1": + version "25.2.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-25.2.1.tgz#08481795277b6ff9d7cb703eb4425ed46861bedc" + integrity sha512-puoD5EfqPeZ5m0dV9l8+PMdOVdRjeWcaEjGkH+eG45l0nPJ2vRcxu8J6CRl/6nQ5ZTHgg7LuM9C6FauNpdRpUA== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^25.1.0" + "@jest/types" "^25.2.1" babel-plugin-istanbul "^6.0.0" chalk "^3.0.0" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" graceful-fs "^4.2.3" - jest-haste-map "^25.1.0" - jest-regex-util "^25.1.0" - jest-util "^25.1.0" + jest-haste-map "^25.2.1" + jest-regex-util "^25.2.1" + jest-util "^25.2.1" micromatch "^4.0.2" pirates "^4.0.1" - realpath-native "^1.1.0" + realpath-native "^2.0.0" slash "^3.0.0" source-map "^0.6.1" write-file-atomic "^3.0.0" @@ -338,6 +336,16 @@ "@types/yargs" "^15.0.0" chalk "^3.0.0" +"@jest/types@^25.2.1": + version "25.2.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.2.1.tgz#692c8950d4c21fc6b4cfd141c3470b735c5bffca" + integrity sha512-WuGFGJ3Rrycg+5ZwQTWKjr21M9psANPAWYD28K42hSeUzhv1H591VXIoq0tjs00mydhNOgVOkKSpzRS3CrOYFw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^15.0.0" + chalk "^3.0.0" + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -571,6 +579,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.17.tgz#7a183163a9e6ff720d86502db23ba4aade5999b8" integrity sha512-gpNnRnZP3VWzzj5k3qrpRC6Rk3H/uclhAVo1aIvwzK5p5cOrs9yEyQ8H/HBsBY0u5rrWxXEiVPQ0dEB6pkjE8Q== +"@types/prettier@^1.19.0": + version "1.19.1" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.19.1.tgz#33509849f8e679e4add158959fdb086440e9553f" + integrity sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ== + "@types/rimraf@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-3.0.0.tgz#b9d03f090ece263671898d57bb7bb007023ac19f" @@ -868,16 +881,16 @@ axios@^0.19.0: follow-redirects "1.5.10" is-buffer "^2.0.2" -babel-jest@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.1.0.tgz#206093ac380a4b78c4404a05b3277391278f80fb" - integrity sha512-tz0VxUhhOE2y+g8R2oFrO/2VtVjA1lkJeavlhExuRBg3LdNJY9gwQ+Vcvqt9+cqy71MCTJhewvTB7Qtnnr9SWg== +babel-jest@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.2.1.tgz#d01ff8025b305a886421b176f3d99ec5461b23b7" + integrity sha512-OiBpQGYtV4rWMuFneIaEsqJB0VdoOBw4SqwO4hA2EhDY/O8RylQ20JwALkxv8iv+CYnyrZZfF+DELPgrdrkRIw== dependencies: - "@jest/transform" "^25.1.0" - "@jest/types" "^25.1.0" + "@jest/transform" "^25.2.1" + "@jest/types" "^25.2.1" "@types/babel__core" "^7.1.0" babel-plugin-istanbul "^6.0.0" - babel-preset-jest "^25.1.0" + babel-preset-jest "^25.2.1" chalk "^3.0.0" slash "^3.0.0" @@ -892,21 +905,21 @@ babel-plugin-istanbul@^6.0.0: istanbul-lib-instrument "^4.0.0" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.1.0.tgz#fb62d7b3b53eb36c97d1bc7fec2072f9bd115981" - integrity sha512-oIsopO41vW4YFZ9yNYoLQATnnN46lp+MZ6H4VvPKFkcc2/fkl3CfE/NZZSmnEIEsJRmJAgkVEK0R7Zbl50CpTw== +babel-plugin-jest-hoist@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.2.1.tgz#d0003a1f3d5caa281e1107fe03bbf16b799f9955" + integrity sha512-HysbCQfJhxLlyxDbKcB2ucGYV0LjqK4h6dBoI3RtFuOxTiTWK6XGZMsHb0tGh8iJdV4hC6Z2GCHzVvDeh9i0lQ== dependencies: "@types/babel__traverse" "^7.0.6" -babel-preset-jest@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-25.1.0.tgz#d0aebfebb2177a21cde710996fce8486d34f1d33" - integrity sha512-eCGn64olaqwUMaugXsTtGAM2I0QTahjEtnRu0ql8Ie+gDWAc1N6wqN0k2NilnyTunM69Pad7gJY7LOtwLimoFQ== +babel-preset-jest@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-25.2.1.tgz#4ccd0e577f69aa11b71806edfe8b25a5c3ac93a2" + integrity sha512-zXHJBM5iR8oEO4cvdF83AQqqJf3tJrXy3x8nfu2Nlqvn4cneg4Ca8M7cQvC5S9BzDDy1O0tZ9iXru9J6E3ym+A== dependencies: "@babel/plugin-syntax-bigint" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - babel-plugin-jest-hoist "^25.1.0" + babel-plugin-jest-hoist "^25.2.1" balanced-match@^1.0.0: version "1.0.0" @@ -1751,12 +1764,10 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= -define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== define-property@^0.2.5: version "0.2.5" @@ -1815,6 +1826,11 @@ diff-sequences@^25.1.0: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.1.0.tgz#fd29a46f1c913fd66c22645dc75bffbe43051f32" integrity sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw== +diff-sequences@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.1.tgz#fcfe8aa07dd9b0c648396a478dabca8e76c6ab27" + integrity sha512-foe7dXnGlSh3jR1ovJmdv+77VQj98eKCHHwJPbZ2eEf0fHwKbkZicpPxEch9smZ+n2dnF6QFwkOQdLq9hpeJUg== + diff@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff" @@ -1877,32 +1893,6 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" -es-abstract@^1.17.0-next.1, es-abstract@^1.17.2: - version "1.17.4" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184" - integrity sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.1.5" - is-regex "^1.0.5" - object-inspect "^1.7.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimleft "^2.1.1" - string.prototype.trimright "^2.1.1" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -2012,17 +2002,17 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-25.1.0.tgz#7e8d7b06a53f7d66ec927278db3304254ee683ee" - integrity sha512-wqHzuoapQkhc3OKPlrpetsfueuEiMf3iWh0R8+duCu9PIjXoP7HgD5aeypwTnXUAjC8aMsiVDaWwlbJ1RlQ38g== +expect@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-25.2.1.tgz#f543b6a7fee921c554b5eec9b8ca384551dccedd" + integrity sha512-mRvuu0xujdgYuS0S2dZ489PGAcXl60blmsLofaq7heqn+ZcUOox+VWQvrCee/x+/0WBpxDs7pBWuFYNO5U+txQ== dependencies: - "@jest/types" "^25.1.0" + "@jest/types" "^25.2.1" ansi-styles "^4.0.0" - jest-get-type "^25.1.0" - jest-matcher-utils "^25.1.0" - jest-message-util "^25.1.0" - jest-regex-util "^25.1.0" + jest-get-type "^25.2.1" + jest-matcher-utils "^25.2.1" + jest-message-util "^25.2.1" + jest-regex-util "^25.2.1" express@^4.17.1: version "4.17.1" @@ -2255,11 +2245,6 @@ fsevents@^2.1.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805" integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA== -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -2403,16 +2388,6 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" - integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= - -has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== - has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -2449,13 +2424,6 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - hash.js@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" @@ -2618,16 +2586,6 @@ is-buffer@^2.0.2: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== -is-callable@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" - integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== - -is-callable@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" - integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== - is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" @@ -2649,11 +2607,6 @@ is-data-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-date-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" - integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= - is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" @@ -2732,13 +2685,6 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-regex@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" - integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== - dependencies: - has "^1.0.3" - is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -2749,13 +2695,6 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== -is-symbol@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" - integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== - dependencies: - has-symbols "^1.0.0" - is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -2842,56 +2781,57 @@ istanbul-reports@^3.0.0: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jest-changed-files@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-25.1.0.tgz#73dae9a7d9949fdfa5c278438ce8f2ff3ec78131" - integrity sha512-bdL1aHjIVy3HaBO3eEQeemGttsq1BDlHgWcOjEOIAcga7OOEGWHD2WSu8HhL7I1F0mFFyci8VKU4tRNk+qtwDA== +jest-changed-files@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-25.2.1.tgz#2dca2c81980479c940addee863d8e73cc3a6b322" + integrity sha512-BB4XjM/dJNUAUtchZ2yJq50VK8XXbmgvt1MUD6kzgzoyz9F0+1ZDQ1yNvLl6pfDwKrMBG9GBY1lzaIBO3JByMg== dependencies: - "@jest/types" "^25.1.0" + "@jest/types" "^25.2.1" execa "^3.2.0" throat "^5.0.0" -jest-cli@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-25.1.0.tgz#75f0b09cf6c4f39360906bf78d580be1048e4372" - integrity sha512-p+aOfczzzKdo3AsLJlhs8J5EW6ffVidfSZZxXedJ0mHPBOln1DccqFmGCoO8JWd4xRycfmwy1eoQkMsF8oekPg== +jest-cli@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-25.2.1.tgz#b83436541d79cf150b79dd6dbc0acbfc15fc383b" + integrity sha512-7moIaOsKvifiHpCUorpSHb3ALHpyZB9SlrFsvkloEo31KTTgFkHZuQw68LJX8FJwY6pg9LoxJJ2Vy4AFmHMclQ== dependencies: - "@jest/core" "^25.1.0" - "@jest/test-result" "^25.1.0" - "@jest/types" "^25.1.0" + "@jest/core" "^25.2.1" + "@jest/test-result" "^25.2.1" + "@jest/types" "^25.2.1" chalk "^3.0.0" exit "^0.1.2" import-local "^3.0.2" is-ci "^2.0.0" - jest-config "^25.1.0" - jest-util "^25.1.0" - jest-validate "^25.1.0" + jest-config "^25.2.1" + jest-util "^25.2.1" + jest-validate "^25.2.1" prompts "^2.0.1" - realpath-native "^1.1.0" - yargs "^15.0.0" + realpath-native "^2.0.0" + yargs "^15.3.1" -jest-config@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-25.1.0.tgz#d114e4778c045d3ef239452213b7ad3ec1cbea90" - integrity sha512-tLmsg4SZ5H7tuhBC5bOja0HEblM0coS3Wy5LTCb2C8ZV6eWLewHyK+3qSq9Bi29zmWQ7ojdCd3pxpx4l4d2uGw== +jest-config@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-25.2.1.tgz#44c0d39ac8240a46f051708ba22d513481e45201" + integrity sha512-Kh6a3stGSCtVwucvD9wSMaEQBmU0CfqVjHvf0X0iLfCrZfsezvV+sGgRWQAidaTIvo51yAaL217xOwEETMqh6w== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^25.1.0" - "@jest/types" "^25.1.0" - babel-jest "^25.1.0" + "@jest/test-sequencer" "^25.2.1" + "@jest/types" "^25.2.1" + babel-jest "^25.2.1" chalk "^3.0.0" + deepmerge "^4.2.2" glob "^7.1.1" - jest-environment-jsdom "^25.1.0" - jest-environment-node "^25.1.0" - jest-get-type "^25.1.0" - jest-jasmine2 "^25.1.0" - jest-regex-util "^25.1.0" - jest-resolve "^25.1.0" - jest-util "^25.1.0" - jest-validate "^25.1.0" + jest-environment-jsdom "^25.2.1" + jest-environment-node "^25.2.1" + jest-get-type "^25.2.1" + jest-jasmine2 "^25.2.1" + jest-regex-util "^25.2.1" + jest-resolve "^25.2.1" + jest-util "^25.2.1" + jest-validate "^25.2.1" micromatch "^4.0.2" - pretty-format "^25.1.0" - realpath-native "^1.1.0" + pretty-format "^25.2.1" + realpath-native "^2.0.0" jest-diff@^25.1.0: version "25.1.0" @@ -2903,292 +2843,310 @@ jest-diff@^25.1.0: jest-get-type "^25.1.0" pretty-format "^25.1.0" -jest-docblock@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-25.1.0.tgz#0f44bea3d6ca6dfc38373d465b347c8818eccb64" - integrity sha512-370P/mh1wzoef6hUKiaMcsPtIapY25suP6JqM70V9RJvdKLrV4GaGbfUseUVk4FZJw4oTZ1qSCJNdrClKt5JQA== +jest-diff@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.2.1.tgz#8c073596cc88356227c86a50d71a23d8a9dfa81a" + integrity sha512-e/TU8VLBBGQQS9tXA5B5LeT806jh7CHUeHbBfrU9UvA2zTbOTRz71UD6fAP1HAhzUEyCVLU2ZP5e8X16A9b0Fg== + dependencies: + chalk "^3.0.0" + diff-sequences "^25.2.1" + jest-get-type "^25.2.1" + pretty-format "^25.2.1" + +jest-docblock@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-25.2.0.tgz#b1b78e275131bcaa9a5722e663545ed949c278ee" + integrity sha512-M7ZDbghaxFd2unWkyDFGLZDjPpIbDtEbICXSzwGrUBccFwVG/1dhLLAYX3D+98bFksaJuM0iMZGuIQUzKgnkQw== dependencies: detect-newline "^3.0.0" -jest-each@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-25.1.0.tgz#a6b260992bdf451c2d64a0ccbb3ac25e9b44c26a" - integrity sha512-R9EL8xWzoPySJ5wa0DXFTj7NrzKpRD40Jy+zQDp3Qr/2QmevJgkN9GqioCGtAJ2bW9P/MQRznQHQQhoeAyra7A== +jest-each@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-25.2.1.tgz#d96b4fc0c035fcddb852f19da42ea241b1943999" + integrity sha512-2vWAaf11IJsSwkEzGph3un4OMSG4v/3hpM2UqJdeU3peGUgUSn75TlXZGQnT0smbnAr4eE+URW1OpE8U9wl0TA== dependencies: - "@jest/types" "^25.1.0" + "@jest/types" "^25.2.1" chalk "^3.0.0" - jest-get-type "^25.1.0" - jest-util "^25.1.0" - pretty-format "^25.1.0" + jest-get-type "^25.2.1" + jest-util "^25.2.1" + pretty-format "^25.2.1" -jest-environment-jsdom@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-25.1.0.tgz#6777ab8b3e90fd076801efd3bff8e98694ab43c3" - integrity sha512-ILb4wdrwPAOHX6W82GGDUiaXSSOE274ciuov0lztOIymTChKFtC02ddyicRRCdZlB5YSrv3vzr1Z5xjpEe1OHQ== +jest-environment-jsdom@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-25.2.1.tgz#4f1da1bc46897c6ed818c850464b1114429e3ad5" + integrity sha512-bUhhhXtgrOgLhsFQFXgao8CQPYAEwtaVvhsF6O0A7Ie2uPONtAKCwuxyOM9WJaz9ag2ci5Pg7i2V2PRfGLl95w== dependencies: - "@jest/environment" "^25.1.0" - "@jest/fake-timers" "^25.1.0" - "@jest/types" "^25.1.0" - jest-mock "^25.1.0" - jest-util "^25.1.0" - jsdom "^15.1.1" + "@jest/environment" "^25.2.1" + "@jest/fake-timers" "^25.2.1" + "@jest/types" "^25.2.1" + jest-mock "^25.2.1" + jest-util "^25.2.1" + jsdom "^15.2.1" -jest-environment-node@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-25.1.0.tgz#797bd89b378cf0bd794dc8e3dca6ef21126776db" - integrity sha512-U9kFWTtAPvhgYY5upnH9rq8qZkj6mYLup5l1caAjjx9uNnkLHN2xgZy5mo4SyLdmrh/EtB9UPpKFShvfQHD0Iw== +jest-environment-node@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-25.2.1.tgz#d28f1cd18425417a2b9b8b0d81553f4850f8f879" + integrity sha512-HiAAwx4HrkaV9YAyuI56dmPDuTDckJyPpO0BwCu7+Ht2fmlMDhX13HZyyuIGTAIjUrjJiM3paB8tht+0mXtiIA== dependencies: - "@jest/environment" "^25.1.0" - "@jest/fake-timers" "^25.1.0" - "@jest/types" "^25.1.0" - jest-mock "^25.1.0" - jest-util "^25.1.0" + "@jest/environment" "^25.2.1" + "@jest/fake-timers" "^25.2.1" + "@jest/types" "^25.2.1" + jest-mock "^25.2.1" + jest-util "^25.2.1" jest-get-type@^25.1.0: version "25.1.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.1.0.tgz#1cfe5fc34f148dc3a8a3b7275f6b9ce9e2e8a876" integrity sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw== -jest-haste-map@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-25.1.0.tgz#ae12163d284f19906260aa51fd405b5b2e5a4ad3" - integrity sha512-/2oYINIdnQZAqyWSn1GTku571aAfs8NxzSErGek65Iu5o8JYb+113bZysRMcC/pjE5v9w0Yz+ldbj9NxrFyPyw== +jest-get-type@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.1.tgz#6c83de603c41b1627e6964da2f5454e6aa3c13a6" + integrity sha512-EYjTiqcDTCRJDcSNKbLTwn/LcDPEE7ITk8yRMNAOjEsN6yp+Uu+V1gx4djwnuj/DvWg0YGmqaBqPVGsPxlvE7w== + +jest-haste-map@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-25.2.1.tgz#61cbb3c99185b3551d63da9daedc5f64b9efe544" + integrity sha512-svz3KbQmv9qeomR0LlRjQfoi7lQbZQkC39m7uHFKhqyEuX4F6DH6HayNPSEbTCZDx6d9/ljxfAcxlPpgQvrpvQ== dependencies: - "@jest/types" "^25.1.0" + "@jest/types" "^25.2.1" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.3" - jest-serializer "^25.1.0" - jest-util "^25.1.0" - jest-worker "^25.1.0" + jest-serializer "^25.2.1" + jest-util "^25.2.1" + jest-worker "^25.2.1" micromatch "^4.0.2" sane "^4.0.3" walker "^1.0.7" + which "^2.0.2" optionalDependencies: fsevents "^2.1.2" -jest-jasmine2@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-25.1.0.tgz#681b59158a430f08d5d0c1cce4f01353e4b48137" - integrity sha512-GdncRq7jJ7sNIQ+dnXvpKO2MyP6j3naNK41DTTjEAhLEdpImaDA9zSAZwDhijjSF/D7cf4O5fdyUApGBZleaEg== +jest-jasmine2@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-25.2.1.tgz#5edbe8dd4ed03598fb5db063eb398b67941c8ead" + integrity sha512-He8HdO9jx1LdEaof2vjnvKeJeRPYnn+zXz32X8Z/iOUgAgmP7iZActUkiCCiTazSZlaGlY1iK+LOrqnpGQ0+UA== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^25.1.0" - "@jest/source-map" "^25.1.0" - "@jest/test-result" "^25.1.0" - "@jest/types" "^25.1.0" + "@jest/environment" "^25.2.1" + "@jest/source-map" "^25.2.1" + "@jest/test-result" "^25.2.1" + "@jest/types" "^25.2.1" chalk "^3.0.0" co "^4.6.0" - expect "^25.1.0" + expect "^25.2.1" is-generator-fn "^2.0.0" - jest-each "^25.1.0" - jest-matcher-utils "^25.1.0" - jest-message-util "^25.1.0" - jest-runtime "^25.1.0" - jest-snapshot "^25.1.0" - jest-util "^25.1.0" - pretty-format "^25.1.0" + jest-each "^25.2.1" + jest-matcher-utils "^25.2.1" + jest-message-util "^25.2.1" + jest-runtime "^25.2.1" + jest-snapshot "^25.2.1" + jest-util "^25.2.1" + pretty-format "^25.2.1" throat "^5.0.0" -jest-leak-detector@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-25.1.0.tgz#ed6872d15aa1c72c0732d01bd073dacc7c38b5c6" - integrity sha512-3xRI264dnhGaMHRvkFyEKpDeaRzcEBhyNrOG5oT8xPxOyUAblIAQnpiR3QXu4wDor47MDTiHbiFcbypdLcLW5w== +jest-leak-detector@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-25.2.1.tgz#77c55c59c32de9600f6bd9aab9540538b541b253" + integrity sha512-bsxjjFksjLWNqC8aLsN0KO2KQ3tiqPqmFpYt+0y4RLHc1dqaThQL68jra5y1f/yhX3dNC8ugksDvqnGxwxjo4w== dependencies: - jest-get-type "^25.1.0" - pretty-format "^25.1.0" + jest-get-type "^25.2.1" + pretty-format "^25.2.1" -jest-matcher-utils@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.1.0.tgz#fa5996c45c7193a3c24e73066fc14acdee020220" - integrity sha512-KGOAFcSFbclXIFE7bS4C53iYobKI20ZWleAdAFun4W1Wz1Kkej8Ng6RRbhL8leaEvIOjGXhGf/a1JjO8bkxIWQ== +jest-matcher-utils@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.2.1.tgz#67da3d3aea74b4de6da990b636d7baebfebac0e4" + integrity sha512-uuoYY8W6eeVxHUEOvrKIVVTl9X6RP+ohQn2Ta2W8OOLMN6oA8pZUKQEPGxLsSqB3RKfpTueurMLrxDTEZGllsA== dependencies: chalk "^3.0.0" - jest-diff "^25.1.0" - jest-get-type "^25.1.0" - pretty-format "^25.1.0" + jest-diff "^25.2.1" + jest-get-type "^25.2.1" + pretty-format "^25.2.1" -jest-message-util@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.1.0.tgz#702a9a5cb05c144b9aa73f06e17faa219389845e" - integrity sha512-Nr/Iwar2COfN22aCqX0kCVbXgn8IBm9nWf4xwGr5Olv/KZh0CZ32RKgZWMVDXGdOahicM10/fgjdimGNX/ttCQ== +jest-message-util@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.2.1.tgz#43fb5f239954a28954e74dfea0b75efc4e7377fb" + integrity sha512-pxwehr9uPEuCI9bPjBiZxpFMN0+3wny5p7/E3hbV9XjsqREhJJAMf0czvHtgNeUBo2iAiAI9yi9ICKHPOKePEw== dependencies: "@babel/code-frame" "^7.0.0" - "@jest/test-result" "^25.1.0" - "@jest/types" "^25.1.0" + "@jest/test-result" "^25.2.1" + "@jest/types" "^25.2.1" "@types/stack-utils" "^1.0.1" chalk "^3.0.0" micromatch "^4.0.2" slash "^3.0.0" stack-utils "^1.0.1" -jest-mock@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-25.1.0.tgz#411d549e1b326b7350b2e97303a64715c28615fd" - integrity sha512-28/u0sqS+42vIfcd1mlcg4ZVDmSUYuNvImP4X2lX5hRMLW+CN0BeiKVD4p+ujKKbSPKd3rg/zuhCF+QBLJ4vag== +jest-mock@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-25.2.1.tgz#37b294b8d0aa94c1af7714e039cc410df61593da" + integrity sha512-ZXcmqpCTG1MEm2AP2q9XiJzdbQ655Pnssj+xQMP1thrW2ptEFrd4vSkxTpxk6rnluLPRKagaHmzUpWNxShMvqQ== dependencies: - "@jest/types" "^25.1.0" + "@jest/types" "^25.2.1" jest-pnp-resolver@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== -jest-regex-util@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.1.0.tgz#efaf75914267741838e01de24da07b2192d16d87" - integrity sha512-9lShaDmDpqwg+xAd73zHydKrBbbrIi08Kk9YryBEBybQFg/lBWR/2BDjjiSE7KIppM9C5+c03XiDaZ+m4Pgs1w== +jest-regex-util@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.2.1.tgz#db64b0d15cd3642c93b7b9627801d7c518600584" + integrity sha512-wroFVJw62LdqTdkL508ZLV82FrJJWVJMIuYG7q4Uunl1WAPTf4ftPKrqqfec4SvOIlvRZUdEX2TFpWR356YG/w== -jest-resolve-dependencies@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-25.1.0.tgz#8a1789ec64eb6aaa77fd579a1066a783437e70d2" - integrity sha512-Cu/Je38GSsccNy4I2vL12ZnBlD170x2Oh1devzuM9TLH5rrnLW1x51lN8kpZLYTvzx9j+77Y5pqBaTqfdzVzrw== +jest-resolve-dependencies@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-25.2.1.tgz#47b9ee4b9ec0cf387419f175512367118590f8ee" + integrity sha512-fnct/NyrBpBAVUIMa0M876ubufHP/2Rrc038+gCpVT1s7kazV7ZPFlmGfInahCIthbMr644uzt6pnSvmQgTPGg== dependencies: - "@jest/types" "^25.1.0" - jest-regex-util "^25.1.0" - jest-snapshot "^25.1.0" + "@jest/types" "^25.2.1" + jest-regex-util "^25.2.1" + jest-snapshot "^25.2.1" -jest-resolve@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-25.1.0.tgz#23d8b6a4892362baf2662877c66aa241fa2eaea3" - integrity sha512-XkBQaU1SRCHj2Evz2Lu4Czs+uIgJXWypfO57L7JYccmAXv4slXA6hzNblmcRmf7P3cQ1mE7fL3ABV6jAwk4foQ== +jest-resolve@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-25.2.1.tgz#44f8f87c5688bad31e762f123540b09cac5907f8" + integrity sha512-5rVc6khEckNH62adcR+jlYd34/jBO/U22VHf+elmyO6UBHNWXSbfy63+spJRN4GQ/0dbu6Hi6ZVdR58bmNG2Eg== dependencies: - "@jest/types" "^25.1.0" + "@jest/types" "^25.2.1" browser-resolve "^1.11.3" chalk "^3.0.0" jest-pnp-resolver "^1.2.1" - realpath-native "^1.1.0" + realpath-native "^2.0.0" + resolve "^1.15.1" -jest-runner@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-25.1.0.tgz#fef433a4d42c89ab0a6b6b268e4a4fbe6b26e812" - integrity sha512-su3O5fy0ehwgt+e8Wy7A8CaxxAOCMzL4gUBftSs0Ip32S0epxyZPDov9Znvkl1nhVOJNf4UwAsnqfc3plfQH9w== +jest-runner@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-25.2.1.tgz#95e57abee889bd61f2cde099d4d8badec6e797ba" + integrity sha512-eONqmMQ2vvKh9BsmJmPmv22DqezFSnwX97rj0L5LvPxQNXTz+rpx7nWiKA7xlvOykLFcspw6worK3+AzhwHWhQ== dependencies: - "@jest/console" "^25.1.0" - "@jest/environment" "^25.1.0" - "@jest/test-result" "^25.1.0" - "@jest/types" "^25.1.0" + "@jest/console" "^25.2.1" + "@jest/environment" "^25.2.1" + "@jest/test-result" "^25.2.1" + "@jest/types" "^25.2.1" chalk "^3.0.0" exit "^0.1.2" graceful-fs "^4.2.3" - jest-config "^25.1.0" - jest-docblock "^25.1.0" - jest-haste-map "^25.1.0" - jest-jasmine2 "^25.1.0" - jest-leak-detector "^25.1.0" - jest-message-util "^25.1.0" - jest-resolve "^25.1.0" - jest-runtime "^25.1.0" - jest-util "^25.1.0" - jest-worker "^25.1.0" + jest-config "^25.2.1" + jest-docblock "^25.2.0" + jest-haste-map "^25.2.1" + jest-jasmine2 "^25.2.1" + jest-leak-detector "^25.2.1" + jest-message-util "^25.2.1" + jest-resolve "^25.2.1" + jest-runtime "^25.2.1" + jest-util "^25.2.1" + jest-worker "^25.2.1" source-map-support "^0.5.6" throat "^5.0.0" -jest-runtime@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-25.1.0.tgz#02683218f2f95aad0f2ec1c9cdb28c1dc0ec0314" - integrity sha512-mpPYYEdbExKBIBB16ryF6FLZTc1Rbk9Nx0ryIpIMiDDkOeGa0jQOKVI/QeGvVGlunKKm62ywcioeFVzIbK03bA== - dependencies: - "@jest/console" "^25.1.0" - "@jest/environment" "^25.1.0" - "@jest/source-map" "^25.1.0" - "@jest/test-result" "^25.1.0" - "@jest/transform" "^25.1.0" - "@jest/types" "^25.1.0" +jest-runtime@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-25.2.1.tgz#bf6a71e3a654e131326413851c7973f3be235ab0" + integrity sha512-eHEnMrOVeGe8mGDoTZWqCdbsM3RwxsMKVMAj1RTZ4LtRyWqQHKec3RiJiJST5LVj3Mw72clr0U21yoE4p5Mq3w== + dependencies: + "@jest/console" "^25.2.1" + "@jest/environment" "^25.2.1" + "@jest/source-map" "^25.2.1" + "@jest/test-result" "^25.2.1" + "@jest/transform" "^25.2.1" + "@jest/types" "^25.2.1" "@types/yargs" "^15.0.0" chalk "^3.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.2.3" - jest-config "^25.1.0" - jest-haste-map "^25.1.0" - jest-message-util "^25.1.0" - jest-mock "^25.1.0" - jest-regex-util "^25.1.0" - jest-resolve "^25.1.0" - jest-snapshot "^25.1.0" - jest-util "^25.1.0" - jest-validate "^25.1.0" - realpath-native "^1.1.0" + jest-config "^25.2.1" + jest-haste-map "^25.2.1" + jest-message-util "^25.2.1" + jest-mock "^25.2.1" + jest-regex-util "^25.2.1" + jest-resolve "^25.2.1" + jest-snapshot "^25.2.1" + jest-util "^25.2.1" + jest-validate "^25.2.1" + realpath-native "^2.0.0" slash "^3.0.0" strip-bom "^4.0.0" - yargs "^15.0.0" + yargs "^15.3.1" -jest-serializer@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-25.1.0.tgz#73096ba90e07d19dec4a0c1dd89c355e2f129e5d" - integrity sha512-20Wkq5j7o84kssBwvyuJ7Xhn7hdPeTXndnwIblKDR2/sy1SUm6rWWiG9kSCgJPIfkDScJCIsTtOKdlzfIHOfKA== +jest-serializer@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-25.2.1.tgz#51727a5fc04256f461abe0fa024a022ba165877a" + integrity sha512-fibDi7M5ffx6c/P66IkvR4FKkjG5ldePAK1WlbNoaU4GZmIAkS9Le/frAwRUFEX0KdnisSPWf+b1RC5jU7EYJQ== -jest-snapshot@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-25.1.0.tgz#d5880bd4b31faea100454608e15f8d77b9d221d9" - integrity sha512-xZ73dFYN8b/+X2hKLXz4VpBZGIAn7muD/DAg+pXtDzDGw3iIV10jM7WiHqhCcpDZfGiKEj7/2HXAEPtHTj0P2A== +jest-snapshot@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-25.2.1.tgz#1fdcc8c780f83f0e902dd75df79d0d7313fe939e" + integrity sha512-5Wd8SEJVTXqQvzkQpuYqQt1QTlRj2XVUV/iaEzO+AeSVg6g5pQWu0z2iLdSBlVeWRrX0MyZn6dhxYGwEq4wW0w== dependencies: "@babel/types" "^7.0.0" - "@jest/types" "^25.1.0" + "@jest/types" "^25.2.1" + "@types/prettier" "^1.19.0" chalk "^3.0.0" - expect "^25.1.0" - jest-diff "^25.1.0" - jest-get-type "^25.1.0" - jest-matcher-utils "^25.1.0" - jest-message-util "^25.1.0" - jest-resolve "^25.1.0" - mkdirp "^0.5.1" + expect "^25.2.1" + jest-diff "^25.2.1" + jest-get-type "^25.2.1" + jest-matcher-utils "^25.2.1" + jest-message-util "^25.2.1" + jest-resolve "^25.2.1" + make-dir "^3.0.0" natural-compare "^1.4.0" - pretty-format "^25.1.0" - semver "^7.1.1" + pretty-format "^25.2.1" + semver "^6.3.0" -jest-util@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.1.0.tgz#7bc56f7b2abd534910e9fa252692f50624c897d9" - integrity sha512-7did6pLQ++87Qsj26Fs/TIwZMUFBXQ+4XXSodRNy3luch2DnRXsSnmpVtxxQ0Yd6WTipGpbhh2IFP1mq6/fQGw== +jest-util@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.2.1.tgz#96086efe850ce6d07c42ad5324b80a3ede4246e6" + integrity sha512-oFVMSY/7flrSgEE/B+RApaBZOdLURXRnXCf4COV5td9uRidxudyjA64I1xk2h9Pf3jloSArm96e2FKAbFs0DYg== dependencies: - "@jest/types" "^25.1.0" + "@jest/types" "^25.2.1" chalk "^3.0.0" is-ci "^2.0.0" - mkdirp "^0.5.1" + make-dir "^3.0.0" -jest-validate@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-25.1.0.tgz#1469fa19f627bb0a9a98e289f3e9ab6a668c732a" - integrity sha512-kGbZq1f02/zVO2+t1KQGSVoCTERc5XeObLwITqC6BTRH3Adv7NZdYqCpKIZLUgpLXf2yISzQ465qOZpul8abXA== +jest-validate@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-25.2.1.tgz#a07a4e6697fc58e6ea31c03de541af4d0a475fbc" + integrity sha512-vGtNFPyvylFfTFFfptzqCy5S3cP/N5JJVwm8gsXeZq8jMmvUngfWtuw+Tr5Wjo+dqOle23td8BE0ruGnsONDmw== dependencies: - "@jest/types" "^25.1.0" + "@jest/types" "^25.2.1" camelcase "^5.3.1" chalk "^3.0.0" - jest-get-type "^25.1.0" + jest-get-type "^25.2.1" leven "^3.1.0" - pretty-format "^25.1.0" + pretty-format "^25.2.1" -jest-watcher@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-25.1.0.tgz#97cb4a937f676f64c9fad2d07b824c56808e9806" - integrity sha512-Q9eZ7pyaIr6xfU24OeTg4z1fUqBF/4MP6J801lyQfg7CsnZ/TCzAPvCfckKdL5dlBBEKBeHV0AdyjFZ5eWj4ig== +jest-watcher@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-25.2.1.tgz#605aeef37ee4ce867f2f58485fdb9eea0f8cb369" + integrity sha512-m35rftCYE2EEh01+IIpQMpdB9VXBAjITZvgP4drd/LI3JEJIdd0Pkf/qJZ3oiMQJdqmuwYcTqE+BL40MxVv83Q== dependencies: - "@jest/test-result" "^25.1.0" - "@jest/types" "^25.1.0" + "@jest/test-result" "^25.2.1" + "@jest/types" "^25.2.1" ansi-escapes "^4.2.1" chalk "^3.0.0" - jest-util "^25.1.0" + jest-util "^25.2.1" string-length "^3.1.0" -jest-worker@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.1.0.tgz#75d038bad6fdf58eba0d2ec1835856c497e3907a" - integrity sha512-ZHhHtlxOWSxCoNOKHGbiLzXnl42ga9CxDr27H36Qn+15pQZd3R/F24jrmjDelw9j/iHUIWMWs08/u2QN50HHOg== +jest-worker@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.2.1.tgz#209617015c768652646aa33a7828cc2ab472a18a" + integrity sha512-IHnpekk8H/hCUbBlfeaPZzU6v75bqwJp3n4dUrQuQOAgOneI4tx3jV2o8pvlXnDfcRsfkFIUD//HWXpCmR+evQ== dependencies: merge-stream "^2.0.0" supports-color "^7.0.0" -jest@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-25.1.0.tgz#b85ef1ddba2fdb00d295deebbd13567106d35be9" - integrity sha512-FV6jEruneBhokkt9MQk0WUFoNTwnF76CLXtwNMfsc0um0TlB/LG2yxUd0KqaFjEJ9laQmVWQWS0sG/t2GsuI0w== +jest@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-25.2.1.tgz#aa9a956c33fe1f10f016efade2c3e8846d0056d8" + integrity sha512-YXvGtrb4YmfM/JraXaM3jc3NnvhVTHxkdRC9Oof4JtJWwgvIdy0/X01QxeWXqKfCaHmlXi/nKrcPI1+bf0w/Ww== dependencies: - "@jest/core" "^25.1.0" + "@jest/core" "^25.2.1" import-local "^3.0.2" - jest-cli "^25.1.0" + jest-cli "^25.2.1" js-sha256@^0.9.0: version "0.9.0" @@ -3218,7 +3176,7 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -jsdom@^15.1.1: +jsdom@^15.2.1: version "15.2.1" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-15.2.1.tgz#d2feb1aef7183f86be521b8c6833ff5296d07ec5" integrity sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g== @@ -3822,16 +3780,6 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" - integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== - -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" @@ -3839,24 +3787,6 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" -object.assign@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" - -object.getownpropertydescriptors@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" - integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -4115,6 +4045,16 @@ pretty-format@^25.1.0: ansi-styles "^4.0.0" react-is "^16.12.0" +pretty-format@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.2.1.tgz#3b8f7b9241faa6736cdbc32879bee18454d1318d" + integrity sha512-YS+e9oGYIbEeAFgqTU8qeZ3DN2Pz0iaD81ox+iUjLIXVJWeB7Ro/2AnfxRnl/yJJ5R674d7E3jLPuh6bwg0+qw== + dependencies: + "@jest/types" "^25.2.1" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^16.12.0" + process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" @@ -4259,12 +4199,10 @@ readable-stream@^2.3.5: string_decoder "~1.1.1" util-deprecate "~1.0.1" -realpath-native@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" - integrity sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA== - dependencies: - util.promisify "^1.0.0" +realpath-native@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-2.0.0.tgz#7377ac429b6e1fd599dc38d08ed942d0d7beb866" + integrity sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q== regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" @@ -4389,7 +4327,7 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@1.x, resolve@^1.3.2: +resolve@1.x, resolve@^1.15.1, resolve@^1.3.2: version "1.15.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== @@ -4503,11 +4441,6 @@ semver@^6.0.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.1.1: - version "7.1.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.1.3.tgz#e4345ce73071c53f336445cfc19efb1c311df2a6" - integrity sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA== - send@0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" @@ -4778,22 +4711,6 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string.prototype.trimleft@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" - integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag== - dependencies: - define-properties "^1.1.3" - function-bind "^1.1.1" - -string.prototype.trimright@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" - integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g== - dependencies: - define-properties "^1.1.3" - function-bind "^1.1.1" - string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -5227,16 +5144,6 @@ util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util.promisify@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" - integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.2" - has-symbols "^1.0.1" - object.getownpropertydescriptors "^2.1.0" - utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" @@ -5336,7 +5243,7 @@ which@^1.2.9, which@^1.3.1: dependencies: isexe "^2.0.0" -which@^2.0.1: +which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== @@ -5435,10 +5342,18 @@ yargs-parser@^16.1.0: camelcase "^5.0.0" decamelize "^1.2.0" -yargs@^15.0.0: - version "15.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.1.0.tgz#e111381f5830e863a89550bd4b136bb6a5f37219" - integrity sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg== +yargs-parser@^18.1.1: + version "18.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.1.tgz#bf7407b915427fc760fcbbccc6c82b4f0ffcbd37" + integrity sha512-KRHEsOM16IX7XuLnMOqImcPNbLVXMNHYAoFc3BKR8Ortl5gzDbtXvvEoGx9imk5E+X1VeNKNlcHr8B8vi+7ipA== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^15.3.1: + version "15.3.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.3.1.tgz#9505b472763963e54afe60148ad27a330818e98b" + integrity sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA== dependencies: cliui "^6.0.0" decamelize "^1.2.0" @@ -5450,7 +5365,7 @@ yargs@^15.0.0: string-width "^4.2.0" which-module "^2.0.0" y18n "^4.0.0" - yargs-parser "^16.1.0" + yargs-parser "^18.1.1" yargs@^3.10.0: version "3.32.0" From a6852d8a7cf3fe793e029c4daf553319773e003c Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Fri, 27 Mar 2020 11:02:33 +1100 Subject: [PATCH 05/88] Ensure lnd params are defaulted if not present --- CHANGELOG.md | 4 ++ cnd/src/config.rs | 90 +++++++++++++------------------------- cnd/src/config/file.rs | 16 ++++--- cnd/src/config/settings.rs | 88 +++++-------------------------------- 4 files changed, 57 insertions(+), 141 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5eca4521dc..4d1674399a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## Changed + +- Ensure that lnd parameters are defaulted if not present. + ## [0.7.2] - 2020-03-26 ## [0.7.1] - 2020-03-12 diff --git a/cnd/src/config.rs b/cnd/src/config.rs index 5fa7ca1eb8..0e9c517ac5 100644 --- a/cnd/src/config.rs +++ b/cnd/src/config.rs @@ -96,29 +96,38 @@ pub struct Parity { #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct Lightning { pub network: bitcoin::Network, - pub lnd: Option, + pub lnd: Lnd, } impl Default for Lightning { fn default() -> Self { Self { network: bitcoin::Network::Regtest, - lnd: Some(Lnd::default()), + lnd: Lnd::default(), + } + } +} + +impl From for file::Lightning { + fn from(lightning: Lightning) -> Self { + file::Lightning { + lnd: Some(lightning.lnd), + network: lightning.network, } } } #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct Lnd { - pub rest_api_socket: Option, - pub dir: Option, + pub rest_api_socket: SocketAddr, + pub dir: PathBuf, } impl Default for Lnd { fn default() -> Self { Self { - rest_api_socket: Some(*LND_SOCKET), - dir: Some(default_lnd_dir()), + rest_api_socket: *LND_SOCKET, + dir: default_lnd_dir(), } } } @@ -165,77 +174,40 @@ mod tests { #[test] fn lnd_deserializes_correctly() { - let file_contents = vec![ - r#" - rest_api_socket = "127.0.0.1:8080" - dir = "~/.local/share/comit/lnd" - "#, + let actual = toml::from_str( r#" rest_api_socket = "127.0.0.1:8080" - "#, - r#" dir = "~/.local/share/comit/lnd" "#, - ]; + ); - let expected = vec![ - Lnd { - rest_api_socket: Some(*LND_SOCKET), - dir: Some(PathBuf::from("~/.local/share/comit/lnd")), - }, - Lnd { - rest_api_socket: Some(*LND_SOCKET), - dir: None, - }, - Lnd { - rest_api_socket: None, - dir: Some(PathBuf::from("~/.local/share/comit/lnd")), - }, - ]; + let expected = Lnd { + rest_api_socket: *LND_SOCKET, + dir: PathBuf::from("~/.local/share/comit/lnd"), + }; - let actual = file_contents - .into_iter() - .map(toml::from_str) - .collect::, toml::de::Error>>() - .unwrap(); - - assert_eq!(actual, expected); + assert_eq!(actual, Ok(expected)); } #[test] fn lightning_deserializes_correctly() { - let file_contents = vec![ - r#" - network = "regtest" - "#, + let actual = toml::from_str( r#" network = "regtest" [lnd] rest_api_socket = "127.0.0.1:8080" dir = "/path/to/lnd" "#, - ]; + ); - let expected = vec![ - Lightning { - network: bitcoin::Network::Regtest, - lnd: None, - }, - Lightning { - network: bitcoin::Network::Regtest, - lnd: Some(Lnd { - rest_api_socket: Some(*LND_SOCKET), - dir: Some(PathBuf::from("/path/to/lnd")), - }), + let expected = Lightning { + network: bitcoin::Network::Regtest, + lnd: Lnd { + rest_api_socket: *LND_SOCKET, + dir: PathBuf::from("/path/to/lnd"), }, - ]; + }; - let actual = file_contents - .into_iter() - .map(toml::from_str) - .collect::, toml::de::Error>>() - .unwrap(); - - assert_eq!(actual, expected); + assert_eq!(actual, Ok(expected)); } } diff --git a/cnd/src/config/file.rs b/cnd/src/config/file.rs index c09e87be9f..96cc0af41b 100644 --- a/cnd/src/config/file.rs +++ b/cnd/src/config/file.rs @@ -1,5 +1,5 @@ use crate::{ - config::{Bitcoind, Data, Lightning, Network, Parity}, + config::{Bitcoind, Data, Lnd, Network, Parity}, swap_protocols::ledger::ethereum, }; use config as config_rs; @@ -36,6 +36,12 @@ pub struct Ethereum { pub parity: Option, } +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +pub struct Lightning { + pub network: bitcoin::Network, + pub lnd: Option, +} + impl File { pub fn default() -> Self { File { @@ -223,6 +229,7 @@ network = "regtest" [lightning.lnd] rest_api_socket = "127.0.0.1:8080" +dir = "/foo/bar" "#; let file = File { network: Some(Network { @@ -255,11 +262,8 @@ rest_api_socket = "127.0.0.1:8080" lightning: Some(Lightning { network: bitcoin::Network::Regtest, lnd: Some(Lnd { - rest_api_socket: Some(SocketAddr::new( - IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), - 8080, - )), - dir: None, + rest_api_socket: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080), + dir: PathBuf::from("/foo/bar"), }), }), }; diff --git a/cnd/src/config/settings.rs b/cnd/src/config/settings.rs index a8eb360edd..37e51e234a 100644 --- a/cnd/src/config/settings.rs +++ b/cnd/src/config/settings.rs @@ -1,6 +1,5 @@ use crate::config::{ - default_lnd_dir, file, Bitcoin, Bitcoind, Data, Ethereum, File, Lightning, Lnd, Network, - Parity, LND_SOCKET, + file, Bitcoin, Bitcoind, Data, Ethereum, File, Lightning, Lnd, Network, Parity, }; use anyhow::Context; use log::LevelFilter; @@ -103,13 +102,7 @@ impl From for File { }), bitcoin: Some(bitcoin.into()), ethereum: Some(ethereum.into()), - lightning: Some(Lightning { - network: lightning.network, - lnd: lightning.lnd.map(|lnd| Lnd { - rest_api_socket: lnd.rest_api_socket, - dir: lnd.dir, - }), - }), + lightning: Some(lightning.into()), } } } @@ -223,11 +216,11 @@ impl Settings { Some(lightning) => Lightning { network: lightning.network, lnd: match lightning.lnd { - None => Some(Lnd::default()), - Some(lnd) => Some(Lnd { - rest_api_socket: lnd.rest_api_socket.or_else(|| Some(*LND_SOCKET)), - dir: lnd.dir.or_else(|| Some(default_lnd_dir())), - }), + None => Lnd::default(), + Some(lnd) => Lnd { + rest_api_socket: lnd.rest_api_socket, + dir: lnd.dir, + }, }, }, }, @@ -288,7 +281,7 @@ mod tests { use super::*; use crate::{config::file, swap_protocols::ledger::ethereum}; use spectral::prelude::*; - use std::{net::IpAddr, path::PathBuf}; + use std::net::IpAddr; #[test] fn logging_section_defaults_to_info() { @@ -473,19 +466,13 @@ mod tests { assert_that(&settings) .is_ok() .map(|settings| &settings.lightning) - .is_equal_to(Lightning { - network: bitcoin::Network::Regtest, - lnd: Some(Lnd { - rest_api_socket: Some(*LND_SOCKET), - dir: Some(crate::lnd_default_dir().unwrap()), - }), - }) + .is_equal_to(Lightning::default()) } #[test] fn lightning_lnd_section_defaults() { let config_file = File { - lightning: Some(Lightning { + lightning: Some(file::Lightning { network: bitcoin::Network::Regtest, lnd: None, }), @@ -494,63 +481,12 @@ mod tests { let settings = Settings::from_config_file_and_defaults(config_file); - assert_that(&settings) - .is_ok() - .map(|settings| &settings.lightning) - .is_equal_to(Lightning::default()) - } - - #[test] - fn lnd_dir_defaults() { - let config_file = File { - lightning: Some(Lightning { - network: bitcoin::Network::Bitcoin, - lnd: Some(Lnd { - rest_api_socket: Some(*LND_SOCKET), - dir: None, - }), - }), - ..File::default() - }; - - let settings = Settings::from_config_file_and_defaults(config_file); - assert_that(&settings) .is_ok() .map(|settings| &settings.lightning) .is_equal_to(Lightning { - network: bitcoin::Network::Bitcoin, - lnd: Some(Lnd { - rest_api_socket: Some(*LND_SOCKET), - dir: Some(crate::lnd_default_dir().unwrap()), - }), - }) - } - - #[test] - fn lnd_rest_api_socket_defaults() { - let config_file = File { - lightning: Some(Lightning { - network: bitcoin::Network::Bitcoin, - lnd: Some(Lnd { - rest_api_socket: None, - dir: Some(PathBuf::from("~/.cache/comit/lnd")), - }), - }), - ..File::default() - }; - - let settings = Settings::from_config_file_and_defaults(config_file); - - assert_that(&settings) - .is_ok() - .map(|settings| &settings.lightning) - .is_equal_to(Lightning { - network: bitcoin::Network::Bitcoin, - lnd: Some(Lnd { - rest_api_socket: Some(*LND_SOCKET), - dir: Some(PathBuf::from("~/.cache/comit/lnd")), - }), + network: bitcoin::Network::Regtest, + lnd: Lnd::default(), }) } } From b636315e408e56999e47b837841514ed98390ce3 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Fri, 27 Mar 2020 11:19:38 +1100 Subject: [PATCH 06/88] Use Url instead of Socket for lnd REST API --- cnd/src/config.rs | 25 +++++++++++-------------- cnd/src/config/file.rs | 4 ++-- cnd/src/config/settings.rs | 2 +- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/cnd/src/config.rs b/cnd/src/config.rs index 0e9c517ac5..84e34f9bda 100644 --- a/cnd/src/config.rs +++ b/cnd/src/config.rs @@ -5,17 +5,14 @@ pub mod validation; use crate::swap_protocols::ledger::ethereum; use libp2p::Multiaddr; +use reqwest::Url; use serde::{Deserialize, Serialize}; -use std::{ - net::{IpAddr, Ipv4Addr, SocketAddr}, - path::PathBuf, -}; +use std::path::PathBuf; pub use self::{file::File, settings::Settings}; -use reqwest::Url; lazy_static::lazy_static! { - pub static ref LND_SOCKET: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080); + pub static ref LND_URL: Url = Url::parse("https://localhost:8080").expect("static string to be a valid url"); } #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] @@ -37,7 +34,7 @@ pub struct Bitcoin { #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct Bitcoind { - pub node_url: reqwest::Url, + pub node_url: Url, } impl Default for Bitcoin { @@ -90,7 +87,7 @@ impl Default for Ethereum { #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct Parity { - pub node_url: reqwest::Url, + pub node_url: Url, } #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] @@ -119,14 +116,14 @@ impl From for file::Lightning { #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct Lnd { - pub rest_api_socket: SocketAddr, + pub rest_api_url: Url, pub dir: PathBuf, } impl Default for Lnd { fn default() -> Self { Self { - rest_api_socket: *LND_SOCKET, + rest_api_url: LND_URL.clone(), dir: default_lnd_dir(), } } @@ -176,13 +173,13 @@ mod tests { fn lnd_deserializes_correctly() { let actual = toml::from_str( r#" - rest_api_socket = "127.0.0.1:8080" + rest_api_url = "https://localhost:8080" dir = "~/.local/share/comit/lnd" "#, ); let expected = Lnd { - rest_api_socket: *LND_SOCKET, + rest_api_url: LND_URL.clone(), dir: PathBuf::from("~/.local/share/comit/lnd"), }; @@ -195,7 +192,7 @@ mod tests { r#" network = "regtest" [lnd] - rest_api_socket = "127.0.0.1:8080" + rest_api_url = "https://localhost:8080" dir = "/path/to/lnd" "#, ); @@ -203,7 +200,7 @@ mod tests { let expected = Lightning { network: bitcoin::Network::Regtest, lnd: Lnd { - rest_api_socket: *LND_SOCKET, + rest_api_url: LND_URL.clone(), dir: PathBuf::from("/path/to/lnd"), }, }; diff --git a/cnd/src/config/file.rs b/cnd/src/config/file.rs index 96cc0af41b..2b62c0c52c 100644 --- a/cnd/src/config/file.rs +++ b/cnd/src/config/file.rs @@ -228,7 +228,7 @@ node_url = "http://localhost:8545/" network = "regtest" [lightning.lnd] -rest_api_socket = "127.0.0.1:8080" +rest_api_url = "https://localhost:8080" dir = "/foo/bar" "#; let file = File { @@ -262,7 +262,7 @@ dir = "/foo/bar" lightning: Some(Lightning { network: bitcoin::Network::Regtest, lnd: Some(Lnd { - rest_api_socket: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080), + rest_api_url: "https://localhost:8080".parse().unwrap(), dir: PathBuf::from("/foo/bar"), }), }), diff --git a/cnd/src/config/settings.rs b/cnd/src/config/settings.rs index 37e51e234a..b98b663c77 100644 --- a/cnd/src/config/settings.rs +++ b/cnd/src/config/settings.rs @@ -218,7 +218,7 @@ impl Settings { lnd: match lightning.lnd { None => Lnd::default(), Some(lnd) => Lnd { - rest_api_socket: lnd.rest_api_socket, + rest_api_url: lnd.rest_api_url, dir: lnd.dir, }, }, From cef16cb1378c7140cffb9bc32ef98602d0683fd3 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 29 Mar 2020 14:12:59 +0000 Subject: [PATCH 07/88] Bump paste from 0.1.8 to 0.1.9 Bumps [paste](https://github.com/dtolnay/paste) from 0.1.8 to 0.1.9. - [Release notes](https://github.com/dtolnay/paste/releases) - [Commits](https://github.com/dtolnay/paste/compare/0.1.8...0.1.9) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a2e78f100c..3b1747575d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2626,9 +2626,9 @@ dependencies = [ [[package]] name = "paste" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8292c1e1e81ddb552c4c90c36af201a0ce7e34995f55f0480f01052f242811c9" +checksum = "092d791bf7847f70bbd49085489fba25fc2c193571752bff9e36e74e72403932" dependencies = [ "paste-impl", "proc-macro-hack", @@ -2636,9 +2636,9 @@ dependencies = [ [[package]] name = "paste-impl" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e9c43f2645f06ee452544ad032886a75f3d1797b9487dcadcae9100ba58a51c" +checksum = "406c23fb4c45cc6f68a9bbabb8ec7bd6f8cfcbd17e9e8f72c2460282f8325729" dependencies = [ "proc-macro-hack", "proc-macro2 1.0.9", From a808ee9bd44830f1a7f8a21eeb320f714fe09775 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 29 Mar 2020 14:13:43 +0000 Subject: [PATCH 08/88] Bump serde_json from 1.0.48 to 1.0.50 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.48 to 1.0.50. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.48...v1.0.50) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a2e78f100c..90216b350a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3311,9 +3311,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.48" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25" +checksum = "78a7a12c167809363ec3bd7329fc0a3369056996de43c4b37ef3cd54a6ce4867" dependencies = [ "itoa", "ryu", From db4b93c04bd5721c758cbb01caba199b6df4207f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 29 Mar 2020 14:13:44 +0000 Subject: [PATCH 09/88] Bump jest from 25.2.1 to 25.2.3 in /api_tests Bumps [jest](https://github.com/facebook/jest) from 25.2.1 to 25.2.3. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/compare/v25.2.1...v25.2.3) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 571 +++++++++++++++++++++-------------------- 2 files changed, 287 insertions(+), 286 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index affb480172..162eb8efdb 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -46,7 +46,7 @@ "comit-sdk": "^0.15.1", "ethers": "^4.0.46", "get-port": "^5.1.1", - "jest": "^25.2.1", + "jest": "^25.2.3", "js-sha256": "^0.9.0", "log4js": "^6.1.2", "prettier": "^2.0.2", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index fb2d71d0ee..c0867fe044 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -179,43 +179,43 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== -"@jest/console@^25.2.1": - version "25.2.1" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-25.2.1.tgz#63b35b6a2b67f26866f8dcbb9725452a1c8c0d3b" - integrity sha512-v3tkMr5AeVm6R23wnZdC5dzXdHPFa6j2uiTC15iHISYkGIilE9O1qmAYKELHPXZifDbz9c8WwzsqoN8K8uG4jg== +"@jest/console@^25.2.3": + version "25.2.3" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-25.2.3.tgz#38ac19b916ff61457173799239472659e1a67c39" + integrity sha512-k+37B1aSvOt9tKHWbZZSOy1jdgzesB0bj96igCVUG1nAH1W5EoUfgc5EXbBVU08KSLvkVdWopLXaO3xfVGlxtQ== dependencies: "@jest/source-map" "^25.2.1" chalk "^3.0.0" - jest-util "^25.2.1" + jest-util "^25.2.3" slash "^3.0.0" -"@jest/core@^25.2.1": - version "25.2.1" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-25.2.1.tgz#05191bada9ec5d322775454342cbd7b13dd3a691" - integrity sha512-Pe7CVcysOmm69BgdgAuMjRCp6vmcCJy32PxPtArQDgiizIBQElHhE9P34afGwPgSb3+e3WC6XtEm4de7d9BtfQ== - dependencies: - "@jest/console" "^25.2.1" - "@jest/reporters" "^25.2.1" - "@jest/test-result" "^25.2.1" - "@jest/transform" "^25.2.1" - "@jest/types" "^25.2.1" +"@jest/core@^25.2.3": + version "25.2.3" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-25.2.3.tgz#2fd37ce0e6ad845e058dcd8245f2745490df1bc0" + integrity sha512-Ifz3aEkGvZhwijLMmWa7sloZVEMdxpzjFv3CKHv3eRYRShTN8no6DmyvvxaZBjLalOlRalJ7HDgc733J48tSuw== + dependencies: + "@jest/console" "^25.2.3" + "@jest/reporters" "^25.2.3" + "@jest/test-result" "^25.2.3" + "@jest/transform" "^25.2.3" + "@jest/types" "^25.2.3" ansi-escapes "^4.2.1" chalk "^3.0.0" exit "^0.1.2" graceful-fs "^4.2.3" - jest-changed-files "^25.2.1" - jest-config "^25.2.1" - jest-haste-map "^25.2.1" - jest-message-util "^25.2.1" + jest-changed-files "^25.2.3" + jest-config "^25.2.3" + jest-haste-map "^25.2.3" + jest-message-util "^25.2.3" jest-regex-util "^25.2.1" - jest-resolve "^25.2.1" - jest-resolve-dependencies "^25.2.1" - jest-runner "^25.2.1" - jest-runtime "^25.2.1" - jest-snapshot "^25.2.1" - jest-util "^25.2.1" - jest-validate "^25.2.1" - jest-watcher "^25.2.1" + jest-resolve "^25.2.3" + jest-resolve-dependencies "^25.2.3" + jest-runner "^25.2.3" + jest-runtime "^25.2.3" + jest-snapshot "^25.2.3" + jest-util "^25.2.3" + jest-validate "^25.2.3" + jest-watcher "^25.2.3" micromatch "^4.0.2" p-each-series "^2.1.0" realpath-native "^2.0.0" @@ -223,36 +223,36 @@ slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^25.2.1": - version "25.2.1" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-25.2.1.tgz#d967f38c05accfb2dba325e93238684e8b1706bd" - integrity sha512-aeA3UlUmpblmv2CHBcNA7LvcXlcCtRpXaKKFVooRy9/Jk8B4IZAZMfrML/d+1cG5FpF17s4JVdu1kx0mbnaqTQ== +"@jest/environment@^25.2.3": + version "25.2.3" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-25.2.3.tgz#32b3f216355b03e9449b93b62584c18934a2cc4a" + integrity sha512-zRypAMQnNo8rD0rCbI9+5xf+Lu+uvunKZNBcIWjb3lTATSomKbgYO+GYewGDYn7pf+30XCNBc6SH1rnBUN1ioA== dependencies: - "@jest/fake-timers" "^25.2.1" - "@jest/types" "^25.2.1" - jest-mock "^25.2.1" + "@jest/fake-timers" "^25.2.3" + "@jest/types" "^25.2.3" + jest-mock "^25.2.3" -"@jest/fake-timers@^25.2.1": - version "25.2.1" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.2.1.tgz#caaaea22e810796d3538a77fdce6e554c864ae72" - integrity sha512-H1OC8AktrGTD10NHBauICkRCv7VOOrsgI8xokifAsxJMYhqoKBtJZbk2YpbrtnmdTUnk+qoxPUk+Mufwnl44iQ== +"@jest/fake-timers@^25.2.3": + version "25.2.3" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.2.3.tgz#808a8a761be3baac719311f8bde1362bd1861e65" + integrity sha512-B6Qxm86fl613MV8egfvh1mRTMu23hMNdOUjzPhKl/4Nm5cceHz6nwLn0nP0sJXI/ue1vu71aLbtkgVBCgc2hYA== dependencies: - "@jest/types" "^25.2.1" - jest-message-util "^25.2.1" - jest-mock "^25.2.1" - jest-util "^25.2.1" + "@jest/types" "^25.2.3" + jest-message-util "^25.2.3" + jest-mock "^25.2.3" + jest-util "^25.2.3" lolex "^5.0.0" -"@jest/reporters@^25.2.1": - version "25.2.1" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-25.2.1.tgz#c5bc848393f48f3cf141957ba51fc4c1598ddb3a" - integrity sha512-jAnIECIIFVHiASKLpPBpZ9fIgWolKdMwUuyjSlNVixmtX6G83fyiGaOquaAU1ukAxnlKdCLjvH6BYdY+GGbd5Q== +"@jest/reporters@^25.2.3": + version "25.2.3" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-25.2.3.tgz#824e922ea56686d0243c910559c36adacdd2081c" + integrity sha512-S0Zca5e7tTfGgxGRvBh6hktNdOBzqc6HthPzYHPRFYVW81SyzCqHTaNZydtDIVehb9s6NlyYZpcF/I2vco+lNw== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^25.2.1" - "@jest/test-result" "^25.2.1" - "@jest/transform" "^25.2.1" - "@jest/types" "^25.2.1" + "@jest/console" "^25.2.3" + "@jest/test-result" "^25.2.3" + "@jest/transform" "^25.2.3" + "@jest/types" "^25.2.3" chalk "^3.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" @@ -262,9 +262,9 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.0.0" - jest-haste-map "^25.2.1" - jest-resolve "^25.2.1" - jest-util "^25.2.1" + jest-haste-map "^25.2.3" + jest-resolve "^25.2.3" + jest-util "^25.2.3" jest-worker "^25.2.1" slash "^3.0.0" source-map "^0.6.0" @@ -283,42 +283,42 @@ graceful-fs "^4.2.3" source-map "^0.6.0" -"@jest/test-result@^25.2.1": - version "25.2.1" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.2.1.tgz#dc8d26d4329c055733bd5ad6dc4eda190fbacd3b" - integrity sha512-E0tlWh2iOELRLbbPEngs3Dsx88vGBQOs6O3w46YeXfMHlwwqzWrlvoeUq6kRlHRm1O8H+EBr60Wtrwh20C+zWQ== +"@jest/test-result@^25.2.3": + version "25.2.3" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.2.3.tgz#db6028427514702c739dda66528dfbcc7fb8cdf4" + integrity sha512-cNYidqERTcT+xqZZ5FPSvji7Bd2YYq9M/VJCEUmgTVRFZRPOPSu65crEzQJ4czcDChEJ9ovzZ65r3UBlajnh3w== dependencies: - "@jest/console" "^25.2.1" - "@jest/transform" "^25.2.1" - "@jest/types" "^25.2.1" + "@jest/console" "^25.2.3" + "@jest/transform" "^25.2.3" + "@jest/types" "^25.2.3" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^25.2.1": - version "25.2.1" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-25.2.1.tgz#b4e75d46aacabbf24cbf4b0a900253c899980856" - integrity sha512-yEhVlBRS7pg3MGBIQQafYfm2NT5trFa/qoxtLftQoZmyzKx3rPy0oJ+d/8QljK4X2RGY/i7mmQDxE6sGR9UqeQ== +"@jest/test-sequencer@^25.2.3": + version "25.2.3" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-25.2.3.tgz#1400e0e994904844567e6e33c87062cbdf1f3e99" + integrity sha512-trHwV/wCrxWyZyNyNBUQExsaHyBVQxJwH3butpEcR+KBJPfaTUxtpXaxfs38IXXAhH68J4kPZgAaRRfkFTLunA== dependencies: - "@jest/test-result" "^25.2.1" - jest-haste-map "^25.2.1" - jest-runner "^25.2.1" - jest-runtime "^25.2.1" + "@jest/test-result" "^25.2.3" + jest-haste-map "^25.2.3" + jest-runner "^25.2.3" + jest-runtime "^25.2.3" -"@jest/transform@^25.2.1": - version "25.2.1" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-25.2.1.tgz#08481795277b6ff9d7cb703eb4425ed46861bedc" - integrity sha512-puoD5EfqPeZ5m0dV9l8+PMdOVdRjeWcaEjGkH+eG45l0nPJ2vRcxu8J6CRl/6nQ5ZTHgg7LuM9C6FauNpdRpUA== +"@jest/transform@^25.2.3": + version "25.2.3" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-25.2.3.tgz#f090bdd91f54b867631a76959f2b2fc566534ffe" + integrity sha512-w1nfAuYP4OAiEDprFkE/2iwU86jL/hK3j1ylMcYOA3my5VOHqX0oeBcBxS2fUKWse2V4izuO2jqes0yNTDMlzw== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^25.2.1" + "@jest/types" "^25.2.3" babel-plugin-istanbul "^6.0.0" chalk "^3.0.0" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" graceful-fs "^4.2.3" - jest-haste-map "^25.2.1" + jest-haste-map "^25.2.3" jest-regex-util "^25.2.1" - jest-util "^25.2.1" + jest-util "^25.2.3" micromatch "^4.0.2" pirates "^4.0.1" realpath-native "^2.0.0" @@ -336,10 +336,10 @@ "@types/yargs" "^15.0.0" chalk "^3.0.0" -"@jest/types@^25.2.1": - version "25.2.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.2.1.tgz#692c8950d4c21fc6b4cfd141c3470b735c5bffca" - integrity sha512-WuGFGJ3Rrycg+5ZwQTWKjr21M9psANPAWYD28K42hSeUzhv1H591VXIoq0tjs00mydhNOgVOkKSpzRS3CrOYFw== +"@jest/types@^25.2.3": + version "25.2.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.2.3.tgz#035c4fb94e2da472f359ff9a211915d59987f6b6" + integrity sha512-6oLQwO9mKif3Uph3RX5J1i3S7X7xtDHWBaaaoeKw8hOzV6YUd0qDcYcHZ6QXMHDIzSr7zzrEa51o2Ovlj6AtKQ== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^1.1.1" @@ -881,13 +881,13 @@ axios@^0.19.0: follow-redirects "1.5.10" is-buffer "^2.0.2" -babel-jest@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.2.1.tgz#d01ff8025b305a886421b176f3d99ec5461b23b7" - integrity sha512-OiBpQGYtV4rWMuFneIaEsqJB0VdoOBw4SqwO4hA2EhDY/O8RylQ20JwALkxv8iv+CYnyrZZfF+DELPgrdrkRIw== +babel-jest@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.2.3.tgz#8f1c088b1954963e8a5384be2e219dae00d053f4" + integrity sha512-03JjvEwuDrEz/A45K8oggAv+Vqay0xcOdNTJxYFxiuZvB5vlHKo1iZg9Pi5vQTHhNCKpGLb7L/jvUUafyh9j7g== dependencies: - "@jest/transform" "^25.2.1" - "@jest/types" "^25.2.1" + "@jest/transform" "^25.2.3" + "@jest/types" "^25.2.3" "@types/babel__core" "^7.1.0" babel-plugin-istanbul "^6.0.0" babel-preset-jest "^25.2.1" @@ -2002,16 +2002,16 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/expect/-/expect-25.2.1.tgz#f543b6a7fee921c554b5eec9b8ca384551dccedd" - integrity sha512-mRvuu0xujdgYuS0S2dZ489PGAcXl60blmsLofaq7heqn+ZcUOox+VWQvrCee/x+/0WBpxDs7pBWuFYNO5U+txQ== +expect@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/expect/-/expect-25.2.3.tgz#ee714f82bf33c43466fcef139ace0a57b3d0aa48" + integrity sha512-kil4jFRFAK2ySyCyXPqYrphc3EiiKKFd9BthrkKAyHcqr1B84xFTuj5kO8zL+eHRRjT2jQsOPExO0+1Q/fuUXg== dependencies: - "@jest/types" "^25.2.1" + "@jest/types" "^25.2.3" ansi-styles "^4.0.0" jest-get-type "^25.2.1" - jest-matcher-utils "^25.2.1" - jest-message-util "^25.2.1" + jest-matcher-utils "^25.2.3" + jest-message-util "^25.2.3" jest-regex-util "^25.2.1" express@^4.17.1: @@ -2781,56 +2781,56 @@ istanbul-reports@^3.0.0: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jest-changed-files@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-25.2.1.tgz#2dca2c81980479c940addee863d8e73cc3a6b322" - integrity sha512-BB4XjM/dJNUAUtchZ2yJq50VK8XXbmgvt1MUD6kzgzoyz9F0+1ZDQ1yNvLl6pfDwKrMBG9GBY1lzaIBO3JByMg== +jest-changed-files@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-25.2.3.tgz#ad19deef9e47ba37efb432d2c9a67dfd97cc78af" + integrity sha512-EFxy94dvvbqRB36ezIPLKJ4fDIC+jAdNs8i8uTwFpaXd6H3LVc3ova1lNS4ZPWk09OCR2vq5kSdSQgar7zMORg== dependencies: - "@jest/types" "^25.2.1" + "@jest/types" "^25.2.3" execa "^3.2.0" throat "^5.0.0" -jest-cli@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-25.2.1.tgz#b83436541d79cf150b79dd6dbc0acbfc15fc383b" - integrity sha512-7moIaOsKvifiHpCUorpSHb3ALHpyZB9SlrFsvkloEo31KTTgFkHZuQw68LJX8FJwY6pg9LoxJJ2Vy4AFmHMclQ== +jest-cli@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-25.2.3.tgz#47e17240ce6d8ce824ca1a01468ea8824ec6b139" + integrity sha512-T7G0TOkFj0wr33ki5xoq3bxkKC+liwJfjV9SmYIKBozwh91W4YjL1o1dgVCUTB1+sKJa/DiAY0p+eXYE6v2RGw== dependencies: - "@jest/core" "^25.2.1" - "@jest/test-result" "^25.2.1" - "@jest/types" "^25.2.1" + "@jest/core" "^25.2.3" + "@jest/test-result" "^25.2.3" + "@jest/types" "^25.2.3" chalk "^3.0.0" exit "^0.1.2" import-local "^3.0.2" is-ci "^2.0.0" - jest-config "^25.2.1" - jest-util "^25.2.1" - jest-validate "^25.2.1" + jest-config "^25.2.3" + jest-util "^25.2.3" + jest-validate "^25.2.3" prompts "^2.0.1" realpath-native "^2.0.0" yargs "^15.3.1" -jest-config@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-25.2.1.tgz#44c0d39ac8240a46f051708ba22d513481e45201" - integrity sha512-Kh6a3stGSCtVwucvD9wSMaEQBmU0CfqVjHvf0X0iLfCrZfsezvV+sGgRWQAidaTIvo51yAaL217xOwEETMqh6w== +jest-config@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-25.2.3.tgz#c304e91e2ba3763c04b38eafc26d30e5c41b48e8" + integrity sha512-UpTNxN8DgmLLCXFizGuvwIw+ZAPB0T3jbKaFEkzJdGqhSsQrVrk1lxhZNamaVIpWirM2ptYmqwUzvoobGCEkiQ== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^25.2.1" - "@jest/types" "^25.2.1" - babel-jest "^25.2.1" + "@jest/test-sequencer" "^25.2.3" + "@jest/types" "^25.2.3" + babel-jest "^25.2.3" chalk "^3.0.0" deepmerge "^4.2.2" glob "^7.1.1" - jest-environment-jsdom "^25.2.1" - jest-environment-node "^25.2.1" + jest-environment-jsdom "^25.2.3" + jest-environment-node "^25.2.3" jest-get-type "^25.2.1" - jest-jasmine2 "^25.2.1" + jest-jasmine2 "^25.2.3" jest-regex-util "^25.2.1" - jest-resolve "^25.2.1" - jest-util "^25.2.1" - jest-validate "^25.2.1" + jest-resolve "^25.2.3" + jest-util "^25.2.3" + jest-validate "^25.2.3" micromatch "^4.0.2" - pretty-format "^25.2.1" + pretty-format "^25.2.3" realpath-native "^2.0.0" jest-diff@^25.1.0: @@ -2843,56 +2843,57 @@ jest-diff@^25.1.0: jest-get-type "^25.1.0" pretty-format "^25.1.0" -jest-diff@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.2.1.tgz#8c073596cc88356227c86a50d71a23d8a9dfa81a" - integrity sha512-e/TU8VLBBGQQS9tXA5B5LeT806jh7CHUeHbBfrU9UvA2zTbOTRz71UD6fAP1HAhzUEyCVLU2ZP5e8X16A9b0Fg== +jest-diff@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.2.3.tgz#54d601a0a754ef26e808a8c8dbadd278c215aa3f" + integrity sha512-VtZ6LAQtaQpFsmEzps15dQc5ELbJxy4L2DOSo2Ev411TUEtnJPkAMD7JneVypeMJQ1y3hgxN9Ao13n15FAnavg== dependencies: chalk "^3.0.0" diff-sequences "^25.2.1" jest-get-type "^25.2.1" - pretty-format "^25.2.1" + pretty-format "^25.2.3" -jest-docblock@^25.2.0: - version "25.2.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-25.2.0.tgz#b1b78e275131bcaa9a5722e663545ed949c278ee" - integrity sha512-M7ZDbghaxFd2unWkyDFGLZDjPpIbDtEbICXSzwGrUBccFwVG/1dhLLAYX3D+98bFksaJuM0iMZGuIQUzKgnkQw== +jest-docblock@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-25.2.3.tgz#ac45280c43d59e7139f9fbe5896c6e0320c01ebb" + integrity sha512-d3/tmjLLrH5fpRGmIm3oFa3vOaD/IjPxtXVOrfujpfJ9y1tCDB1x/tvunmdOVAyF03/xeMwburl6ITbiQT1mVA== dependencies: detect-newline "^3.0.0" -jest-each@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-25.2.1.tgz#d96b4fc0c035fcddb852f19da42ea241b1943999" - integrity sha512-2vWAaf11IJsSwkEzGph3un4OMSG4v/3hpM2UqJdeU3peGUgUSn75TlXZGQnT0smbnAr4eE+URW1OpE8U9wl0TA== +jest-each@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-25.2.3.tgz#64067ba1508ebbd07e9b126c173ab371e8e6309d" + integrity sha512-RTlmCjsBDK2c9T5oO4MqccA3/5Y8BUtiEy7OOQik1iyCgdnNdHbI0pNEpyapZPBG0nlvZ4mIu7aY6zNUvLraAQ== dependencies: - "@jest/types" "^25.2.1" + "@jest/types" "^25.2.3" chalk "^3.0.0" jest-get-type "^25.2.1" - jest-util "^25.2.1" - pretty-format "^25.2.1" - -jest-environment-jsdom@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-25.2.1.tgz#4f1da1bc46897c6ed818c850464b1114429e3ad5" - integrity sha512-bUhhhXtgrOgLhsFQFXgao8CQPYAEwtaVvhsF6O0A7Ie2uPONtAKCwuxyOM9WJaz9ag2ci5Pg7i2V2PRfGLl95w== - dependencies: - "@jest/environment" "^25.2.1" - "@jest/fake-timers" "^25.2.1" - "@jest/types" "^25.2.1" - jest-mock "^25.2.1" - jest-util "^25.2.1" + jest-util "^25.2.3" + pretty-format "^25.2.3" + +jest-environment-jsdom@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-25.2.3.tgz#f790f87c24878b219d1745f68343380c2d79ab01" + integrity sha512-TLg7nizxIYJafz6tOBAVSmO5Ekswf6Cf3Soseov+mgonXfdYi1I0OZlHlZMJb2fGyXem2ndYFCLrMkwcWPKAnQ== + dependencies: + "@jest/environment" "^25.2.3" + "@jest/fake-timers" "^25.2.3" + "@jest/types" "^25.2.3" + jest-mock "^25.2.3" + jest-util "^25.2.3" jsdom "^15.2.1" -jest-environment-node@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-25.2.1.tgz#d28f1cd18425417a2b9b8b0d81553f4850f8f879" - integrity sha512-HiAAwx4HrkaV9YAyuI56dmPDuTDckJyPpO0BwCu7+Ht2fmlMDhX13HZyyuIGTAIjUrjJiM3paB8tht+0mXtiIA== +jest-environment-node@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-25.2.3.tgz#e50a7e84bf7c7555216aa41aea1e48f53773318f" + integrity sha512-Tu/wlGXfoLtBR4Ym+isz58z3TJkMYX4VnFTkrsxaTGYAxNLN7ArCwL51Ki0WrMd89v+pbCLDj/hDjrb4a2sOrw== dependencies: - "@jest/environment" "^25.2.1" - "@jest/fake-timers" "^25.2.1" - "@jest/types" "^25.2.1" - jest-mock "^25.2.1" - jest-util "^25.2.1" + "@jest/environment" "^25.2.3" + "@jest/fake-timers" "^25.2.3" + "@jest/types" "^25.2.3" + jest-mock "^25.2.3" + jest-util "^25.2.3" + semver "^6.3.0" jest-get-type@^25.1.0: version "25.1.0" @@ -2904,17 +2905,17 @@ jest-get-type@^25.2.1: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.1.tgz#6c83de603c41b1627e6964da2f5454e6aa3c13a6" integrity sha512-EYjTiqcDTCRJDcSNKbLTwn/LcDPEE7ITk8yRMNAOjEsN6yp+Uu+V1gx4djwnuj/DvWg0YGmqaBqPVGsPxlvE7w== -jest-haste-map@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-25.2.1.tgz#61cbb3c99185b3551d63da9daedc5f64b9efe544" - integrity sha512-svz3KbQmv9qeomR0LlRjQfoi7lQbZQkC39m7uHFKhqyEuX4F6DH6HayNPSEbTCZDx6d9/ljxfAcxlPpgQvrpvQ== +jest-haste-map@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-25.2.3.tgz#2649392b5af191f0167a27bfb62e5d96d7eaaade" + integrity sha512-pAP22OHtPr4qgZlJJFks2LLgoQUr4XtM1a+F5UaPIZNiCRnePA0hM3L7aiJ0gzwiNIYwMTfKRwG/S1L28J3A3A== dependencies: - "@jest/types" "^25.2.1" + "@jest/types" "^25.2.3" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.3" jest-serializer "^25.2.1" - jest-util "^25.2.1" + jest-util "^25.2.3" jest-worker "^25.2.1" micromatch "^4.0.2" sane "^4.0.3" @@ -2923,67 +2924,67 @@ jest-haste-map@^25.2.1: optionalDependencies: fsevents "^2.1.2" -jest-jasmine2@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-25.2.1.tgz#5edbe8dd4ed03598fb5db063eb398b67941c8ead" - integrity sha512-He8HdO9jx1LdEaof2vjnvKeJeRPYnn+zXz32X8Z/iOUgAgmP7iZActUkiCCiTazSZlaGlY1iK+LOrqnpGQ0+UA== +jest-jasmine2@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-25.2.3.tgz#a824c5dbe383c63d243aab5e64cc85ab65f87598" + integrity sha512-x9PEGPFdnkSwJj1UG4QxG9JxFdyP8fuJ/UfKXd/eSpK8w9x7MP3VaQDuPQF0UQhCT0YeOITEPkQyqS+ptt0suA== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^25.2.1" + "@jest/environment" "^25.2.3" "@jest/source-map" "^25.2.1" - "@jest/test-result" "^25.2.1" - "@jest/types" "^25.2.1" + "@jest/test-result" "^25.2.3" + "@jest/types" "^25.2.3" chalk "^3.0.0" co "^4.6.0" - expect "^25.2.1" + expect "^25.2.3" is-generator-fn "^2.0.0" - jest-each "^25.2.1" - jest-matcher-utils "^25.2.1" - jest-message-util "^25.2.1" - jest-runtime "^25.2.1" - jest-snapshot "^25.2.1" - jest-util "^25.2.1" - pretty-format "^25.2.1" + jest-each "^25.2.3" + jest-matcher-utils "^25.2.3" + jest-message-util "^25.2.3" + jest-runtime "^25.2.3" + jest-snapshot "^25.2.3" + jest-util "^25.2.3" + pretty-format "^25.2.3" throat "^5.0.0" -jest-leak-detector@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-25.2.1.tgz#77c55c59c32de9600f6bd9aab9540538b541b253" - integrity sha512-bsxjjFksjLWNqC8aLsN0KO2KQ3tiqPqmFpYt+0y4RLHc1dqaThQL68jra5y1f/yhX3dNC8ugksDvqnGxwxjo4w== +jest-leak-detector@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-25.2.3.tgz#4cf39f137925e0061c04c24ca65cae36465f0238" + integrity sha512-yblCMPE7NJKl7778Cf/73yyFWAas5St0iiEBwq7RDyaz6Xd4WPFnPz2j7yDb/Qce71A1IbDoLADlcwD8zT74Aw== dependencies: jest-get-type "^25.2.1" - pretty-format "^25.2.1" + pretty-format "^25.2.3" -jest-matcher-utils@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.2.1.tgz#67da3d3aea74b4de6da990b636d7baebfebac0e4" - integrity sha512-uuoYY8W6eeVxHUEOvrKIVVTl9X6RP+ohQn2Ta2W8OOLMN6oA8pZUKQEPGxLsSqB3RKfpTueurMLrxDTEZGllsA== +jest-matcher-utils@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.2.3.tgz#59285bd6d6c810debc9caa585ed985e46a3f28fd" + integrity sha512-ZmiXiwQRVM9MoKjGMP5YsGGk2Th5ncyRxfXKz5AKsmU8m43kgNZirckVzaP61MlSa9LKmXbevdYqVp1ZKAw2Rw== dependencies: chalk "^3.0.0" - jest-diff "^25.2.1" + jest-diff "^25.2.3" jest-get-type "^25.2.1" - pretty-format "^25.2.1" + pretty-format "^25.2.3" -jest-message-util@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.2.1.tgz#43fb5f239954a28954e74dfea0b75efc4e7377fb" - integrity sha512-pxwehr9uPEuCI9bPjBiZxpFMN0+3wny5p7/E3hbV9XjsqREhJJAMf0czvHtgNeUBo2iAiAI9yi9ICKHPOKePEw== +jest-message-util@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.2.3.tgz#a911c4e3af06df851cc6065d9a3119fd2a3aa240" + integrity sha512-DcyDmdO5LVIeS0ngRvd7rk701XL60dAakUeQJ1tQRby27fyLYXD+V0nqVaC194W7fIlohjVQOZPHmKXIjn+Byw== dependencies: "@babel/code-frame" "^7.0.0" - "@jest/test-result" "^25.2.1" - "@jest/types" "^25.2.1" + "@jest/test-result" "^25.2.3" + "@jest/types" "^25.2.3" "@types/stack-utils" "^1.0.1" chalk "^3.0.0" micromatch "^4.0.2" slash "^3.0.0" stack-utils "^1.0.1" -jest-mock@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-25.2.1.tgz#37b294b8d0aa94c1af7714e039cc410df61593da" - integrity sha512-ZXcmqpCTG1MEm2AP2q9XiJzdbQ655Pnssj+xQMP1thrW2ptEFrd4vSkxTpxk6rnluLPRKagaHmzUpWNxShMvqQ== +jest-mock@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-25.2.3.tgz#b37a581f59d61bd91db27a99bf7eb8b3e5e993d5" + integrity sha512-xlf+pyY0j47zoCs8zGGOGfWyxxLximE8YFOfEK8s4FruR8DtM/UjNj61um+iDuMAFEBDe1bhCXkqiKoCmWjJzg== dependencies: - "@jest/types" "^25.2.1" + "@jest/types" "^25.2.3" jest-pnp-resolver@^1.2.1: version "1.2.1" @@ -2995,78 +2996,78 @@ jest-regex-util@^25.2.1: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.2.1.tgz#db64b0d15cd3642c93b7b9627801d7c518600584" integrity sha512-wroFVJw62LdqTdkL508ZLV82FrJJWVJMIuYG7q4Uunl1WAPTf4ftPKrqqfec4SvOIlvRZUdEX2TFpWR356YG/w== -jest-resolve-dependencies@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-25.2.1.tgz#47b9ee4b9ec0cf387419f175512367118590f8ee" - integrity sha512-fnct/NyrBpBAVUIMa0M876ubufHP/2Rrc038+gCpVT1s7kazV7ZPFlmGfInahCIthbMr644uzt6pnSvmQgTPGg== +jest-resolve-dependencies@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-25.2.3.tgz#cd4d9d068d5238dfbdfa45690f6e902b6413c2da" + integrity sha512-mcWlvjXLlNzgdE9EQxHuaeWICNxozanim87EfyvPwTY0ryWusFZbgF6F8u3E0syJ4FFSooEm0lQ6fgYcnPGAFw== dependencies: - "@jest/types" "^25.2.1" + "@jest/types" "^25.2.3" jest-regex-util "^25.2.1" - jest-snapshot "^25.2.1" + jest-snapshot "^25.2.3" -jest-resolve@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-25.2.1.tgz#44f8f87c5688bad31e762f123540b09cac5907f8" - integrity sha512-5rVc6khEckNH62adcR+jlYd34/jBO/U22VHf+elmyO6UBHNWXSbfy63+spJRN4GQ/0dbu6Hi6ZVdR58bmNG2Eg== +jest-resolve@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-25.2.3.tgz#ababeaf2bb948cb6d2dea8453759116da0fb7842" + integrity sha512-1vZMsvM/DBH258PnpUNSXIgtzpYz+vCVCj9+fcy4akZl4oKbD+9hZSlfe9RIDpU0Fc28ozHQrmwX3EqFRRIHGg== dependencies: - "@jest/types" "^25.2.1" + "@jest/types" "^25.2.3" browser-resolve "^1.11.3" chalk "^3.0.0" jest-pnp-resolver "^1.2.1" realpath-native "^2.0.0" resolve "^1.15.1" -jest-runner@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-25.2.1.tgz#95e57abee889bd61f2cde099d4d8badec6e797ba" - integrity sha512-eONqmMQ2vvKh9BsmJmPmv22DqezFSnwX97rj0L5LvPxQNXTz+rpx7nWiKA7xlvOykLFcspw6worK3+AzhwHWhQ== +jest-runner@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-25.2.3.tgz#88fb448a46cf4ee9194a3e3cf0adbc122e195adb" + integrity sha512-E+u2Zm2TmtTOFEbKs5jllLiV2fwiX77cYc08RdyYZNe/s06wQT3P47aV6a8Rv61L7E2Is7OmozLd0KI/DITRpg== dependencies: - "@jest/console" "^25.2.1" - "@jest/environment" "^25.2.1" - "@jest/test-result" "^25.2.1" - "@jest/types" "^25.2.1" + "@jest/console" "^25.2.3" + "@jest/environment" "^25.2.3" + "@jest/test-result" "^25.2.3" + "@jest/types" "^25.2.3" chalk "^3.0.0" exit "^0.1.2" graceful-fs "^4.2.3" - jest-config "^25.2.1" - jest-docblock "^25.2.0" - jest-haste-map "^25.2.1" - jest-jasmine2 "^25.2.1" - jest-leak-detector "^25.2.1" - jest-message-util "^25.2.1" - jest-resolve "^25.2.1" - jest-runtime "^25.2.1" - jest-util "^25.2.1" + jest-config "^25.2.3" + jest-docblock "^25.2.3" + jest-haste-map "^25.2.3" + jest-jasmine2 "^25.2.3" + jest-leak-detector "^25.2.3" + jest-message-util "^25.2.3" + jest-resolve "^25.2.3" + jest-runtime "^25.2.3" + jest-util "^25.2.3" jest-worker "^25.2.1" source-map-support "^0.5.6" throat "^5.0.0" -jest-runtime@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-25.2.1.tgz#bf6a71e3a654e131326413851c7973f3be235ab0" - integrity sha512-eHEnMrOVeGe8mGDoTZWqCdbsM3RwxsMKVMAj1RTZ4LtRyWqQHKec3RiJiJST5LVj3Mw72clr0U21yoE4p5Mq3w== +jest-runtime@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-25.2.3.tgz#1f0e9ba878a66538c3e9d58be97a6a12c877ed13" + integrity sha512-PZRFeUVF08N24v2G73SDF0b0VpLG7cRNOJ3ggj5TnArBVHkkrWzM3z7txB9OupWu7OO8bH/jFogk6sSjnHLFXQ== dependencies: - "@jest/console" "^25.2.1" - "@jest/environment" "^25.2.1" + "@jest/console" "^25.2.3" + "@jest/environment" "^25.2.3" "@jest/source-map" "^25.2.1" - "@jest/test-result" "^25.2.1" - "@jest/transform" "^25.2.1" - "@jest/types" "^25.2.1" + "@jest/test-result" "^25.2.3" + "@jest/transform" "^25.2.3" + "@jest/types" "^25.2.3" "@types/yargs" "^15.0.0" chalk "^3.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.2.3" - jest-config "^25.2.1" - jest-haste-map "^25.2.1" - jest-message-util "^25.2.1" - jest-mock "^25.2.1" + jest-config "^25.2.3" + jest-haste-map "^25.2.3" + jest-message-util "^25.2.3" + jest-mock "^25.2.3" jest-regex-util "^25.2.1" - jest-resolve "^25.2.1" - jest-snapshot "^25.2.1" - jest-util "^25.2.1" - jest-validate "^25.2.1" + jest-resolve "^25.2.3" + jest-snapshot "^25.2.3" + jest-util "^25.2.3" + jest-validate "^25.2.3" realpath-native "^2.0.0" slash "^3.0.0" strip-bom "^4.0.0" @@ -3077,58 +3078,58 @@ jest-serializer@^25.2.1: resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-25.2.1.tgz#51727a5fc04256f461abe0fa024a022ba165877a" integrity sha512-fibDi7M5ffx6c/P66IkvR4FKkjG5ldePAK1WlbNoaU4GZmIAkS9Le/frAwRUFEX0KdnisSPWf+b1RC5jU7EYJQ== -jest-snapshot@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-25.2.1.tgz#1fdcc8c780f83f0e902dd75df79d0d7313fe939e" - integrity sha512-5Wd8SEJVTXqQvzkQpuYqQt1QTlRj2XVUV/iaEzO+AeSVg6g5pQWu0z2iLdSBlVeWRrX0MyZn6dhxYGwEq4wW0w== +jest-snapshot@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-25.2.3.tgz#2d432fcf9e7f1f7eb3e5012ffcce8035794b76ae" + integrity sha512-HlFVbE6vOZ541mtkwjuAe0rfx9EWhB+QXXneLNOP/s3LlHxGQtX7WFXY5OiH4CkAnCc6BpzLNYS9nfINNRb4Zg== dependencies: "@babel/types" "^7.0.0" - "@jest/types" "^25.2.1" + "@jest/types" "^25.2.3" "@types/prettier" "^1.19.0" chalk "^3.0.0" - expect "^25.2.1" - jest-diff "^25.2.1" + expect "^25.2.3" + jest-diff "^25.2.3" jest-get-type "^25.2.1" - jest-matcher-utils "^25.2.1" - jest-message-util "^25.2.1" - jest-resolve "^25.2.1" + jest-matcher-utils "^25.2.3" + jest-message-util "^25.2.3" + jest-resolve "^25.2.3" make-dir "^3.0.0" natural-compare "^1.4.0" - pretty-format "^25.2.1" + pretty-format "^25.2.3" semver "^6.3.0" -jest-util@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.2.1.tgz#96086efe850ce6d07c42ad5324b80a3ede4246e6" - integrity sha512-oFVMSY/7flrSgEE/B+RApaBZOdLURXRnXCf4COV5td9uRidxudyjA64I1xk2h9Pf3jloSArm96e2FKAbFs0DYg== +jest-util@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.2.3.tgz#0abf95a1d6b96f2de5a3ecd61b36c40a182dc256" + integrity sha512-7tWiMICVSo9lNoObFtqLt9Ezt5exdFlWs5fLe1G4XLY2lEbZc814cw9t4YHScqBkWMfzth8ASHKlYBxiX2rdCw== dependencies: - "@jest/types" "^25.2.1" + "@jest/types" "^25.2.3" chalk "^3.0.0" is-ci "^2.0.0" make-dir "^3.0.0" -jest-validate@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-25.2.1.tgz#a07a4e6697fc58e6ea31c03de541af4d0a475fbc" - integrity sha512-vGtNFPyvylFfTFFfptzqCy5S3cP/N5JJVwm8gsXeZq8jMmvUngfWtuw+Tr5Wjo+dqOle23td8BE0ruGnsONDmw== +jest-validate@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-25.2.3.tgz#ecb0f093cf8ae71d15075fb48439b6f78f1fcb5a" + integrity sha512-GObn91jzU0B0Bv4cusAwjP6vnWy78hJUM8MOSz7keRfnac/ZhQWIsUjvk01IfeXNTemCwgR57EtdjQMzFZGREg== dependencies: - "@jest/types" "^25.2.1" + "@jest/types" "^25.2.3" camelcase "^5.3.1" chalk "^3.0.0" jest-get-type "^25.2.1" leven "^3.1.0" - pretty-format "^25.2.1" + pretty-format "^25.2.3" -jest-watcher@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-25.2.1.tgz#605aeef37ee4ce867f2f58485fdb9eea0f8cb369" - integrity sha512-m35rftCYE2EEh01+IIpQMpdB9VXBAjITZvgP4drd/LI3JEJIdd0Pkf/qJZ3oiMQJdqmuwYcTqE+BL40MxVv83Q== +jest-watcher@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-25.2.3.tgz#a494fe3ddb62da62b0e697abfea457de8f388f1f" + integrity sha512-F6ERbdvJk8nbaRon9lLQVl4kp+vToCCHmy+uWW5QQ8/8/g2jkrZKJQnlQINrYQp0ewg31Bztkhs4nxsZMx6wDg== dependencies: - "@jest/test-result" "^25.2.1" - "@jest/types" "^25.2.1" + "@jest/test-result" "^25.2.3" + "@jest/types" "^25.2.3" ansi-escapes "^4.2.1" chalk "^3.0.0" - jest-util "^25.2.1" + jest-util "^25.2.3" string-length "^3.1.0" jest-worker@^25.2.1: @@ -3139,14 +3140,14 @@ jest-worker@^25.2.1: merge-stream "^2.0.0" supports-color "^7.0.0" -jest@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest/-/jest-25.2.1.tgz#aa9a956c33fe1f10f016efade2c3e8846d0056d8" - integrity sha512-YXvGtrb4YmfM/JraXaM3jc3NnvhVTHxkdRC9Oof4JtJWwgvIdy0/X01QxeWXqKfCaHmlXi/nKrcPI1+bf0w/Ww== +jest@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/jest/-/jest-25.2.3.tgz#0cc9b35192f236fe1d5e76ed8eb3a54e7e0ee2e0" + integrity sha512-UbUmyGeZt0/sCIj/zsWOY0qFfQsx2qEFIZp0iEj8yVH6qASfR22fJOf12gFuSPsdSufam+llZBB0MdXWCg6EEQ== dependencies: - "@jest/core" "^25.2.1" + "@jest/core" "^25.2.3" import-local "^3.0.2" - jest-cli "^25.2.1" + jest-cli "^25.2.3" js-sha256@^0.9.0: version "0.9.0" @@ -4045,12 +4046,12 @@ pretty-format@^25.1.0: ansi-styles "^4.0.0" react-is "^16.12.0" -pretty-format@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.2.1.tgz#3b8f7b9241faa6736cdbc32879bee18454d1318d" - integrity sha512-YS+e9oGYIbEeAFgqTU8qeZ3DN2Pz0iaD81ox+iUjLIXVJWeB7Ro/2AnfxRnl/yJJ5R674d7E3jLPuh6bwg0+qw== +pretty-format@^25.2.3: + version "25.2.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.2.3.tgz#ba6e9603a0d80fa2e470b1fed55de1f9bfd81421" + integrity sha512-IP4+5UOAVGoyqC/DiomOeHBUKN6q00gfyT2qpAsRH64tgOKB2yF7FHJXC18OCiU0/YFierACup/zdCOWw0F/0w== dependencies: - "@jest/types" "^25.2.1" + "@jest/types" "^25.2.3" ansi-regex "^5.0.0" ansi-styles "^4.0.0" react-is "^16.12.0" From be64cf858fc8f7903d7601491e9130023199b698 Mon Sep 17 00:00:00 2001 From: rishflab Date: Thu, 26 Mar 2020 18:47:11 +1100 Subject: [PATCH 10/88] Lock datadir Place a lock on the datadir specified in config. cnd aborts with an error message if the specified datadir is already being used by another cnd process. Closes #2278 --- Cargo.lock | 11 +++++++++++ cnd/Cargo.toml | 1 + cnd/src/main.rs | 7 +++++++ 3 files changed, 19 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 7b1dc67fd0..575f707ee6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -547,6 +547,7 @@ dependencies = [ "directories", "ethbloom", "fern", + "fs2", "futures 0.3.4", "genawaiter", "hex 0.4.2", @@ -1008,6 +1009,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi 0.3.8", +] + [[package]] name = "fuchsia-cprng" version = "0.1.1" diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index 95aa778e45..c45bc7cb3b 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -22,6 +22,7 @@ digest-macro-derive = { path = "../digest-macro-derive" } directories = "2.0" ethbloom = "0.9.0" fern = { version = "0.6", features = ["colored"] } +fs2 = "0.4.3" futures = { version = "0.3", features = ["async-await"], default-features = false } genawaiter = "0.99" hex = "0.4" diff --git a/cnd/src/main.rs b/cnd/src/main.rs index 91a351218b..f166bf9ccd 100644 --- a/cnd/src/main.rs +++ b/cnd/src/main.rs @@ -27,6 +27,7 @@ use cnd::{ seed::RootSeed, swap_protocols::{Facade, LedgerStates, SwapCommunicationStates, SwapErrorStates}, }; +use fs2::FileExt; use rand::rngs::OsRng; use std::{process, sync::Arc}; use structopt::StructOpt; @@ -52,6 +53,12 @@ fn main() -> anyhow::Result<()> { crate::trace::init_tracing(settings.logging.level)?; + let path = &settings.data.dir.to_path_buf(); + + let file = std::fs::File::open(&path)?; + file.try_lock_exclusive()?; + file.lock_exclusive()?; + let seed = RootSeed::from_dir_or_generate(&settings.data.dir, OsRng)?; let mut runtime = runtime::Builder::new() From 35ccb0165d58f971a51ac79b2ee2787291f5231e Mon Sep 17 00:00:00 2001 From: rishflab Date: Fri, 27 Mar 2020 08:58:54 +1100 Subject: [PATCH 11/88] Move datadir locking logic into trait --- cnd/src/file_lock.rs | 16 ++++++++++++++++ cnd/src/lib.rs | 1 + cnd/src/main.rs | 10 +++------- 3 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 cnd/src/file_lock.rs diff --git a/cnd/src/file_lock.rs b/cnd/src/file_lock.rs new file mode 100644 index 0000000000..2df52915de --- /dev/null +++ b/cnd/src/file_lock.rs @@ -0,0 +1,16 @@ +use anyhow::Context; +use fs2::FileExt; +use std::{fs::File, path::PathBuf}; + +pub trait TryLockExclusive { + fn try_lock_exclusive(&self) -> anyhow::Result; +} + +impl TryLockExclusive for PathBuf { + fn try_lock_exclusive(&self) -> anyhow::Result { + let file = File::open(self)?; + file.try_lock_exclusive() + .with_context(|| format!("Could not acquire file system lock on {}", self.display()))?; + Ok(file) + } +} diff --git a/cnd/src/lib.rs b/cnd/src/lib.rs index e122a83dc7..8f2a3465c0 100644 --- a/cnd/src/lib.rs +++ b/cnd/src/lib.rs @@ -44,6 +44,7 @@ pub mod network; pub mod quickcheck; #[macro_use] pub mod seed; +pub mod file_lock; pub mod jsonrpc; #[cfg(test)] pub mod spectral_ext; diff --git a/cnd/src/main.rs b/cnd/src/main.rs index f166bf9ccd..818a7be468 100644 --- a/cnd/src/main.rs +++ b/cnd/src/main.rs @@ -21,18 +21,18 @@ use cnd::{ }, config::{self, validation::validate_blockchain_config, Settings}, db::Sqlite, + file_lock::TryLockExclusive, http_api::route_factory, jsonrpc, load_swaps, network::Swarm, seed::RootSeed, swap_protocols::{Facade, LedgerStates, SwapCommunicationStates, SwapErrorStates}, }; -use fs2::FileExt; + use rand::rngs::OsRng; use std::{process, sync::Arc}; use structopt::StructOpt; use tokio::runtime; - mod cli; mod trace; @@ -53,11 +53,7 @@ fn main() -> anyhow::Result<()> { crate::trace::init_tracing(settings.logging.level)?; - let path = &settings.data.dir.to_path_buf(); - - let file = std::fs::File::open(&path)?; - file.try_lock_exclusive()?; - file.lock_exclusive()?; + let _locked_datadir = &settings.data.dir.try_lock_exclusive()?; let seed = RootSeed::from_dir_or_generate(&settings.data.dir, OsRng)?; From e4e4ab3bc05e36a67a665e81510073da74a83827 Mon Sep 17 00:00:00 2001 From: Lucas Soriano del Pino Date: Sat, 28 Mar 2020 11:33:25 +1100 Subject: [PATCH 12/88] Add yalc files to .gitignore `yalc` seems more reliable than `yarn link`. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 5adde8eb3f..a46acfadeb 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,5 @@ TAGS # Blockchain nodes artifacts blockchain_nodes/bitcoin/ blockchain_nodes/parity/parity +.yalc +yalc.lock From b794b08feae63bfed790649336f7347f1a64db57 Mon Sep 17 00:00:00 2001 From: Lucas Soriano del Pino Date: Mon, 30 Mar 2020 13:32:29 +1100 Subject: [PATCH 13/88] Replace timeout function with external dependency --- api_tests/package.json | 1 + api_tests/src/actor_test.ts | 4 ++-- api_tests/src/utils.ts | 13 ------------- api_tests/yarn.lock | 7 +++++++ 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 162eb8efdb..e83dcd2768 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -49,6 +49,7 @@ "jest": "^25.2.3", "js-sha256": "^0.9.0", "log4js": "^6.1.2", + "p-timeout": "^3.2.0", "prettier": "^2.0.2", "rimraf": "^3.0.2", "satoshi-bitcoin": "^1.0.4", diff --git a/api_tests/src/actor_test.ts b/api_tests/src/actor_test.ts index 96eff5b2c0..9fe0b3eaac 100644 --- a/api_tests/src/actor_test.ts +++ b/api_tests/src/actor_test.ts @@ -1,7 +1,7 @@ import { Actors } from "./actors"; import { createActors } from "./create_actors"; import JasmineSmacker from "smack-my-jasmine-up"; -import { timeout } from "./utils"; +import pTimeout from "p-timeout"; import ProvidesCallback = jest.ProvidesCallback; /* @@ -24,7 +24,7 @@ function nActorTest( const actors = await createActors(name, actorNames); try { - await timeout(60_000, testFn(actors)); + await pTimeout(testFn(actors), 60_000); } catch (e) { for (const actorName of actorNames) { await actors.getActorByName(actorName).dumpState(); diff --git a/api_tests/src/utils.ts b/api_tests/src/utils.ts index 69bfece21b..4e8f0ef11a 100644 --- a/api_tests/src/utils.ts +++ b/api_tests/src/utils.ts @@ -46,19 +46,6 @@ export async function sleep(time: number) { }); } -export async function timeout(ms: number, promise: Promise): Promise { - // Create a promise that rejects in milliseconds - const timeout = new Promise((_, reject) => { - const id = setTimeout(() => { - clearTimeout(id); - reject(new Error(`timed out after ${ms}ms`)); - }, ms); - }); - - // Returns a race between our timeout and the passed in promise - return Promise.race([promise, timeout]); -} - export const DEFAULT_ALPHA = { ledger: { name: "bitcoin", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index c0867fe044..6cc24bf294 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -3915,6 +3915,13 @@ p-timeout@^2.0.1: dependencies: p-finally "^1.0.0" +p-timeout@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" + p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" From 6f24ff282d8c3db637b661164a90d12e294ffac4 Mon Sep 17 00:00:00 2001 From: Lucas Soriano del Pino Date: Thu, 26 Mar 2020 18:27:26 +1100 Subject: [PATCH 14/88] Configure Jasmine to report current test name This allows us to remove the weird `smack-my-jasmine-up` dependency. --- api_tests/jest.config-dry.js | 1 + api_tests/jest.config-e2e.js | 1 + api_tests/package.json | 5 ++-- api_tests/src/actor_test.ts | 4 ++-- api_tests/src/configure_jasmine.ts | 5 ++++ api_tests/tests/dry/sanity.ts | 2 +- .../types/smack-my-jasmine-up/index.d.ts | 5 ---- api_tests/yarn.lock | 23 +++++++++++++++---- 8 files changed, 31 insertions(+), 15 deletions(-) create mode 100644 api_tests/src/configure_jasmine.ts delete mode 100644 api_tests/types/smack-my-jasmine-up/index.d.ts diff --git a/api_tests/jest.config-dry.js b/api_tests/jest.config-dry.js index 34b19b0130..d98be2b1f2 100644 --- a/api_tests/jest.config-dry.js +++ b/api_tests/jest.config-dry.js @@ -8,4 +8,5 @@ module.exports = { moduleFileExtensions: ["ts", "js", "json", "node"], testEnvironment: "/dist/src/dry_test_environment", testTimeout: 63000, + setupFilesAfterEnv: ["/src/configure_jasmine.ts"], }; diff --git a/api_tests/jest.config-e2e.js b/api_tests/jest.config-e2e.js index a3d38b5da2..904245bcca 100644 --- a/api_tests/jest.config-e2e.js +++ b/api_tests/jest.config-e2e.js @@ -8,4 +8,5 @@ module.exports = { moduleFileExtensions: ["ts", "js", "json", "node"], testEnvironment: "/dist/src/e2e_test_environment", testTimeout: 63000, + setupFilesAfterEnv: ["/src/configure_jasmine.ts"], }; diff --git a/api_tests/package.json b/api_tests/package.json index e83dcd2768..d0a25a8356 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -7,7 +7,7 @@ "check": "tsc && prettier --check '**/*.{ts,json,yml}' && tslint --project .", "pretest": "cargo build --bin cnd && tsc", "dry": "jest --config jest.config-dry.js --maxWorkers=4", - "e2e": "yarn jest --config jest.config-e2e.js --runInBand --forceExit --bail", + "e2e": "jest --config jest.config-e2e.js --runInBand --forceExit --bail", "test": "yarn dry && yarn e2e", "ci": "tsc && yarn dry && yarn e2e", "fix": "tslint --project . --fix && prettier --write '**/*.{ts,js,json,yml}'" @@ -24,6 +24,7 @@ "@types/chai-as-promised": "^7.1.2", "@types/chai-json-schema": "^1.4.5", "@types/chai-subset": "^1.3.3", + "@types/jasmine": "^3.5.10", "@types/jest": "^25.1.4", "@types/log4js": "^2.3.5", "@types/node": "^13.9", @@ -46,6 +47,7 @@ "comit-sdk": "^0.15.1", "ethers": "^4.0.46", "get-port": "^5.1.1", + "jasmine": "^3.5.0", "jest": "^25.2.3", "js-sha256": "^0.9.0", "log4js": "^6.1.2", @@ -53,7 +55,6 @@ "prettier": "^2.0.2", "rimraf": "^3.0.2", "satoshi-bitcoin": "^1.0.4", - "smack-my-jasmine-up": "^0.0.3", "tail": "^2.0.3", "temp-write": "^4.0.0", "tmp": "^0.1.0", diff --git a/api_tests/src/actor_test.ts b/api_tests/src/actor_test.ts index 9fe0b3eaac..678d6f170b 100644 --- a/api_tests/src/actor_test.ts +++ b/api_tests/src/actor_test.ts @@ -1,6 +1,5 @@ import { Actors } from "./actors"; import { createActors } from "./create_actors"; -import JasmineSmacker from "smack-my-jasmine-up"; import pTimeout from "p-timeout"; import ProvidesCallback = jest.ProvidesCallback; @@ -13,7 +12,8 @@ function nActorTest( testFn: (actors: Actors) => Promise ): ProvidesCallback { return async (done) => { - const name = JasmineSmacker.getCurrentTestName(); + // @ts-ignore + const name = jasmine.currentTestName; if (!name.match(/[A-z0-9\-]+/)) { // We use the test name as a file name for the log and hence need to restrict it. throw new Error( diff --git a/api_tests/src/configure_jasmine.ts b/api_tests/src/configure_jasmine.ts new file mode 100644 index 0000000000..80242dbb0a --- /dev/null +++ b/api_tests/src/configure_jasmine.ts @@ -0,0 +1,5 @@ +jasmine.getEnv().addReporter({ + specStarted: (result) => + // @ts-ignore + (jasmine.currentTestName = result.description), +}); diff --git a/api_tests/tests/dry/sanity.ts b/api_tests/tests/dry/sanity.ts index b617b1ea63..059ea9c905 100644 --- a/api_tests/tests/dry/sanity.ts +++ b/api_tests/tests/dry/sanity.ts @@ -11,7 +11,7 @@ import { Entity, Link } from "comit-sdk"; // Sanity tests // // ******************************************** // -describe("Sanity - peers using IP", () => { +describe("Sanity", () => { it( "invalid-swap-yields-404", oneActorTest(async ({ alice }) => { diff --git a/api_tests/types/smack-my-jasmine-up/index.d.ts b/api_tests/types/smack-my-jasmine-up/index.d.ts deleted file mode 100644 index e64f145118..0000000000 --- a/api_tests/types/smack-my-jasmine-up/index.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare module "smack-my-jasmine-up" { - export default class JasmineSmacker { - static getCurrentTestName(); - } -} diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 6cc24bf294..57e1a15919 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -544,6 +544,11 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" +"@types/jasmine@^3.5.10": + version "3.5.10" + resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.5.10.tgz#a1a41012012b5da9d4b205ba9eba58f6cce2ab7b" + integrity sha512-3F8qpwBAiVc5+HPJeXJpbrl+XjawGmciN5LgiO7Gv1pl1RHtjoMNqZpqEksaPJW05ViKe8snYInRs6xB25Xdew== + "@types/jest@^25.1.4": version "25.1.4" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-25.1.4.tgz#9e9f1e59dda86d3fd56afce71d1ea1b331f6f760" @@ -2781,6 +2786,19 @@ istanbul-reports@^3.0.0: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +jasmine-core@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.5.0.tgz#132c23e645af96d85c8bca13c8758b18429fc1e4" + integrity sha512-nCeAiw37MIMA9w9IXso7bRaLl+c/ef3wnxsoSAlYrzS+Ot0zTG6nU8G/cIfGkqpkjX2wNaIW9RFG0TwIFnG6bA== + +jasmine@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-3.5.0.tgz#7101eabfd043a1fc82ac24e0ab6ec56081357f9e" + integrity sha512-DYypSryORqzsGoMazemIHUfMkXM7I7easFaxAvNM3Mr6Xz3Fy36TupTrAOxZWN8MVKEU5xECv22J4tUQf3uBzQ== + dependencies: + glob "^7.1.4" + jasmine-core "~3.5.0" + jest-changed-files@^25.2.3: version "25.2.3" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-25.2.3.tgz#ad19deef9e47ba37efb432d2c9a67dfd97cc78af" @@ -4547,11 +4565,6 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -smack-my-jasmine-up@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/smack-my-jasmine-up/-/smack-my-jasmine-up-0.0.3.tgz#44c9420220f7bd90b7ffe329b343828eb3c05972" - integrity sha512-DLaxxk5L3vrnjgqRwgUsFtmw4CvjnOmaXdxHp89rKTxt03erWQ0xgE0ZKZtllv+3BH3xljF5fR5pHIe27OLRbg== - snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" From 9f7531713619f8582f32169fa7450623770160d8 Mon Sep 17 00:00:00 2001 From: Lucas Soriano del Pino Date: Sat, 28 Mar 2020 15:42:16 +1100 Subject: [PATCH 15/88] Close all blockchain-related handles during Jest teardown We ensure that all nodes are stopped and all wallets are closed during Jest teardown. --- api_tests/package.json | 2 +- api_tests/src/actor_test.ts | 3 ++- api_tests/src/e2e_test_environment.ts | 12 ++++++++---- api_tests/src/wallets/bitcoin.ts | 4 ++++ api_tests/src/wallets/index.ts | 14 ++++++++++++++ api_tests/src/wallets/lightning.ts | 4 ++++ api_tests/yarn.lock | 8 ++++---- 7 files changed, 37 insertions(+), 10 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index d0a25a8356..1c9bc311fd 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -44,7 +44,7 @@ "chai-json-schema": "^1.5.0", "chai-string": "^1.5.0", "chai-subset": "^1.6.0", - "comit-sdk": "^0.15.1", + "comit-sdk": "^0.15.2", "ethers": "^4.0.46", "get-port": "^5.1.1", "jasmine": "^3.5.0", diff --git a/api_tests/src/actor_test.ts b/api_tests/src/actor_test.ts index 678d6f170b..9e3f5dfa00 100644 --- a/api_tests/src/actor_test.ts +++ b/api_tests/src/actor_test.ts @@ -32,7 +32,8 @@ function nActorTest( throw e; } finally { for (const actorName of actorNames) { - await actors.getActorByName(actorName).stop(); + const actor = actors.getActorByName(actorName); + await Promise.all([actor.stop(), actor.wallets.close()]); } } done(); diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index eecf121c33..f830aab435 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -258,19 +258,23 @@ export default class E2ETestEnvironment extends NodeEnvironment { const tasks = []; if (this.bitcoinLedger) { - tasks.push(this.bitcoinLedger.stop); + tasks.push(this.bitcoinLedger.stop()); } if (this.ethereumLedger) { - tasks.push(this.ethereumLedger.stop); + tasks.push(this.ethereumLedger.stop()); } if (this.aliceLightning) { - tasks.push(this.aliceLightning.stop); + tasks.push(this.aliceLightning.stop()); } if (this.bobLightning) { - tasks.push(this.bobLightning.stop); + tasks.push(this.bobLightning.stop()); + } + + for (const [, wallet] of Object.entries(this.global.lndWallets)) { + tasks.push(wallet.close()); } await Promise.all(tasks); diff --git a/api_tests/src/wallets/bitcoin.ts b/api_tests/src/wallets/bitcoin.ts index bbb29ef634..d83aa8a0a6 100644 --- a/api_tests/src/wallets/bitcoin.ts +++ b/api_tests/src/wallets/bitcoin.ts @@ -98,4 +98,8 @@ export class BitcoinWallet implements Wallet { return blockchainInfo.mediantime; } + + public async close(): Promise { + return this.inner.close(); + } } diff --git a/api_tests/src/wallets/index.ts b/api_tests/src/wallets/index.ts index 13e283cf76..6a189b90dd 100644 --- a/api_tests/src/wallets/index.ts +++ b/api_tests/src/wallets/index.ts @@ -83,6 +83,20 @@ export class Wallets { } } } + + public async close(): Promise { + const tasks = []; + + if (this.wallets.lightning) { + tasks.push(this.wallets.lightning.close()); + } + + if (this.wallets.bitcoin) { + tasks.push(this.wallets.bitcoin.close()); + } + + return Promise.all(tasks); + } } export async function pollUntilMinted( diff --git a/api_tests/src/wallets/lightning.ts b/api_tests/src/wallets/lightning.ts index b5540d1a24..52c51046e6 100644 --- a/api_tests/src/wallets/lightning.ts +++ b/api_tests/src/wallets/lightning.ts @@ -172,4 +172,8 @@ export class LightningWallet implements Wallet { await sleep(500); return this.pollUntilChannelIsOpen(outpoint); } + + public async close(): Promise { + return this.bitcoinWallet.close(); + } } diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 57e1a15919..92ec686ead 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -1562,10 +1562,10 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -comit-sdk@^0.15.1: - version "0.15.1" - resolved "https://registry.yarnpkg.com/comit-sdk/-/comit-sdk-0.15.1.tgz#2ccc262a9ba5ee86999284c773f34d659b967b8d" - integrity sha512-5oKJ1Ns4/9qei9AzzeeZOrb36Qb0yewpKQyvV/odCBQrMqbXHhcrGl0ArC6X5N7dED0IDEAI7J4G2qrVCsG1Cg== +comit-sdk@^0.15.2: + version "0.15.2" + resolved "https://registry.yarnpkg.com/comit-sdk/-/comit-sdk-0.15.2.tgz#affca33aed1cc18e7a3d39109a47041e3f0864e0" + integrity sha512-5HTRYRTR2Qpeiq29sTuTtPVkIF2CxEA7cku/8G3hHNp+EK2qicaV6bvJ9rhRitKY5EWSmWzBLOg+NzpCqvyyPg== dependencies: "@radar/lnrpc" "^0.9.1-beta" axios "^0.19.0" From 251c44fdca624335230afe1710d11975d9caf6c8 Mon Sep 17 00:00:00 2001 From: Lucas Soriano del Pino Date: Sat, 28 Mar 2020 16:37:51 +1100 Subject: [PATCH 16/88] Shut down logger during Jest teardown --- api_tests/src/dry_test_environment.ts | 4 +++- api_tests/src/e2e_test_environment.ts | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/api_tests/src/dry_test_environment.ts b/api_tests/src/dry_test_environment.ts index eda1943bb6..2d6e19f97e 100644 --- a/api_tests/src/dry_test_environment.ts +++ b/api_tests/src/dry_test_environment.ts @@ -3,7 +3,7 @@ import { execAsync, HarnessGlobal, mkdirAsync, rimrafAsync } from "./utils"; import NodeEnvironment from "jest-environment-node"; import { Mutex } from "async-mutex"; import path from "path"; -import { configure } from "log4js"; +import { configure, shutdown as loggerShutdown } from "log4js"; // ************************ // // Setting global variables // @@ -83,6 +83,8 @@ export default class DryTestEnvironment extends NodeEnvironment { async teardown() { await super.teardown(); + + loggerShutdown(); } private extractDocblockPragmas( diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index f830aab435..54127d57c3 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -13,7 +13,7 @@ import EthereumLedger from "./ledgers/ethereum"; import LightningLedger from "./ledgers/lightning"; import { ParityInstance } from "./ledgers/parity_instance"; import { LndInstance } from "./ledgers/lnd_instance"; -import { configure, Logger } from "log4js"; +import { configure, Logger, shutdown as loggerShutdown } from "log4js"; // ************************ // // Setting global variables // @@ -251,6 +251,9 @@ export default class E2ETestEnvironment extends NodeEnvironment { this.logger.info("Tearing down test environment"); await this.cleanupAll(); + + loggerShutdown(); + this.logger.info("Tearing down complete"); } From 3fb3ffb6490c27770f48f32883bed0b5b732cc20 Mon Sep 17 00:00:00 2001 From: Lucas Soriano del Pino Date: Sat, 28 Mar 2020 16:38:17 +1100 Subject: [PATCH 17/88] Close log files after 5 seconds of inactivity To prevent reaching the limit of listeners. --- api_tests/src/dry_test_environment.ts | 1 + api_tests/src/e2e_test_environment.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/api_tests/src/dry_test_environment.ts b/api_tests/src/dry_test_environment.ts index 2d6e19f97e..ea7096ee15 100644 --- a/api_tests/src/dry_test_environment.ts +++ b/api_tests/src/dry_test_environment.ts @@ -55,6 +55,7 @@ export default class DryTestEnvironment extends NodeEnvironment { type: "pattern", pattern: "%d %5.10p: %m", }, + timeout: 5000, }, }, categories: { diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index 54127d57c3..ff94c2af95 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -73,6 +73,7 @@ export default class E2ETestEnvironment extends NodeEnvironment { type: "pattern", pattern: "%d %5.10p: %m", }, + timeout: 5000, }, }, categories: { From 07d7a0afa41e98f21ddbb6acb92afd20d2038d41 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2020 14:12:44 +0000 Subject: [PATCH 18/88] Bump thiserror from 1.0.13 to 1.0.14 Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.13 to 1.0.14. - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.13...1.0.14) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b1dc67fd0..90cd0dd2b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3650,18 +3650,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3711fd1c4e75b3eff12ba5c40dba762b6b65c5476e8174c1a664772060c49bf" +checksum = "f0570dc61221295909abdb95c739f2e74325e14293b2026b0a7e195091ec54ae" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae2b85ba4c9aa32dd3343bd80eb8d22e9b54b7688c17ea3907f236885353b233" +checksum = "227362df41d566be41a28f64401e07a043157c21c14b9785a0d8e256f940a8fd" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", From 51d95393b5cbfb701785c00d6d76b001793fedcd Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2020 14:13:14 +0000 Subject: [PATCH 19/88] Bump derivative from 2.0.2 to 2.1.0 Bumps [derivative](https://github.com/mcarton/rust-derivative) from 2.0.2 to 2.1.0. - [Release notes](https://github.com/mcarton/rust-derivative/releases) - [Changelog](https://github.com/mcarton/rust-derivative/blob/master/CHANGELOG.md) - [Commits](https://github.com/mcarton/rust-derivative/commits) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b1dc67fd0..ad2c13c74c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -539,7 +539,7 @@ dependencies = [ "blockchain_contracts", "chrono", "config", - "derivative 2.0.2", + "derivative 2.1.0", "diesel", "diesel_migrations", "digest 0.1.0", @@ -783,9 +783,9 @@ dependencies = [ [[package]] name = "derivative" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b94d2eb97732ec84b4e25eaf37db890e317b80e921f168c82cb5282473f8151" +checksum = "1eae4d76b7cefedd1b4f8cc24378b2fbd1ac1b66e3bbebe8e2192d3be81cb355" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", @@ -1682,7 +1682,7 @@ name = "libp2p-comit" version = "0.1.0" dependencies = [ "bytes 0.5.4", - "derivative 2.0.2", + "derivative 2.1.0", "futures 0.3.4", "futures_codec 0.4.0", "libp2p", From 95bf0f8b6f47d28b0d552000b2d4ab8d3b5bb577 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2020 18:20:47 +0000 Subject: [PATCH 20/88] Bump ts-jest from 25.2.1 to 25.3.0 in /api_tests Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 25.2.1 to 25.3.0. - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/master/CHANGELOG.md) - [Commits](https://github.com/kulshekhar/ts-jest/compare/25.2.1...v25.3.0) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 48 ++++++++++++++++++------------------------ 2 files changed, 21 insertions(+), 29 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 162eb8efdb..54aced8f1a 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -56,7 +56,7 @@ "tail": "^2.0.3", "temp-write": "^4.0.0", "tmp": "^0.1.0", - "ts-jest": "^25.2.1", + "ts-jest": "^25.3.0", "ts-node": "^8.8.1", "tslint": "^6.1.0", "tslint-config-prettier": "^1.18.0", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index c0867fe044..2ceeb089e7 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -2099,16 +2099,11 @@ fast-deep-equal@^2.0.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= -fast-json-stable-stringify@2.x: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= - fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" @@ -3549,7 +3544,12 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@0.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: +mkdirp@1.x: + version "1.0.3" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.3.tgz#4cf2e30ad45959dddea53ad97d518b6c8205e1ea" + integrity sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g== + +mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -4432,16 +4432,16 @@ scrypt-js@2.0.4: resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== -semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5, semver@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^6.0.0, semver@^6.3.0: +semver@6.x, semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + send@0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" @@ -4952,10 +4952,10 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" -ts-jest@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-25.2.1.tgz#49bf05da26a8b7fbfbc36b4ae2fcdc2fef35c85d" - integrity sha512-TnntkEEjuXq/Gxpw7xToarmHbAafgCaAzOpnajnFC6jI7oo1trMzAHA04eWpc3MhV6+yvhE8uUBAmN+teRJh0A== +ts-jest@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-25.3.0.tgz#c12d34573cbe34d49f10567940e44fd19d1c9178" + integrity sha512-qH/uhaC+AFDU9JfAueSr0epIFJkGMvUPog4FxSEVAtPOur1Oni5WBJMiQIkfHvc7PviVRsnlVLLY2I6221CQew== dependencies: bs-logger "0.x" buffer-from "1.x" @@ -4963,10 +4963,10 @@ ts-jest@^25.2.1: json5 "2.x" lodash.memoize "4.x" make-error "1.x" - mkdirp "0.x" + mkdirp "1.x" resolve "1.x" - semver "^5.5" - yargs-parser "^16.1.0" + semver "6.x" + yargs-parser "^18.1.1" ts-node@^8.8.1: version "8.8.1" @@ -5335,14 +5335,6 @@ yallist@^3.0.0, yallist@^3.0.3: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yargs-parser@^16.1.0: - version "16.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-16.1.0.tgz#73747d53ae187e7b8dbe333f95714c76ea00ecf1" - integrity sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - yargs-parser@^18.1.1: version "18.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.1.tgz#bf7407b915427fc760fcbbccc6c82b4f0ffcbd37" From 45aa642f539a9e4b31edc30841b3cc6818578803 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2020 18:21:33 +0000 Subject: [PATCH 21/88] Bump comit-sdk from 0.15.1 to 0.15.2 in /api_tests Bumps [comit-sdk](https://github.com/comit-network/comit-js-sdk) from 0.15.1 to 0.15.2. - [Release notes](https://github.com/comit-network/comit-js-sdk/releases) - [Changelog](https://github.com/comit-network/comit-js-sdk/blob/master/CHANGELOG.md) - [Commits](https://github.com/comit-network/comit-js-sdk/compare/0.15.1...0.15.2) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 162eb8efdb..3a0e2bf61b 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -43,7 +43,7 @@ "chai-json-schema": "^1.5.0", "chai-string": "^1.5.0", "chai-subset": "^1.6.0", - "comit-sdk": "^0.15.1", + "comit-sdk": "^0.15.2", "ethers": "^4.0.46", "get-port": "^5.1.1", "jest": "^25.2.3", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index c0867fe044..ccc0dad5d4 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -1557,10 +1557,10 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -comit-sdk@^0.15.1: - version "0.15.1" - resolved "https://registry.yarnpkg.com/comit-sdk/-/comit-sdk-0.15.1.tgz#2ccc262a9ba5ee86999284c773f34d659b967b8d" - integrity sha512-5oKJ1Ns4/9qei9AzzeeZOrb36Qb0yewpKQyvV/odCBQrMqbXHhcrGl0ArC6X5N7dED0IDEAI7J4G2qrVCsG1Cg== +comit-sdk@^0.15.2: + version "0.15.2" + resolved "https://registry.yarnpkg.com/comit-sdk/-/comit-sdk-0.15.2.tgz#affca33aed1cc18e7a3d39109a47041e3f0864e0" + integrity sha512-5HTRYRTR2Qpeiq29sTuTtPVkIF2CxEA7cku/8G3hHNp+EK2qicaV6bvJ9rhRitKY5EWSmWzBLOg+NzpCqvyyPg== dependencies: "@radar/lnrpc" "^0.9.1-beta" axios "^0.19.0" From 151183d010a150dcf1778c137a42e116787d57ae Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2020 21:15:39 +0000 Subject: [PATCH 22/88] Bump @types/node from 13.9.4 to 13.9.5 in /api_tests Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 13.9.4 to 13.9.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot-preview[bot] --- api_tests/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index e87f965562..9a3f72aee9 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -575,9 +575,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*", "@types/node@^13.9": - version "13.9.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.4.tgz#63c58e67999bfbfa688dd49ed84639b01b543606" - integrity sha512-uzaaDXey/NI2l7kU+xCgWu852Dh/zmf6ZKApc0YQEQpY4DaiZFmLN29E6SLHJfSedj3iNWAndSwfSBpEDadJfg== + version "13.9.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.5.tgz#59738bf30b31aea1faa2df7f4a5f55613750cf00" + integrity sha512-hkzMMD3xu6BrJpGVLeQ3htQQNAcOrJjX7WFmtK8zWQpz2UJf13LCFF2ALA7c9OVdvc2vQJeDdjfR35M0sBCxvw== "@types/node@^10.1.0": version "10.17.17" From 44791b4d98361479cdfcc915c3d86dbd1de5af77 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2020 21:15:46 +0000 Subject: [PATCH 23/88] Bump jest from 25.2.3 to 25.2.4 in /api_tests Bumps [jest](https://github.com/facebook/jest) from 25.2.3 to 25.2.4. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/compare/v25.2.3...v25.2.4) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 282 ++++++++++++++++++++--------------------- 2 files changed, 142 insertions(+), 142 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 9f91f2213d..3452880509 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -48,7 +48,7 @@ "ethers": "^4.0.46", "get-port": "^5.1.1", "jasmine": "^3.5.0", - "jest": "^25.2.3", + "jest": "^25.2.4", "js-sha256": "^0.9.0", "log4js": "^6.1.2", "p-timeout": "^3.2.0", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index e87f965562..fcd00e698f 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -189,33 +189,33 @@ jest-util "^25.2.3" slash "^3.0.0" -"@jest/core@^25.2.3": - version "25.2.3" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-25.2.3.tgz#2fd37ce0e6ad845e058dcd8245f2745490df1bc0" - integrity sha512-Ifz3aEkGvZhwijLMmWa7sloZVEMdxpzjFv3CKHv3eRYRShTN8no6DmyvvxaZBjLalOlRalJ7HDgc733J48tSuw== +"@jest/core@^25.2.4": + version "25.2.4" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-25.2.4.tgz#382ef80369d3311f1df79db1ee19e958ae95cdad" + integrity sha512-WcWYShl0Bqfcb32oXtjwbiR78D/djhMdJW+ulp4/bmHgeODcsieqUJfUH+kEv8M7VNV77E6jds5aA+WuGh1nmg== dependencies: "@jest/console" "^25.2.3" - "@jest/reporters" "^25.2.3" - "@jest/test-result" "^25.2.3" - "@jest/transform" "^25.2.3" + "@jest/reporters" "^25.2.4" + "@jest/test-result" "^25.2.4" + "@jest/transform" "^25.2.4" "@jest/types" "^25.2.3" ansi-escapes "^4.2.1" chalk "^3.0.0" exit "^0.1.2" graceful-fs "^4.2.3" jest-changed-files "^25.2.3" - jest-config "^25.2.3" + jest-config "^25.2.4" jest-haste-map "^25.2.3" - jest-message-util "^25.2.3" + jest-message-util "^25.2.4" jest-regex-util "^25.2.1" jest-resolve "^25.2.3" - jest-resolve-dependencies "^25.2.3" - jest-runner "^25.2.3" - jest-runtime "^25.2.3" - jest-snapshot "^25.2.3" + jest-resolve-dependencies "^25.2.4" + jest-runner "^25.2.4" + jest-runtime "^25.2.4" + jest-snapshot "^25.2.4" jest-util "^25.2.3" jest-validate "^25.2.3" - jest-watcher "^25.2.3" + jest-watcher "^25.2.4" micromatch "^4.0.2" p-each-series "^2.1.0" realpath-native "^2.0.0" @@ -223,35 +223,35 @@ slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^25.2.3": - version "25.2.3" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-25.2.3.tgz#32b3f216355b03e9449b93b62584c18934a2cc4a" - integrity sha512-zRypAMQnNo8rD0rCbI9+5xf+Lu+uvunKZNBcIWjb3lTATSomKbgYO+GYewGDYn7pf+30XCNBc6SH1rnBUN1ioA== +"@jest/environment@^25.2.4": + version "25.2.4" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-25.2.4.tgz#74f4d8dd87b427434d0b822cde37bc0e78f3e28b" + integrity sha512-wA4xlhD19/gukkDpJ5HQsTle0pgnzI5qMFEjw267lpTDC8d9N7Ihqr5pI+l0p8Qn1SQhai+glSqxrGdzKy4jxw== dependencies: - "@jest/fake-timers" "^25.2.3" + "@jest/fake-timers" "^25.2.4" "@jest/types" "^25.2.3" jest-mock "^25.2.3" -"@jest/fake-timers@^25.2.3": - version "25.2.3" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.2.3.tgz#808a8a761be3baac719311f8bde1362bd1861e65" - integrity sha512-B6Qxm86fl613MV8egfvh1mRTMu23hMNdOUjzPhKl/4Nm5cceHz6nwLn0nP0sJXI/ue1vu71aLbtkgVBCgc2hYA== +"@jest/fake-timers@^25.2.4": + version "25.2.4" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.2.4.tgz#6821b6edde74fda2a42467ae92cc93095d4c9527" + integrity sha512-oC1TJiwfMcBttVN7Wz+VZnqEAgYTiEMu0QLOXpypR89nab0uCB31zm/QeBZddhSstn20qe3yqOXygp6OwvKT/Q== dependencies: "@jest/types" "^25.2.3" - jest-message-util "^25.2.3" + jest-message-util "^25.2.4" jest-mock "^25.2.3" jest-util "^25.2.3" lolex "^5.0.0" -"@jest/reporters@^25.2.3": - version "25.2.3" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-25.2.3.tgz#824e922ea56686d0243c910559c36adacdd2081c" - integrity sha512-S0Zca5e7tTfGgxGRvBh6hktNdOBzqc6HthPzYHPRFYVW81SyzCqHTaNZydtDIVehb9s6NlyYZpcF/I2vco+lNw== +"@jest/reporters@^25.2.4": + version "25.2.4" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-25.2.4.tgz#aa01c20aab217150d3a6080d5c98ce0bf34b17ed" + integrity sha512-VHbLxM03jCc+bTLOluW/IqHR2G0Cl0iATwIQbuZtIUast8IXO4fD0oy4jpVGpG5b20S6REA8U3BaQoCW/CeVNQ== dependencies: "@bcoe/v8-coverage" "^0.2.3" "@jest/console" "^25.2.3" - "@jest/test-result" "^25.2.3" - "@jest/transform" "^25.2.3" + "@jest/test-result" "^25.2.4" + "@jest/transform" "^25.2.4" "@jest/types" "^25.2.3" chalk "^3.0.0" collect-v8-coverage "^1.0.0" @@ -283,31 +283,31 @@ graceful-fs "^4.2.3" source-map "^0.6.0" -"@jest/test-result@^25.2.3": - version "25.2.3" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.2.3.tgz#db6028427514702c739dda66528dfbcc7fb8cdf4" - integrity sha512-cNYidqERTcT+xqZZ5FPSvji7Bd2YYq9M/VJCEUmgTVRFZRPOPSu65crEzQJ4czcDChEJ9ovzZ65r3UBlajnh3w== +"@jest/test-result@^25.2.4": + version "25.2.4" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.2.4.tgz#8fc9eac58e82eb2a82e4058e68c3814f98f59cf5" + integrity sha512-AI7eUy+q2lVhFnaibDFg68NGkrxVWZdD6KBr9Hm6EvN0oAe7GxpEwEavgPfNHQjU2mi6g+NsFn/6QPgTUwM1qg== dependencies: "@jest/console" "^25.2.3" - "@jest/transform" "^25.2.3" + "@jest/transform" "^25.2.4" "@jest/types" "^25.2.3" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^25.2.3": - version "25.2.3" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-25.2.3.tgz#1400e0e994904844567e6e33c87062cbdf1f3e99" - integrity sha512-trHwV/wCrxWyZyNyNBUQExsaHyBVQxJwH3butpEcR+KBJPfaTUxtpXaxfs38IXXAhH68J4kPZgAaRRfkFTLunA== +"@jest/test-sequencer@^25.2.4": + version "25.2.4" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-25.2.4.tgz#28364aeddec140c696324114f63570f3de536c87" + integrity sha512-TEZm/Rkd6YgskdpTJdYLBtu6Gc11tfWPuSpatq0duH77ekjU8dpqX2zkPdY/ayuHxztV5LTJoV5BLtI9mZfXew== dependencies: - "@jest/test-result" "^25.2.3" + "@jest/test-result" "^25.2.4" jest-haste-map "^25.2.3" - jest-runner "^25.2.3" - jest-runtime "^25.2.3" + jest-runner "^25.2.4" + jest-runtime "^25.2.4" -"@jest/transform@^25.2.3": - version "25.2.3" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-25.2.3.tgz#f090bdd91f54b867631a76959f2b2fc566534ffe" - integrity sha512-w1nfAuYP4OAiEDprFkE/2iwU86jL/hK3j1ylMcYOA3my5VOHqX0oeBcBxS2fUKWse2V4izuO2jqes0yNTDMlzw== +"@jest/transform@^25.2.4": + version "25.2.4" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-25.2.4.tgz#34336f37f13f62f7d1f5b93d5d150ba9eb3e11b9" + integrity sha512-6eRigvb+G6bs4kW5j1/y8wu4nCrmVuIe0epPBbiWaYlwawJ8yi1EIyK3d/btDqmBpN5GpN4YhR6iPPnDmkYdTA== dependencies: "@babel/core" "^7.1.0" "@jest/types" "^25.2.3" @@ -886,12 +886,12 @@ axios@^0.19.0: follow-redirects "1.5.10" is-buffer "^2.0.2" -babel-jest@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.2.3.tgz#8f1c088b1954963e8a5384be2e219dae00d053f4" - integrity sha512-03JjvEwuDrEz/A45K8oggAv+Vqay0xcOdNTJxYFxiuZvB5vlHKo1iZg9Pi5vQTHhNCKpGLb7L/jvUUafyh9j7g== +babel-jest@^25.2.4: + version "25.2.4" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.2.4.tgz#b21b68d3af8f161c3e6e501e91f0dea8e652e344" + integrity sha512-+yDzlyJVWrqih9i2Cvjpt7COaN8vUwCsKGtxJLzg6I0xhxD54K8mvDUCliPKLufyzHh/c5C4MRj4Vk7VMjOjIg== dependencies: - "@jest/transform" "^25.2.3" + "@jest/transform" "^25.2.4" "@jest/types" "^25.2.3" "@types/babel__core" "^7.1.0" babel-plugin-istanbul "^6.0.0" @@ -2007,16 +2007,16 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/expect/-/expect-25.2.3.tgz#ee714f82bf33c43466fcef139ace0a57b3d0aa48" - integrity sha512-kil4jFRFAK2ySyCyXPqYrphc3EiiKKFd9BthrkKAyHcqr1B84xFTuj5kO8zL+eHRRjT2jQsOPExO0+1Q/fuUXg== +expect@^25.2.4: + version "25.2.4" + resolved "https://registry.yarnpkg.com/expect/-/expect-25.2.4.tgz#b66e0777c861034ebc21730bb34e1839d5d46806" + integrity sha512-hfuPhPds4yOsZtIw4kwAg70r0hqGmpqekgA+VX7pf/3wZ6FY+xIOXZhNsPMMMsspYG/YIsbAiwqsdnD4Ht+bCA== dependencies: "@jest/types" "^25.2.3" ansi-styles "^4.0.0" jest-get-type "^25.2.1" jest-matcher-utils "^25.2.3" - jest-message-util "^25.2.3" + jest-message-util "^25.2.4" jest-regex-util "^25.2.1" express@^4.17.1: @@ -2803,41 +2803,41 @@ jest-changed-files@^25.2.3: execa "^3.2.0" throat "^5.0.0" -jest-cli@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-25.2.3.tgz#47e17240ce6d8ce824ca1a01468ea8824ec6b139" - integrity sha512-T7G0TOkFj0wr33ki5xoq3bxkKC+liwJfjV9SmYIKBozwh91W4YjL1o1dgVCUTB1+sKJa/DiAY0p+eXYE6v2RGw== +jest-cli@^25.2.4: + version "25.2.4" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-25.2.4.tgz#021c2383904696597abc060dcb133c82ebd8bfcc" + integrity sha512-zeY2pRDWKj2LZudIncvvguwLMEdcnJqc2jJbwza1beqi80qqLvkPF/BjbFkK2sIV3r+mfTJS+7ITrvK6pCdRjg== dependencies: - "@jest/core" "^25.2.3" - "@jest/test-result" "^25.2.3" + "@jest/core" "^25.2.4" + "@jest/test-result" "^25.2.4" "@jest/types" "^25.2.3" chalk "^3.0.0" exit "^0.1.2" import-local "^3.0.2" is-ci "^2.0.0" - jest-config "^25.2.3" + jest-config "^25.2.4" jest-util "^25.2.3" jest-validate "^25.2.3" prompts "^2.0.1" realpath-native "^2.0.0" yargs "^15.3.1" -jest-config@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-25.2.3.tgz#c304e91e2ba3763c04b38eafc26d30e5c41b48e8" - integrity sha512-UpTNxN8DgmLLCXFizGuvwIw+ZAPB0T3jbKaFEkzJdGqhSsQrVrk1lxhZNamaVIpWirM2ptYmqwUzvoobGCEkiQ== +jest-config@^25.2.4: + version "25.2.4" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-25.2.4.tgz#f4f33238979f225683179c89d1e402893008975d" + integrity sha512-fxy3nIpwJqOUQJRVF/q+pNQb6dv5b9YufOeCbpPZJ/md1zXpiupbhfehpfODhnKOfqbzSiigtSLzlWWmbRxnqQ== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^25.2.3" + "@jest/test-sequencer" "^25.2.4" "@jest/types" "^25.2.3" - babel-jest "^25.2.3" + babel-jest "^25.2.4" chalk "^3.0.0" deepmerge "^4.2.2" glob "^7.1.1" - jest-environment-jsdom "^25.2.3" - jest-environment-node "^25.2.3" + jest-environment-jsdom "^25.2.4" + jest-environment-node "^25.2.4" jest-get-type "^25.2.1" - jest-jasmine2 "^25.2.3" + jest-jasmine2 "^25.2.4" jest-regex-util "^25.2.1" jest-resolve "^25.2.3" jest-util "^25.2.3" @@ -2884,25 +2884,25 @@ jest-each@^25.2.3: jest-util "^25.2.3" pretty-format "^25.2.3" -jest-environment-jsdom@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-25.2.3.tgz#f790f87c24878b219d1745f68343380c2d79ab01" - integrity sha512-TLg7nizxIYJafz6tOBAVSmO5Ekswf6Cf3Soseov+mgonXfdYi1I0OZlHlZMJb2fGyXem2ndYFCLrMkwcWPKAnQ== +jest-environment-jsdom@^25.2.4: + version "25.2.4" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-25.2.4.tgz#f2783541d0538b1bc43641703372cea6a2e83611" + integrity sha512-5dm+tNwrLmhELdjAwiQnVGf/U9iFMWdTL4/wyrMg2HU6RQnCiuxpWbIigLHUhuP1P2Ak0F4k3xhjrikboKyShA== dependencies: - "@jest/environment" "^25.2.3" - "@jest/fake-timers" "^25.2.3" + "@jest/environment" "^25.2.4" + "@jest/fake-timers" "^25.2.4" "@jest/types" "^25.2.3" jest-mock "^25.2.3" jest-util "^25.2.3" jsdom "^15.2.1" -jest-environment-node@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-25.2.3.tgz#e50a7e84bf7c7555216aa41aea1e48f53773318f" - integrity sha512-Tu/wlGXfoLtBR4Ym+isz58z3TJkMYX4VnFTkrsxaTGYAxNLN7ArCwL51Ki0WrMd89v+pbCLDj/hDjrb4a2sOrw== +jest-environment-node@^25.2.4: + version "25.2.4" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-25.2.4.tgz#dc211dfb0d8b66dfc1965a8f846e72e54ff0c430" + integrity sha512-Jkc5Y8goyXPrLRHnrUlqC7P4o5zn2m4zw6qWoRJ59kxV1f2a5wK+TTGhrhCwnhW/Ckpdl/pm+LufdvhJkvJbiw== dependencies: - "@jest/environment" "^25.2.3" - "@jest/fake-timers" "^25.2.3" + "@jest/environment" "^25.2.4" + "@jest/fake-timers" "^25.2.4" "@jest/types" "^25.2.3" jest-mock "^25.2.3" jest-util "^25.2.3" @@ -2937,25 +2937,25 @@ jest-haste-map@^25.2.3: optionalDependencies: fsevents "^2.1.2" -jest-jasmine2@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-25.2.3.tgz#a824c5dbe383c63d243aab5e64cc85ab65f87598" - integrity sha512-x9PEGPFdnkSwJj1UG4QxG9JxFdyP8fuJ/UfKXd/eSpK8w9x7MP3VaQDuPQF0UQhCT0YeOITEPkQyqS+ptt0suA== +jest-jasmine2@^25.2.4: + version "25.2.4" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-25.2.4.tgz#5f77de83e1027f0c7588137055a80da773872374" + integrity sha512-juoKrmNmLwaheNbAg71SuUF9ovwUZCFNTpKVhvCXWk+SSeORcIUMptKdPCoLXV3D16htzhTSKmNxnxSk4SrTjA== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^25.2.3" + "@jest/environment" "^25.2.4" "@jest/source-map" "^25.2.1" - "@jest/test-result" "^25.2.3" + "@jest/test-result" "^25.2.4" "@jest/types" "^25.2.3" chalk "^3.0.0" co "^4.6.0" - expect "^25.2.3" + expect "^25.2.4" is-generator-fn "^2.0.0" jest-each "^25.2.3" jest-matcher-utils "^25.2.3" - jest-message-util "^25.2.3" - jest-runtime "^25.2.3" - jest-snapshot "^25.2.3" + jest-message-util "^25.2.4" + jest-runtime "^25.2.4" + jest-snapshot "^25.2.4" jest-util "^25.2.3" pretty-format "^25.2.3" throat "^5.0.0" @@ -2978,13 +2978,13 @@ jest-matcher-utils@^25.2.3: jest-get-type "^25.2.1" pretty-format "^25.2.3" -jest-message-util@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.2.3.tgz#a911c4e3af06df851cc6065d9a3119fd2a3aa240" - integrity sha512-DcyDmdO5LVIeS0ngRvd7rk701XL60dAakUeQJ1tQRby27fyLYXD+V0nqVaC194W7fIlohjVQOZPHmKXIjn+Byw== +jest-message-util@^25.2.4: + version "25.2.4" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.2.4.tgz#b1441b9c82f5c11fc661303cbf200a2f136a7762" + integrity sha512-9wWMH3Bf+GVTv0GcQLmH/FRr0x0toptKw9TA8U5YFLVXx7Tq9pvcNzTyJrcTJ+wLqNbMPPJlJNft4MnlcrtF5Q== dependencies: "@babel/code-frame" "^7.0.0" - "@jest/test-result" "^25.2.3" + "@jest/test-result" "^25.2.4" "@jest/types" "^25.2.3" "@types/stack-utils" "^1.0.1" chalk "^3.0.0" @@ -3009,14 +3009,14 @@ jest-regex-util@^25.2.1: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.2.1.tgz#db64b0d15cd3642c93b7b9627801d7c518600584" integrity sha512-wroFVJw62LdqTdkL508ZLV82FrJJWVJMIuYG7q4Uunl1WAPTf4ftPKrqqfec4SvOIlvRZUdEX2TFpWR356YG/w== -jest-resolve-dependencies@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-25.2.3.tgz#cd4d9d068d5238dfbdfa45690f6e902b6413c2da" - integrity sha512-mcWlvjXLlNzgdE9EQxHuaeWICNxozanim87EfyvPwTY0ryWusFZbgF6F8u3E0syJ4FFSooEm0lQ6fgYcnPGAFw== +jest-resolve-dependencies@^25.2.4: + version "25.2.4" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-25.2.4.tgz#2d904400387d74a366dff54badb40a2b3210e733" + integrity sha512-qhUnK4PfNHzNdca7Ub1mbAqE0j5WNyMTwxBZZJjQlUrdqsiYho/QGK65FuBkZuSoYtKIIqriR9TpGrPEc3P5Gg== dependencies: "@jest/types" "^25.2.3" jest-regex-util "^25.2.1" - jest-snapshot "^25.2.3" + jest-snapshot "^25.2.4" jest-resolve@^25.2.3: version "25.2.3" @@ -3030,41 +3030,41 @@ jest-resolve@^25.2.3: realpath-native "^2.0.0" resolve "^1.15.1" -jest-runner@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-25.2.3.tgz#88fb448a46cf4ee9194a3e3cf0adbc122e195adb" - integrity sha512-E+u2Zm2TmtTOFEbKs5jllLiV2fwiX77cYc08RdyYZNe/s06wQT3P47aV6a8Rv61L7E2Is7OmozLd0KI/DITRpg== +jest-runner@^25.2.4: + version "25.2.4" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-25.2.4.tgz#d0daf7c56b4a83b6b675863d5cdcd502c960f9a1" + integrity sha512-5xaIfqqxck9Wg2CV4b9KmJtf/sWO7zWQx7O+34GCLGPzoPcVmB3mZtdrQI1/jS3Reqjru9ycLjgLHSf6XoxRqA== dependencies: "@jest/console" "^25.2.3" - "@jest/environment" "^25.2.3" - "@jest/test-result" "^25.2.3" + "@jest/environment" "^25.2.4" + "@jest/test-result" "^25.2.4" "@jest/types" "^25.2.3" chalk "^3.0.0" exit "^0.1.2" graceful-fs "^4.2.3" - jest-config "^25.2.3" + jest-config "^25.2.4" jest-docblock "^25.2.3" jest-haste-map "^25.2.3" - jest-jasmine2 "^25.2.3" + jest-jasmine2 "^25.2.4" jest-leak-detector "^25.2.3" - jest-message-util "^25.2.3" + jest-message-util "^25.2.4" jest-resolve "^25.2.3" - jest-runtime "^25.2.3" + jest-runtime "^25.2.4" jest-util "^25.2.3" jest-worker "^25.2.1" source-map-support "^0.5.6" throat "^5.0.0" -jest-runtime@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-25.2.3.tgz#1f0e9ba878a66538c3e9d58be97a6a12c877ed13" - integrity sha512-PZRFeUVF08N24v2G73SDF0b0VpLG7cRNOJ3ggj5TnArBVHkkrWzM3z7txB9OupWu7OO8bH/jFogk6sSjnHLFXQ== +jest-runtime@^25.2.4: + version "25.2.4" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-25.2.4.tgz#c66a421e115944426b377a7fd331f6c0902cfa56" + integrity sha512-6ehOUizgIghN+aV5YSrDzTZ+zJ9omgEjJbTHj3Jqes5D52XHfhzT7cSfdREwkNjRytrR7mNwZ7pRauoyNLyJ8Q== dependencies: "@jest/console" "^25.2.3" - "@jest/environment" "^25.2.3" + "@jest/environment" "^25.2.4" "@jest/source-map" "^25.2.1" - "@jest/test-result" "^25.2.3" - "@jest/transform" "^25.2.3" + "@jest/test-result" "^25.2.4" + "@jest/transform" "^25.2.4" "@jest/types" "^25.2.3" "@types/yargs" "^15.0.0" chalk "^3.0.0" @@ -3072,13 +3072,13 @@ jest-runtime@^25.2.3: exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.2.3" - jest-config "^25.2.3" + jest-config "^25.2.4" jest-haste-map "^25.2.3" - jest-message-util "^25.2.3" + jest-message-util "^25.2.4" jest-mock "^25.2.3" jest-regex-util "^25.2.1" jest-resolve "^25.2.3" - jest-snapshot "^25.2.3" + jest-snapshot "^25.2.4" jest-util "^25.2.3" jest-validate "^25.2.3" realpath-native "^2.0.0" @@ -3091,20 +3091,20 @@ jest-serializer@^25.2.1: resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-25.2.1.tgz#51727a5fc04256f461abe0fa024a022ba165877a" integrity sha512-fibDi7M5ffx6c/P66IkvR4FKkjG5ldePAK1WlbNoaU4GZmIAkS9Le/frAwRUFEX0KdnisSPWf+b1RC5jU7EYJQ== -jest-snapshot@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-25.2.3.tgz#2d432fcf9e7f1f7eb3e5012ffcce8035794b76ae" - integrity sha512-HlFVbE6vOZ541mtkwjuAe0rfx9EWhB+QXXneLNOP/s3LlHxGQtX7WFXY5OiH4CkAnCc6BpzLNYS9nfINNRb4Zg== +jest-snapshot@^25.2.4: + version "25.2.4" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-25.2.4.tgz#08d4517579c864df4280bcc948ceea34327a4ded" + integrity sha512-nIwpW7FZCq5p0AE3Oyqyb6jL0ENJixXzJ5/CD/XRuOqp3gS5OM3O/k+NnTrniCXxPFV4ry6s9HNfiPQBi0wcoA== dependencies: "@babel/types" "^7.0.0" "@jest/types" "^25.2.3" "@types/prettier" "^1.19.0" chalk "^3.0.0" - expect "^25.2.3" + expect "^25.2.4" jest-diff "^25.2.3" jest-get-type "^25.2.1" jest-matcher-utils "^25.2.3" - jest-message-util "^25.2.3" + jest-message-util "^25.2.4" jest-resolve "^25.2.3" make-dir "^3.0.0" natural-compare "^1.4.0" @@ -3133,12 +3133,12 @@ jest-validate@^25.2.3: leven "^3.1.0" pretty-format "^25.2.3" -jest-watcher@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-25.2.3.tgz#a494fe3ddb62da62b0e697abfea457de8f388f1f" - integrity sha512-F6ERbdvJk8nbaRon9lLQVl4kp+vToCCHmy+uWW5QQ8/8/g2jkrZKJQnlQINrYQp0ewg31Bztkhs4nxsZMx6wDg== +jest-watcher@^25.2.4: + version "25.2.4" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-25.2.4.tgz#dda85b914d470fa4145164a8f70bda4f208bafb6" + integrity sha512-p7g7s3zqcy69slVzQYcphyzkB2FBmJwMbv6k6KjI5mqd6KnUnQPfQVKuVj2l+34EeuxnbXqnrjtUFmxhcL87rg== dependencies: - "@jest/test-result" "^25.2.3" + "@jest/test-result" "^25.2.4" "@jest/types" "^25.2.3" ansi-escapes "^4.2.1" chalk "^3.0.0" @@ -3153,14 +3153,14 @@ jest-worker@^25.2.1: merge-stream "^2.0.0" supports-color "^7.0.0" -jest@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest/-/jest-25.2.3.tgz#0cc9b35192f236fe1d5e76ed8eb3a54e7e0ee2e0" - integrity sha512-UbUmyGeZt0/sCIj/zsWOY0qFfQsx2qEFIZp0iEj8yVH6qASfR22fJOf12gFuSPsdSufam+llZBB0MdXWCg6EEQ== +jest@^25.2.4: + version "25.2.4" + resolved "https://registry.yarnpkg.com/jest/-/jest-25.2.4.tgz#d10941948a2b57eb7accc2e7ae78af4a0e11b40a" + integrity sha512-Lu4LXxf4+durzN/IFilcAoQSisOwgHIXgl9vffopePpSSwFqfj1Pj4y+k3nL8oTbnvjxgDIsEcepy6he4bWqnQ== dependencies: - "@jest/core" "^25.2.3" + "@jest/core" "^25.2.4" import-local "^3.0.2" - jest-cli "^25.2.3" + jest-cli "^25.2.4" js-sha256@^0.9.0: version "0.9.0" From 04c986fa7e09c0b5bc8ff41ebae84a201614c63a Mon Sep 17 00:00:00 2001 From: rishflab Date: Tue, 31 Mar 2020 10:09:31 +1100 Subject: [PATCH 24/88] Fix failing e2e tests The order of file system locking was causing the e2e tests to fail. --- cnd/src/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cnd/src/main.rs b/cnd/src/main.rs index 818a7be468..d27482284e 100644 --- a/cnd/src/main.rs +++ b/cnd/src/main.rs @@ -53,10 +53,12 @@ fn main() -> anyhow::Result<()> { crate::trace::init_tracing(settings.logging.level)?; - let _locked_datadir = &settings.data.dir.try_lock_exclusive()?; + let database = Sqlite::new_in_dir(&settings.data.dir)?; let seed = RootSeed::from_dir_or_generate(&settings.data.dir, OsRng)?; + let _locked_datadir = &settings.data.dir.try_lock_exclusive()?; + let mut runtime = runtime::Builder::new() .enable_all() .threaded_scheduler() @@ -115,8 +117,6 @@ fn main() -> anyhow::Result<()> { let swap_error_states = Arc::new(SwapErrorStates::default()); - let database = Sqlite::new_in_dir(&settings.data.dir)?; - let swarm = Swarm::new( &settings, seed, From 93ef2b5c2b708e2d66f5f39d6f22deca95b7cef2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2020 14:13:12 +0000 Subject: [PATCH 25/88] Bump proc-macro2 from 1.0.9 to 1.0.10 Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.9 to 1.0.10. - [Release notes](https://github.com/alexcrichton/proc-macro2/releases) - [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.9...1.0.10) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 64 +++++++++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d43da605c3..b2a701dcd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -64,7 +64,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61874b33258f18ca7923047c12887078ccfe95c2811b03c1a09e309c19b7e50b" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -174,7 +174,7 @@ version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77e07b5570f31843d05dc82384ea9da01c04fe0839e24f34134c649c09b904ee" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -788,7 +788,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1eae4d76b7cefedd1b4f8cc24378b2fbd1ac1b66e3bbebe8e2192d3be81cb355" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -811,7 +811,7 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -849,7 +849,7 @@ name = "digest-macro-derive" version = "0.1.0" dependencies = [ "hex 0.4.2", - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -1103,7 +1103,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -1208,7 +1208,7 @@ checksum = "784f84eebc366e15251c4a8c3acee82a6a6f427949776ecb88377362a9621738" dependencies = [ "proc-macro-error", "proc-macro-hack", - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -1530,7 +1530,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e20558cac9252437815e7231074926454f1d59d9797fff4840d135a30c930a49" dependencies = [ "itertools", - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -2175,7 +2175,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719ef0bc7f531428764c9b70661c14abd50a7f3d21f355752d9985aa21251c9e" dependencies = [ "migrations_internals", - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -2652,7 +2652,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "406c23fb4c45cc6f68a9bbabb8ec7bd6f8cfcbd17e9e8f72c2460282f8325729" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -2705,7 +2705,7 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -2753,7 +2753,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "052b3c9af39c7e5e94245f820530487d19eb285faedcb40e0c3275132293f242" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "rustversion", "syn 1.0.17", @@ -2765,7 +2765,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d175bef481c7902e63e3165627123fff3502f06ac043d3ef42d08c1246da9253" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "rustversion", "syn 1.0.17", @@ -2778,7 +2778,7 @@ version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -2800,9 +2800,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" +checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" dependencies = [ "unicode-xid 0.2.0", ] @@ -2843,7 +2843,7 @@ checksum = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72" dependencies = [ "anyhow", "itertools", - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -2902,7 +2902,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", ] [[package]] @@ -2999,7 +2999,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9fd3125016eb3257fe8038dcafaa5fbecc081bcd46defe9ccb98ceae0175219" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -3158,7 +3158,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -3315,7 +3315,7 @@ version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -3529,7 +3529,7 @@ checksum = "3f88b8e18c69496aad6f9ddf4630dd7d585bcaf765786cb415b9aec2fe5a0430" dependencies = [ "heck", "proc-macro-error", - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -3547,7 +3547,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c" dependencies = [ "heck", - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -3592,7 +3592,7 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "unicode-xid 0.2.0", ] @@ -3603,7 +3603,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -3614,7 +3614,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", "unicode-xid 0.2.0", @@ -3674,7 +3674,7 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "227362df41d566be41a28f64401e07a043157c21c14b9785a0d8e256f940a8fd" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -3744,7 +3744,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4b1e7ed7d5d4c2af3d999904b0eebe76544897cdbfb2b9684bed2174ab20f7c" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -4128,7 +4128,7 @@ dependencies = [ "bumpalo", "lazy_static", "log 0.4.8", - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", "wasm-bindgen-shared", @@ -4162,7 +4162,7 @@ version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", "wasm-bindgen-backend", @@ -4184,7 +4184,7 @@ dependencies = [ "anyhow", "heck", "log 0.4.8", - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", "wasm-bindgen-backend", @@ -4332,7 +4332,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", "synstructure", From 3413903e7d4e29e78c47e5029d7997074126b05b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2020 15:42:05 +0000 Subject: [PATCH 26/88] Bump anyhow from 1.0.27 to 1.0.28 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.27 to 1.0.28. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.27...1.0.28) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b2a701dcd4..76e40eff26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,9 +80,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "013a6e0a2cbe3d20f9c60b65458f7a7f7a5e636c5d0f45a5a6aee5d4b1f01785" +checksum = "d9a60d744a80c30fcb657dfe2c1b22bcb3e814c1a1e3674f32bf5820b570fbff" [[package]] name = "array-init" From 79a06b1bcfbb51236189a0df9d6a0a7de5b1af21 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2020 16:28:31 +0000 Subject: [PATCH 27/88] Bump @types/node from 13.9.5 to 13.9.8 in /api_tests Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 13.9.5 to 13.9.8. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot-preview[bot] --- api_tests/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 53aeae1614..dc872f8e19 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -575,9 +575,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*", "@types/node@^13.9": - version "13.9.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.5.tgz#59738bf30b31aea1faa2df7f4a5f55613750cf00" - integrity sha512-hkzMMD3xu6BrJpGVLeQ3htQQNAcOrJjX7WFmtK8zWQpz2UJf13LCFF2ALA7c9OVdvc2vQJeDdjfR35M0sBCxvw== + version "13.9.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.8.tgz#09976420fc80a7a00bf40680c63815ed8c7616f4" + integrity sha512-1WgO8hsyHynlx7nhP1kr0OFzsgKz5XDQL+Lfc3b1Q3qIln/n8cKD4m09NJ0+P1Rq7Zgnc7N0+SsMnoD1rEb0kA== "@types/node@^10.1.0": version "10.17.17" From d951fd4f8d5df0ff2c2f852a6765ca9938505d72 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 1 Apr 2020 14:12:35 +0000 Subject: [PATCH 28/88] Bump bitcoincore-rpc from 0.9.1 to 0.10.0 Bumps [bitcoincore-rpc](https://github.com/rust-bitcoin/rust-bitcoincore-rpc) from 0.9.1 to 0.10.0. - [Release notes](https://github.com/rust-bitcoin/rust-bitcoincore-rpc/releases) - [Changelog](https://github.com/rust-bitcoin/rust-bitcoincore-rpc/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-bitcoin/rust-bitcoincore-rpc/compare/v0.9.1...v0.10.0) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 10 ++++------ cnd/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 76e40eff26..883911a821 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -265,9 +265,9 @@ dependencies = [ [[package]] name = "bitcoincore-rpc" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f41f59566728c0940ca4032d3b3c51089ddeed32f3b2071d80c285394861dc7" +checksum = "8fd9841d25f6ea05395d39821f8320fcc920854b16ba2acdea7521b9e96308cc" dependencies = [ "bitcoincore-rpc-json", "jsonrpc", @@ -278,13 +278,12 @@ dependencies = [ [[package]] name = "bitcoincore-rpc-json" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42c8db224907013dc662cc5fecb35f853051dce42dd14d00dd82b42f4d82ff46" +checksum = "1bafd8df8adc84be1df6203999a171f8b661775521846ec54c4ccaa86a720dfe" dependencies = [ "bitcoin", "hex 0.3.2", - "num-bigint 0.2.6", "serde", "serde_json", ] @@ -2402,7 +2401,6 @@ dependencies = [ "autocfg 1.0.0", "num-integer", "num-traits", - "serde", ] [[package]] diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index c45bc7cb3b..f3fd9f4de8 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -65,7 +65,7 @@ warp = { version = "0.2", default-features = false } [dev-dependencies] base64 = "0.12" -bitcoincore-rpc = "0.9.1" +bitcoincore-rpc = "0.10.0" quickcheck = "0.9.2" regex = "1.3" serde_urlencoded = "0.6" From 8ad30489e4e037845be0b9e6928b5242211335e6 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 2 Apr 2020 14:13:24 +0000 Subject: [PATCH 29/88] Bump async-trait from 0.1.25 to 0.1.29 Bumps [async-trait](https://github.com/dtolnay/async-trait) from 0.1.25 to 0.1.29. - [Release notes](https://github.com/dtolnay/async-trait/releases) - [Commits](https://github.com/dtolnay/async-trait/compare/0.1.25...0.1.29) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 883911a821..a5c21c59d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -170,9 +170,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.25" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e07b5570f31843d05dc82384ea9da01c04fe0839e24f34134c649c09b904ee" +checksum = "bab5c215748dc1ad11a145359b1067107ae0f8ca5e99844fa64067ed5bf198e3" dependencies = [ "proc-macro2 1.0.10", "quote 1.0.3", From 67b0b971e542f99c60713ee0f8c6e7fd8578d2d2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 2 Apr 2020 14:13:44 +0000 Subject: [PATCH 30/88] Bump tiny-keccak from 2.0.1 to 2.0.2 Bumps [tiny-keccak](https://github.com/debris/tiny-keccak) from 2.0.1 to 2.0.2. - [Release notes](https://github.com/debris/tiny-keccak/releases) - [Commits](https://github.com/debris/tiny-keccak/commits) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 883911a821..5d95958675 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3699,9 +3699,9 @@ dependencies = [ [[package]] name = "tiny-keccak" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2953ca5148619bc99695c1274cb54c5275bbb913c6adad87e72eaf8db9787f69" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" dependencies = [ "crunchy", ] From 5edae3594fac498a4380d44ca88b1ea9fd92f30f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 2 Apr 2020 14:14:32 +0000 Subject: [PATCH 31/88] Bump paste from 0.1.9 to 0.1.10 Bumps [paste](https://github.com/dtolnay/paste) from 0.1.9 to 0.1.10. - [Release notes](https://github.com/dtolnay/paste/releases) - [Commits](https://github.com/dtolnay/paste/compare/0.1.9...0.1.10) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 883911a821..7a24690d26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2635,9 +2635,9 @@ dependencies = [ [[package]] name = "paste" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092d791bf7847f70bbd49085489fba25fc2c193571752bff9e36e74e72403932" +checksum = "ab4fb1930692d1b6a9cfabdde3d06ea0a7d186518e2f4d67660d8970e2fa647a" dependencies = [ "paste-impl", "proc-macro-hack", @@ -2645,9 +2645,9 @@ dependencies = [ [[package]] name = "paste-impl" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406c23fb4c45cc6f68a9bbabb8ec7bd6f8cfcbd17e9e8f72c2460282f8325729" +checksum = "a62486e111e571b1e93b710b61e8f493c0013be39629b714cb166bdb06aa5a8a" dependencies = [ "proc-macro-hack", "proc-macro2 1.0.10", From e783844a88ed65ce25af912193d85cf5a05f064b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 2 Apr 2020 14:14:54 +0000 Subject: [PATCH 32/88] Bump tokio from 0.2.13 to 0.2.14 Bumps [tokio](https://github.com/tokio-rs/tokio) from 0.2.13 to 0.2.14. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-0.2.13...tokio-0.2.14) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 883911a821..94cbc90d35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3708,9 +3708,9 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa5e81d6bc4e67fe889d5783bd2a128ab2e0cfa487e0be16b6a8d177b101616" +checksum = "2751672f9da075d045c67fdb0068be9850ab7b231fa77bb51d6fd35da9c0bb0d" dependencies = [ "bytes 0.5.4", "fnv", From dd7fa58d4fa2d309525536d310b3b3449b58d3ac Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 2 Apr 2020 15:54:10 +0000 Subject: [PATCH 33/88] Bump jest from 25.2.4 to 25.2.6 in /api_tests Bumps [jest](https://github.com/facebook/jest) from 25.2.4 to 25.2.6. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/compare/v25.2.4...v25.2.6) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 680 ++++++++++++++++++++--------------------- 2 files changed, 340 insertions(+), 342 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 3452880509..5bef198375 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -48,7 +48,7 @@ "ethers": "^4.0.46", "get-port": "^5.1.1", "jasmine": "^3.5.0", - "jest": "^25.2.4", + "jest": "^25.2.6", "js-sha256": "^0.9.0", "log4js": "^6.1.2", "p-timeout": "^3.2.0", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 53aeae1614..9ba66a23a3 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -179,43 +179,43 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== -"@jest/console@^25.2.3": - version "25.2.3" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-25.2.3.tgz#38ac19b916ff61457173799239472659e1a67c39" - integrity sha512-k+37B1aSvOt9tKHWbZZSOy1jdgzesB0bj96igCVUG1nAH1W5EoUfgc5EXbBVU08KSLvkVdWopLXaO3xfVGlxtQ== +"@jest/console@^25.2.6": + version "25.2.6" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-25.2.6.tgz#f594847ec8aef3cf27f448abe97e76e491212e97" + integrity sha512-bGp+0PicZVCEhb+ifnW9wpKWONNdkhtJsRE7ap729hiAfTvCN6VhGx0s/l/V/skA2pnyqq+N/7xl9ZWfykDpsg== dependencies: - "@jest/source-map" "^25.2.1" + "@jest/source-map" "^25.2.6" chalk "^3.0.0" - jest-util "^25.2.3" + jest-util "^25.2.6" slash "^3.0.0" -"@jest/core@^25.2.4": - version "25.2.4" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-25.2.4.tgz#382ef80369d3311f1df79db1ee19e958ae95cdad" - integrity sha512-WcWYShl0Bqfcb32oXtjwbiR78D/djhMdJW+ulp4/bmHgeODcsieqUJfUH+kEv8M7VNV77E6jds5aA+WuGh1nmg== +"@jest/core@^25.2.6": + version "25.2.6" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-25.2.6.tgz#4bcb2919268d92c3813e1ff7c97443cde7a2873a" + integrity sha512-uMwUtpS4CWc7SadHcHEQ3VdrZ8A5u+UVbHIVUqhXcxlQ/bBC5+/T9IJGSu0o8e+/EXmFrTtl4zGr1nRPFq0Wlg== dependencies: - "@jest/console" "^25.2.3" - "@jest/reporters" "^25.2.4" - "@jest/test-result" "^25.2.4" - "@jest/transform" "^25.2.4" - "@jest/types" "^25.2.3" + "@jest/console" "^25.2.6" + "@jest/reporters" "^25.2.6" + "@jest/test-result" "^25.2.6" + "@jest/transform" "^25.2.6" + "@jest/types" "^25.2.6" ansi-escapes "^4.2.1" chalk "^3.0.0" exit "^0.1.2" graceful-fs "^4.2.3" - jest-changed-files "^25.2.3" - jest-config "^25.2.4" - jest-haste-map "^25.2.3" - jest-message-util "^25.2.4" - jest-regex-util "^25.2.1" - jest-resolve "^25.2.3" - jest-resolve-dependencies "^25.2.4" - jest-runner "^25.2.4" - jest-runtime "^25.2.4" - jest-snapshot "^25.2.4" - jest-util "^25.2.3" - jest-validate "^25.2.3" - jest-watcher "^25.2.4" + jest-changed-files "^25.2.6" + jest-config "^25.2.6" + jest-haste-map "^25.2.6" + jest-message-util "^25.2.6" + jest-regex-util "^25.2.6" + jest-resolve "^25.2.6" + jest-resolve-dependencies "^25.2.6" + jest-runner "^25.2.6" + jest-runtime "^25.2.6" + jest-snapshot "^25.2.6" + jest-util "^25.2.6" + jest-validate "^25.2.6" + jest-watcher "^25.2.6" micromatch "^4.0.2" p-each-series "^2.1.0" realpath-native "^2.0.0" @@ -223,36 +223,36 @@ slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^25.2.4": - version "25.2.4" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-25.2.4.tgz#74f4d8dd87b427434d0b822cde37bc0e78f3e28b" - integrity sha512-wA4xlhD19/gukkDpJ5HQsTle0pgnzI5qMFEjw267lpTDC8d9N7Ihqr5pI+l0p8Qn1SQhai+glSqxrGdzKy4jxw== +"@jest/environment@^25.2.6": + version "25.2.6" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-25.2.6.tgz#8f7931e79abd81893ce88b7306f0cc4744835000" + integrity sha512-17WIw+wCb9drRNFw1hi8CHah38dXVdOk7ga9exThhGtXlZ9mK8xH4DjSB9uGDGXIWYSHmrxoyS6KJ7ywGr7bzg== dependencies: - "@jest/fake-timers" "^25.2.4" - "@jest/types" "^25.2.3" - jest-mock "^25.2.3" + "@jest/fake-timers" "^25.2.6" + "@jest/types" "^25.2.6" + jest-mock "^25.2.6" -"@jest/fake-timers@^25.2.4": - version "25.2.4" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.2.4.tgz#6821b6edde74fda2a42467ae92cc93095d4c9527" - integrity sha512-oC1TJiwfMcBttVN7Wz+VZnqEAgYTiEMu0QLOXpypR89nab0uCB31zm/QeBZddhSstn20qe3yqOXygp6OwvKT/Q== +"@jest/fake-timers@^25.2.6": + version "25.2.6" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.2.6.tgz#239dbde3f56badf7d05bcf888f5d669296077cad" + integrity sha512-A6qtDIA2zg/hVgUJJYzQSHFBIp25vHdSxW/s4XmTJAYxER6eL0NQdQhe4+232uUSviKitubHGXXirt5M7blPiA== dependencies: - "@jest/types" "^25.2.3" - jest-message-util "^25.2.4" - jest-mock "^25.2.3" - jest-util "^25.2.3" + "@jest/types" "^25.2.6" + jest-message-util "^25.2.6" + jest-mock "^25.2.6" + jest-util "^25.2.6" lolex "^5.0.0" -"@jest/reporters@^25.2.4": - version "25.2.4" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-25.2.4.tgz#aa01c20aab217150d3a6080d5c98ce0bf34b17ed" - integrity sha512-VHbLxM03jCc+bTLOluW/IqHR2G0Cl0iATwIQbuZtIUast8IXO4fD0oy4jpVGpG5b20S6REA8U3BaQoCW/CeVNQ== +"@jest/reporters@^25.2.6": + version "25.2.6" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-25.2.6.tgz#6d87e40fb15adb69e22bb83aa02a4d88b2253b5f" + integrity sha512-DRMyjaxcd6ZKctiXNcuVObnPwB1eUs7xrUVu0J2V0p5/aZJei5UM9GL3s/bmN4hRV8Mt3zXh+/9X2o0Q4ClZIA== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^25.2.3" - "@jest/test-result" "^25.2.4" - "@jest/transform" "^25.2.4" - "@jest/types" "^25.2.3" + "@jest/console" "^25.2.6" + "@jest/test-result" "^25.2.6" + "@jest/transform" "^25.2.6" + "@jest/types" "^25.2.6" chalk "^3.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" @@ -262,10 +262,10 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.0.0" - jest-haste-map "^25.2.3" - jest-resolve "^25.2.3" - jest-util "^25.2.3" - jest-worker "^25.2.1" + jest-haste-map "^25.2.6" + jest-resolve "^25.2.6" + jest-util "^25.2.6" + jest-worker "^25.2.6" slash "^3.0.0" source-map "^0.6.0" string-length "^3.1.0" @@ -274,51 +274,50 @@ optionalDependencies: node-notifier "^6.0.0" -"@jest/source-map@^25.2.1": - version "25.2.1" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-25.2.1.tgz#b62ecf8ae76170b08eff8859b56eb7576df34ab8" - integrity sha512-PgScGJm1U27+9Te/cxP4oUFqJ2PX6NhBL2a6unQ7yafCgs8k02c0LSyjSIx/ao0AwcAdCczfAPDf5lJ7zoB/7A== +"@jest/source-map@^25.2.6": + version "25.2.6" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-25.2.6.tgz#0ef2209514c6d445ebccea1438c55647f22abb4c" + integrity sha512-VuIRZF8M2zxYFGTEhkNSvQkUKafQro4y+mwUxy5ewRqs5N/ynSFUODYp3fy1zCnbCMy1pz3k+u57uCqx8QRSQQ== dependencies: callsites "^3.0.0" graceful-fs "^4.2.3" source-map "^0.6.0" -"@jest/test-result@^25.2.4": - version "25.2.4" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.2.4.tgz#8fc9eac58e82eb2a82e4058e68c3814f98f59cf5" - integrity sha512-AI7eUy+q2lVhFnaibDFg68NGkrxVWZdD6KBr9Hm6EvN0oAe7GxpEwEavgPfNHQjU2mi6g+NsFn/6QPgTUwM1qg== +"@jest/test-result@^25.2.6": + version "25.2.6" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.2.6.tgz#f6082954955313eb96f6cabf9fb14f8017826916" + integrity sha512-gmGgcF4qz/pkBzyfJuVHo2DA24kIgVQ5Pf/VpW4QbyMLSegi8z+9foSZABfIt5se6k0fFj/3p/vrQXdaOgit0w== dependencies: - "@jest/console" "^25.2.3" - "@jest/transform" "^25.2.4" - "@jest/types" "^25.2.3" + "@jest/console" "^25.2.6" + "@jest/types" "^25.2.6" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^25.2.4": - version "25.2.4" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-25.2.4.tgz#28364aeddec140c696324114f63570f3de536c87" - integrity sha512-TEZm/Rkd6YgskdpTJdYLBtu6Gc11tfWPuSpatq0duH77ekjU8dpqX2zkPdY/ayuHxztV5LTJoV5BLtI9mZfXew== +"@jest/test-sequencer@^25.2.6": + version "25.2.6" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-25.2.6.tgz#62026007610b0323e646ad70db59c69c7ed4785c" + integrity sha512-6sHqVeXbEapfxoGb77NKCywNn9jc4WlIPtFqhwCKGhigGnpl42AuyLxclRWxbFx+V63ozzfjnemYxqHlkcoikQ== dependencies: - "@jest/test-result" "^25.2.4" - jest-haste-map "^25.2.3" - jest-runner "^25.2.4" - jest-runtime "^25.2.4" + "@jest/test-result" "^25.2.6" + jest-haste-map "^25.2.6" + jest-runner "^25.2.6" + jest-runtime "^25.2.6" -"@jest/transform@^25.2.4": - version "25.2.4" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-25.2.4.tgz#34336f37f13f62f7d1f5b93d5d150ba9eb3e11b9" - integrity sha512-6eRigvb+G6bs4kW5j1/y8wu4nCrmVuIe0epPBbiWaYlwawJ8yi1EIyK3d/btDqmBpN5GpN4YhR6iPPnDmkYdTA== +"@jest/transform@^25.2.6": + version "25.2.6" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-25.2.6.tgz#007fd946dedf12d2a9eb5d4154faf1991d5f61ff" + integrity sha512-rZnjCjZf9avPOf9q/w9RUZ9Uc29JmB53uIXNJmNz04QbDMD5cR/VjfikiMKajBsXe2vnFl5sJ4RTt+9HPicauQ== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^25.2.3" + "@jest/types" "^25.2.6" babel-plugin-istanbul "^6.0.0" chalk "^3.0.0" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" graceful-fs "^4.2.3" - jest-haste-map "^25.2.3" - jest-regex-util "^25.2.1" - jest-util "^25.2.3" + jest-haste-map "^25.2.6" + jest-regex-util "^25.2.6" + jest-util "^25.2.6" micromatch "^4.0.2" pirates "^4.0.1" realpath-native "^2.0.0" @@ -336,10 +335,10 @@ "@types/yargs" "^15.0.0" chalk "^3.0.0" -"@jest/types@^25.2.3": - version "25.2.3" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.2.3.tgz#035c4fb94e2da472f359ff9a211915d59987f6b6" - integrity sha512-6oLQwO9mKif3Uph3RX5J1i3S7X7xtDHWBaaaoeKw8hOzV6YUd0qDcYcHZ6QXMHDIzSr7zzrEa51o2Ovlj6AtKQ== +"@jest/types@^25.2.6": + version "25.2.6" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.2.6.tgz#c12f44af9bed444438091e4b59e7ed05f8659cb6" + integrity sha512-myJTTV37bxK7+3NgKc4Y/DlQ5q92/NOwZsZ+Uch7OXdElxOg61QYc72fPYNAjlvbnJ2YvbXLamIsa9tj48BmyQ== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^1.1.1" @@ -886,16 +885,16 @@ axios@^0.19.0: follow-redirects "1.5.10" is-buffer "^2.0.2" -babel-jest@^25.2.4: - version "25.2.4" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.2.4.tgz#b21b68d3af8f161c3e6e501e91f0dea8e652e344" - integrity sha512-+yDzlyJVWrqih9i2Cvjpt7COaN8vUwCsKGtxJLzg6I0xhxD54K8mvDUCliPKLufyzHh/c5C4MRj4Vk7VMjOjIg== +babel-jest@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.2.6.tgz#fe67ff4d0db3626ca8082da8881dd5e84e07ae75" + integrity sha512-MDJOAlwtIeIQiGshyX0d2PxTbV73xZMpNji40ivVTPQOm59OdRR9nYCkffqI7ugtsK4JR98HgNKbDbuVf4k5QQ== dependencies: - "@jest/transform" "^25.2.4" - "@jest/types" "^25.2.3" + "@jest/transform" "^25.2.6" + "@jest/types" "^25.2.6" "@types/babel__core" "^7.1.0" babel-plugin-istanbul "^6.0.0" - babel-preset-jest "^25.2.1" + babel-preset-jest "^25.2.6" chalk "^3.0.0" slash "^3.0.0" @@ -910,21 +909,21 @@ babel-plugin-istanbul@^6.0.0: istanbul-lib-instrument "^4.0.0" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.2.1.tgz#d0003a1f3d5caa281e1107fe03bbf16b799f9955" - integrity sha512-HysbCQfJhxLlyxDbKcB2ucGYV0LjqK4h6dBoI3RtFuOxTiTWK6XGZMsHb0tGh8iJdV4hC6Z2GCHzVvDeh9i0lQ== +babel-plugin-jest-hoist@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.2.6.tgz#2af07632b8ac7aad7d414c1e58425d5fc8e84909" + integrity sha512-qE2xjMathybYxjiGFJg0mLFrz0qNp83aNZycWDY/SuHiZNq+vQfRQtuINqyXyue1ELd8Rd+1OhFSLjms8msMbw== dependencies: "@types/babel__traverse" "^7.0.6" -babel-preset-jest@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-25.2.1.tgz#4ccd0e577f69aa11b71806edfe8b25a5c3ac93a2" - integrity sha512-zXHJBM5iR8oEO4cvdF83AQqqJf3tJrXy3x8nfu2Nlqvn4cneg4Ca8M7cQvC5S9BzDDy1O0tZ9iXru9J6E3ym+A== +babel-preset-jest@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-25.2.6.tgz#5d3f7c99e2a8508d61775c9d68506d143b7f71b5" + integrity sha512-Xh2eEAwaLY9+SyMt/xmGZDnXTW/7pSaBPG0EMo7EuhvosFKVWYB6CqwYD31DaEQuoTL090oDZ0FEqygffGRaSQ== dependencies: "@babel/plugin-syntax-bigint" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - babel-plugin-jest-hoist "^25.2.1" + babel-plugin-jest-hoist "^25.2.6" balanced-match@^1.0.0: version "1.0.0" @@ -1831,10 +1830,10 @@ diff-sequences@^25.1.0: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.1.0.tgz#fd29a46f1c913fd66c22645dc75bffbe43051f32" integrity sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw== -diff-sequences@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.1.tgz#fcfe8aa07dd9b0c648396a478dabca8e76c6ab27" - integrity sha512-foe7dXnGlSh3jR1ovJmdv+77VQj98eKCHHwJPbZ2eEf0fHwKbkZicpPxEch9smZ+n2dnF6QFwkOQdLq9hpeJUg== +diff-sequences@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" + integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg== diff@^4.0.1: version "4.0.1" @@ -2007,17 +2006,17 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^25.2.4: - version "25.2.4" - resolved "https://registry.yarnpkg.com/expect/-/expect-25.2.4.tgz#b66e0777c861034ebc21730bb34e1839d5d46806" - integrity sha512-hfuPhPds4yOsZtIw4kwAg70r0hqGmpqekgA+VX7pf/3wZ6FY+xIOXZhNsPMMMsspYG/YIsbAiwqsdnD4Ht+bCA== +expect@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/expect/-/expect-25.2.6.tgz#85f022097e8ed3c5666c1bd7f9076d3a790a8a47" + integrity sha512-hMqqX3OX5Erw7CLoXXcawqi6xThhz/rYk+vEufhoCAyzDC2PW99ypYc/pvcgKjyuwbOB1wjqqClmwvlOL36Inw== dependencies: - "@jest/types" "^25.2.3" + "@jest/types" "^25.2.6" ansi-styles "^4.0.0" - jest-get-type "^25.2.1" - jest-matcher-utils "^25.2.3" - jest-message-util "^25.2.4" - jest-regex-util "^25.2.1" + jest-get-type "^25.2.6" + jest-matcher-utils "^25.2.6" + jest-message-util "^25.2.6" + jest-regex-util "^25.2.6" express@^4.17.1: version "4.17.1" @@ -2794,56 +2793,56 @@ jasmine@^3.5.0: glob "^7.1.4" jasmine-core "~3.5.0" -jest-changed-files@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-25.2.3.tgz#ad19deef9e47ba37efb432d2c9a67dfd97cc78af" - integrity sha512-EFxy94dvvbqRB36ezIPLKJ4fDIC+jAdNs8i8uTwFpaXd6H3LVc3ova1lNS4ZPWk09OCR2vq5kSdSQgar7zMORg== +jest-changed-files@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-25.2.6.tgz#7d569cd6b265b1a84db3914db345d9c452f26b71" + integrity sha512-F7l2m5n55jFnJj4ItB9XbAlgO+6umgvz/mdK76BfTd2NGkvGf9x96hUXP/15a1K0k14QtVOoutwpRKl360msvg== dependencies: - "@jest/types" "^25.2.3" + "@jest/types" "^25.2.6" execa "^3.2.0" throat "^5.0.0" -jest-cli@^25.2.4: - version "25.2.4" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-25.2.4.tgz#021c2383904696597abc060dcb133c82ebd8bfcc" - integrity sha512-zeY2pRDWKj2LZudIncvvguwLMEdcnJqc2jJbwza1beqi80qqLvkPF/BjbFkK2sIV3r+mfTJS+7ITrvK6pCdRjg== +jest-cli@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-25.2.6.tgz#972356e70663e9b4faa07c507704441786e524e8" + integrity sha512-i31HkagK5veFOUg1ZqxxfP+ZeKDggmI5qZhK6/Cp0ohuaKFQdtS43AqqnXg13JWKCV0E38Nu/K0W4NsFlXLNEA== dependencies: - "@jest/core" "^25.2.4" - "@jest/test-result" "^25.2.4" - "@jest/types" "^25.2.3" + "@jest/core" "^25.2.6" + "@jest/test-result" "^25.2.6" + "@jest/types" "^25.2.6" chalk "^3.0.0" exit "^0.1.2" import-local "^3.0.2" is-ci "^2.0.0" - jest-config "^25.2.4" - jest-util "^25.2.3" - jest-validate "^25.2.3" + jest-config "^25.2.6" + jest-util "^25.2.6" + jest-validate "^25.2.6" prompts "^2.0.1" realpath-native "^2.0.0" yargs "^15.3.1" -jest-config@^25.2.4: - version "25.2.4" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-25.2.4.tgz#f4f33238979f225683179c89d1e402893008975d" - integrity sha512-fxy3nIpwJqOUQJRVF/q+pNQb6dv5b9YufOeCbpPZJ/md1zXpiupbhfehpfODhnKOfqbzSiigtSLzlWWmbRxnqQ== +jest-config@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-25.2.6.tgz#fecff70f9fb083db1a25e7a624c3cd3035d01546" + integrity sha512-R82bUaOHU/2nPSXmvrwLZtQRRr5x1V7qEXE0i4Pybv55XDqVl2/yKNBkYPneG3uSL3n5f6EJeP0/9HNxQu/SZg== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^25.2.4" - "@jest/types" "^25.2.3" - babel-jest "^25.2.4" + "@jest/test-sequencer" "^25.2.6" + "@jest/types" "^25.2.6" + babel-jest "^25.2.6" chalk "^3.0.0" deepmerge "^4.2.2" glob "^7.1.1" - jest-environment-jsdom "^25.2.4" - jest-environment-node "^25.2.4" - jest-get-type "^25.2.1" - jest-jasmine2 "^25.2.4" - jest-regex-util "^25.2.1" - jest-resolve "^25.2.3" - jest-util "^25.2.3" - jest-validate "^25.2.3" + jest-environment-jsdom "^25.2.6" + jest-environment-node "^25.2.6" + jest-get-type "^25.2.6" + jest-jasmine2 "^25.2.6" + jest-regex-util "^25.2.6" + jest-resolve "^25.2.6" + jest-util "^25.2.6" + jest-validate "^25.2.6" micromatch "^4.0.2" - pretty-format "^25.2.3" + pretty-format "^25.2.6" realpath-native "^2.0.0" jest-diff@^25.1.0: @@ -2856,56 +2855,56 @@ jest-diff@^25.1.0: jest-get-type "^25.1.0" pretty-format "^25.1.0" -jest-diff@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.2.3.tgz#54d601a0a754ef26e808a8c8dbadd278c215aa3f" - integrity sha512-VtZ6LAQtaQpFsmEzps15dQc5ELbJxy4L2DOSo2Ev411TUEtnJPkAMD7JneVypeMJQ1y3hgxN9Ao13n15FAnavg== +jest-diff@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.2.6.tgz#a6d70a9ab74507715ea1092ac513d1ab81c1b5e7" + integrity sha512-KuadXImtRghTFga+/adnNrv9s61HudRMR7gVSbP35UKZdn4IK2/0N0PpGZIqtmllK9aUyye54I3nu28OYSnqOg== dependencies: chalk "^3.0.0" - diff-sequences "^25.2.1" - jest-get-type "^25.2.1" - pretty-format "^25.2.3" + diff-sequences "^25.2.6" + jest-get-type "^25.2.6" + pretty-format "^25.2.6" -jest-docblock@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-25.2.3.tgz#ac45280c43d59e7139f9fbe5896c6e0320c01ebb" - integrity sha512-d3/tmjLLrH5fpRGmIm3oFa3vOaD/IjPxtXVOrfujpfJ9y1tCDB1x/tvunmdOVAyF03/xeMwburl6ITbiQT1mVA== +jest-docblock@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-25.2.6.tgz#4b09f1e7b7d6b3f39242ef3647ac7106770f722b" + integrity sha512-VAYrljEq0upq0oERfIaaNf28gC6p9gORndhHstCYF8NWGNQJnzoaU//S475IxfWMk4UjjVmS9rJKLe5Jjjbixw== dependencies: detect-newline "^3.0.0" -jest-each@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-25.2.3.tgz#64067ba1508ebbd07e9b126c173ab371e8e6309d" - integrity sha512-RTlmCjsBDK2c9T5oO4MqccA3/5Y8BUtiEy7OOQik1iyCgdnNdHbI0pNEpyapZPBG0nlvZ4mIu7aY6zNUvLraAQ== +jest-each@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-25.2.6.tgz#026f6dea2ccc443c35cea793265620aab1b278b6" + integrity sha512-OgQ01VINaRD6idWJOhCYwUc5EcgHBiFlJuw+ON2VgYr7HLtMFyCcuo+3mmBvuLUH4QudREZN7cDCZviknzsaJQ== dependencies: - "@jest/types" "^25.2.3" + "@jest/types" "^25.2.6" chalk "^3.0.0" - jest-get-type "^25.2.1" - jest-util "^25.2.3" - pretty-format "^25.2.3" - -jest-environment-jsdom@^25.2.4: - version "25.2.4" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-25.2.4.tgz#f2783541d0538b1bc43641703372cea6a2e83611" - integrity sha512-5dm+tNwrLmhELdjAwiQnVGf/U9iFMWdTL4/wyrMg2HU6RQnCiuxpWbIigLHUhuP1P2Ak0F4k3xhjrikboKyShA== - dependencies: - "@jest/environment" "^25.2.4" - "@jest/fake-timers" "^25.2.4" - "@jest/types" "^25.2.3" - jest-mock "^25.2.3" - jest-util "^25.2.3" + jest-get-type "^25.2.6" + jest-util "^25.2.6" + pretty-format "^25.2.6" + +jest-environment-jsdom@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-25.2.6.tgz#b7ae41c6035905b8e58d63a8f63cf8eaa00af279" + integrity sha512-/o7MZIhGmLGIEG5j7r5B5Az0umWLCHU+F5crwfbm0BzC4ybHTJZOQTFQWhohBg+kbTCNOuftMcqHlVkVduJCQQ== + dependencies: + "@jest/environment" "^25.2.6" + "@jest/fake-timers" "^25.2.6" + "@jest/types" "^25.2.6" + jest-mock "^25.2.6" + jest-util "^25.2.6" jsdom "^15.2.1" -jest-environment-node@^25.2.4: - version "25.2.4" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-25.2.4.tgz#dc211dfb0d8b66dfc1965a8f846e72e54ff0c430" - integrity sha512-Jkc5Y8goyXPrLRHnrUlqC7P4o5zn2m4zw6qWoRJ59kxV1f2a5wK+TTGhrhCwnhW/Ckpdl/pm+LufdvhJkvJbiw== +jest-environment-node@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-25.2.6.tgz#ad4398432867113f474d94fe37b071ed04b30f3d" + integrity sha512-D1Ihj14fxZiMHGeTtU/LunhzSI+UeBvlr/rcXMTNyRMUMSz2PEhuqGbB78brBY6Dk3FhJDk7Ta+8reVaGjLWhA== dependencies: - "@jest/environment" "^25.2.4" - "@jest/fake-timers" "^25.2.4" - "@jest/types" "^25.2.3" - jest-mock "^25.2.3" - jest-util "^25.2.3" + "@jest/environment" "^25.2.6" + "@jest/fake-timers" "^25.2.6" + "@jest/types" "^25.2.6" + jest-mock "^25.2.6" + jest-util "^25.2.6" semver "^6.3.0" jest-get-type@^25.1.0: @@ -2913,23 +2912,23 @@ jest-get-type@^25.1.0: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.1.0.tgz#1cfe5fc34f148dc3a8a3b7275f6b9ce9e2e8a876" integrity sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw== -jest-get-type@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.1.tgz#6c83de603c41b1627e6964da2f5454e6aa3c13a6" - integrity sha512-EYjTiqcDTCRJDcSNKbLTwn/LcDPEE7ITk8yRMNAOjEsN6yp+Uu+V1gx4djwnuj/DvWg0YGmqaBqPVGsPxlvE7w== +jest-get-type@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877" + integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig== -jest-haste-map@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-25.2.3.tgz#2649392b5af191f0167a27bfb62e5d96d7eaaade" - integrity sha512-pAP22OHtPr4qgZlJJFks2LLgoQUr4XtM1a+F5UaPIZNiCRnePA0hM3L7aiJ0gzwiNIYwMTfKRwG/S1L28J3A3A== +jest-haste-map@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-25.2.6.tgz#4aa6bcfa15310afccdb9ca77af58a98add8cedb8" + integrity sha512-nom0+fnY8jwzelSDQnrqaKAcDZczYQvMEwcBjeL3PQ4MlcsqeB7dmrsAniUw/9eLkngT5DE6FhnenypilQFsgA== dependencies: - "@jest/types" "^25.2.3" + "@jest/types" "^25.2.6" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.3" - jest-serializer "^25.2.1" - jest-util "^25.2.3" - jest-worker "^25.2.1" + jest-serializer "^25.2.6" + jest-util "^25.2.6" + jest-worker "^25.2.6" micromatch "^4.0.2" sane "^4.0.3" walker "^1.0.7" @@ -2937,230 +2936,229 @@ jest-haste-map@^25.2.3: optionalDependencies: fsevents "^2.1.2" -jest-jasmine2@^25.2.4: - version "25.2.4" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-25.2.4.tgz#5f77de83e1027f0c7588137055a80da773872374" - integrity sha512-juoKrmNmLwaheNbAg71SuUF9ovwUZCFNTpKVhvCXWk+SSeORcIUMptKdPCoLXV3D16htzhTSKmNxnxSk4SrTjA== +jest-jasmine2@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-25.2.6.tgz#f0de8e922de421444e34be23a66e8887fee9b2a1" + integrity sha512-0429YtThQjol9EElh0mLMsfMBB++yFCjWuGv3xNK4QPrvralJRlpHbuhfSVaOsHC91RrRBbKfM7jSA+FiVG+Jg== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^25.2.4" - "@jest/source-map" "^25.2.1" - "@jest/test-result" "^25.2.4" - "@jest/types" "^25.2.3" + "@jest/environment" "^25.2.6" + "@jest/source-map" "^25.2.6" + "@jest/test-result" "^25.2.6" + "@jest/types" "^25.2.6" chalk "^3.0.0" co "^4.6.0" - expect "^25.2.4" + expect "^25.2.6" is-generator-fn "^2.0.0" - jest-each "^25.2.3" - jest-matcher-utils "^25.2.3" - jest-message-util "^25.2.4" - jest-runtime "^25.2.4" - jest-snapshot "^25.2.4" - jest-util "^25.2.3" - pretty-format "^25.2.3" + jest-each "^25.2.6" + jest-matcher-utils "^25.2.6" + jest-message-util "^25.2.6" + jest-runtime "^25.2.6" + jest-snapshot "^25.2.6" + jest-util "^25.2.6" + pretty-format "^25.2.6" throat "^5.0.0" -jest-leak-detector@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-25.2.3.tgz#4cf39f137925e0061c04c24ca65cae36465f0238" - integrity sha512-yblCMPE7NJKl7778Cf/73yyFWAas5St0iiEBwq7RDyaz6Xd4WPFnPz2j7yDb/Qce71A1IbDoLADlcwD8zT74Aw== +jest-leak-detector@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-25.2.6.tgz#68fbaf651142292b03e30641f33e15af9b8c62b1" + integrity sha512-n+aJUM+j/x1kIaPVxzerMqhAUuqTU1PL5kup46rXh+l9SP8H6LqECT/qD1GrnylE1L463/0StSPkH4fUpkuEjA== dependencies: - jest-get-type "^25.2.1" - pretty-format "^25.2.3" + jest-get-type "^25.2.6" + pretty-format "^25.2.6" -jest-matcher-utils@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.2.3.tgz#59285bd6d6c810debc9caa585ed985e46a3f28fd" - integrity sha512-ZmiXiwQRVM9MoKjGMP5YsGGk2Th5ncyRxfXKz5AKsmU8m43kgNZirckVzaP61MlSa9LKmXbevdYqVp1ZKAw2Rw== +jest-matcher-utils@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.2.6.tgz#a5156c1daa16e13ff6c55117f798b285a294a3e6" + integrity sha512-+6IbC98ZBw3X7hsfUvt+7VIYBdI0FEvhSBjWo9XTHOc1KAAHDsrSHdeyHH/Su0r/pf4OEGuWRRLPnjkhS2S19A== dependencies: chalk "^3.0.0" - jest-diff "^25.2.3" - jest-get-type "^25.2.1" - pretty-format "^25.2.3" + jest-diff "^25.2.6" + jest-get-type "^25.2.6" + pretty-format "^25.2.6" -jest-message-util@^25.2.4: - version "25.2.4" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.2.4.tgz#b1441b9c82f5c11fc661303cbf200a2f136a7762" - integrity sha512-9wWMH3Bf+GVTv0GcQLmH/FRr0x0toptKw9TA8U5YFLVXx7Tq9pvcNzTyJrcTJ+wLqNbMPPJlJNft4MnlcrtF5Q== +jest-message-util@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.2.6.tgz#9d5523bebec8cd9cdef75f0f3069d6ec9a2252df" + integrity sha512-Hgg5HbOssSqOuj+xU1mi7m3Ti2nwSQJQf/kxEkrz2r2rp2ZLO1pMeKkz2WiDUWgSR+APstqz0uMFcE5yc0qdcg== dependencies: "@babel/code-frame" "^7.0.0" - "@jest/test-result" "^25.2.4" - "@jest/types" "^25.2.3" + "@jest/types" "^25.2.6" "@types/stack-utils" "^1.0.1" chalk "^3.0.0" micromatch "^4.0.2" slash "^3.0.0" stack-utils "^1.0.1" -jest-mock@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-25.2.3.tgz#b37a581f59d61bd91db27a99bf7eb8b3e5e993d5" - integrity sha512-xlf+pyY0j47zoCs8zGGOGfWyxxLximE8YFOfEK8s4FruR8DtM/UjNj61um+iDuMAFEBDe1bhCXkqiKoCmWjJzg== +jest-mock@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-25.2.6.tgz#8df66eaa55a713d0f2a7dfb4f14507289d24dfa3" + integrity sha512-vc4nibavi2RGPdj/MyZy/azuDjZhpYZLvpfgq1fxkhbyTpKVdG7CgmRVKJ7zgLpY5kuMjTzDYA6QnRwhsCU+tA== dependencies: - "@jest/types" "^25.2.3" + "@jest/types" "^25.2.6" jest-pnp-resolver@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== -jest-regex-util@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.2.1.tgz#db64b0d15cd3642c93b7b9627801d7c518600584" - integrity sha512-wroFVJw62LdqTdkL508ZLV82FrJJWVJMIuYG7q4Uunl1WAPTf4ftPKrqqfec4SvOIlvRZUdEX2TFpWR356YG/w== +jest-regex-util@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.2.6.tgz#d847d38ba15d2118d3b06390056028d0f2fd3964" + integrity sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw== -jest-resolve-dependencies@^25.2.4: - version "25.2.4" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-25.2.4.tgz#2d904400387d74a366dff54badb40a2b3210e733" - integrity sha512-qhUnK4PfNHzNdca7Ub1mbAqE0j5WNyMTwxBZZJjQlUrdqsiYho/QGK65FuBkZuSoYtKIIqriR9TpGrPEc3P5Gg== +jest-resolve-dependencies@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-25.2.6.tgz#c42272ff49e6be83a8ed9366b4c6e563a1e5604c" + integrity sha512-SJeRBCDZzXVy/DjbwBH3KzjxPw5Q/j3foDkWZYu2GIa6SHqy34qVaw1mL7SJg9r6GApwjIoKP6fGwU6c/afg0A== dependencies: - "@jest/types" "^25.2.3" - jest-regex-util "^25.2.1" - jest-snapshot "^25.2.4" + "@jest/types" "^25.2.6" + jest-regex-util "^25.2.6" + jest-snapshot "^25.2.6" -jest-resolve@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-25.2.3.tgz#ababeaf2bb948cb6d2dea8453759116da0fb7842" - integrity sha512-1vZMsvM/DBH258PnpUNSXIgtzpYz+vCVCj9+fcy4akZl4oKbD+9hZSlfe9RIDpU0Fc28ozHQrmwX3EqFRRIHGg== +jest-resolve@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-25.2.6.tgz#84694ead5da13c2890ac04d4a78699ba937f3896" + integrity sha512-7O61GVdcAXkLz/vNGKdF+00A80/fKEAA47AEXVNcZwj75vEjPfZbXDaWFmAQCyXj4oo9y9dC9D+CLA11t8ieGw== dependencies: - "@jest/types" "^25.2.3" + "@jest/types" "^25.2.6" browser-resolve "^1.11.3" chalk "^3.0.0" jest-pnp-resolver "^1.2.1" realpath-native "^2.0.0" resolve "^1.15.1" -jest-runner@^25.2.4: - version "25.2.4" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-25.2.4.tgz#d0daf7c56b4a83b6b675863d5cdcd502c960f9a1" - integrity sha512-5xaIfqqxck9Wg2CV4b9KmJtf/sWO7zWQx7O+34GCLGPzoPcVmB3mZtdrQI1/jS3Reqjru9ycLjgLHSf6XoxRqA== +jest-runner@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-25.2.6.tgz#5ee1607e66890ccd798695cfaa708e322087c50b" + integrity sha512-sN45p3jxvpsG7UjeQFqyC+JR5+THLrIT9oXAHwQQIDWfpmZBFko2RROn1fvdQNWhuPzDeUf/oHykbhNRGo9eWg== dependencies: - "@jest/console" "^25.2.3" - "@jest/environment" "^25.2.4" - "@jest/test-result" "^25.2.4" - "@jest/types" "^25.2.3" + "@jest/console" "^25.2.6" + "@jest/environment" "^25.2.6" + "@jest/test-result" "^25.2.6" + "@jest/types" "^25.2.6" chalk "^3.0.0" exit "^0.1.2" graceful-fs "^4.2.3" - jest-config "^25.2.4" - jest-docblock "^25.2.3" - jest-haste-map "^25.2.3" - jest-jasmine2 "^25.2.4" - jest-leak-detector "^25.2.3" - jest-message-util "^25.2.4" - jest-resolve "^25.2.3" - jest-runtime "^25.2.4" - jest-util "^25.2.3" - jest-worker "^25.2.1" + jest-config "^25.2.6" + jest-docblock "^25.2.6" + jest-haste-map "^25.2.6" + jest-jasmine2 "^25.2.6" + jest-leak-detector "^25.2.6" + jest-message-util "^25.2.6" + jest-resolve "^25.2.6" + jest-runtime "^25.2.6" + jest-util "^25.2.6" + jest-worker "^25.2.6" source-map-support "^0.5.6" throat "^5.0.0" -jest-runtime@^25.2.4: - version "25.2.4" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-25.2.4.tgz#c66a421e115944426b377a7fd331f6c0902cfa56" - integrity sha512-6ehOUizgIghN+aV5YSrDzTZ+zJ9omgEjJbTHj3Jqes5D52XHfhzT7cSfdREwkNjRytrR7mNwZ7pRauoyNLyJ8Q== - dependencies: - "@jest/console" "^25.2.3" - "@jest/environment" "^25.2.4" - "@jest/source-map" "^25.2.1" - "@jest/test-result" "^25.2.4" - "@jest/transform" "^25.2.4" - "@jest/types" "^25.2.3" +jest-runtime@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-25.2.6.tgz#417e8d548c92bd10e659393a3bd5aa8cbdd71e6d" + integrity sha512-u0iNjO7VvI46341igiQP/bnm1TwdXV6IjVEo7DMVqRbTDTz4teTNOUXChuSMdoyjQcfJ3zmI7/jVktUpjnZhYw== + dependencies: + "@jest/console" "^25.2.6" + "@jest/environment" "^25.2.6" + "@jest/source-map" "^25.2.6" + "@jest/test-result" "^25.2.6" + "@jest/transform" "^25.2.6" + "@jest/types" "^25.2.6" "@types/yargs" "^15.0.0" chalk "^3.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.2.3" - jest-config "^25.2.4" - jest-haste-map "^25.2.3" - jest-message-util "^25.2.4" - jest-mock "^25.2.3" - jest-regex-util "^25.2.1" - jest-resolve "^25.2.3" - jest-snapshot "^25.2.4" - jest-util "^25.2.3" - jest-validate "^25.2.3" + jest-config "^25.2.6" + jest-haste-map "^25.2.6" + jest-message-util "^25.2.6" + jest-mock "^25.2.6" + jest-regex-util "^25.2.6" + jest-resolve "^25.2.6" + jest-snapshot "^25.2.6" + jest-util "^25.2.6" + jest-validate "^25.2.6" realpath-native "^2.0.0" slash "^3.0.0" strip-bom "^4.0.0" yargs "^15.3.1" -jest-serializer@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-25.2.1.tgz#51727a5fc04256f461abe0fa024a022ba165877a" - integrity sha512-fibDi7M5ffx6c/P66IkvR4FKkjG5ldePAK1WlbNoaU4GZmIAkS9Le/frAwRUFEX0KdnisSPWf+b1RC5jU7EYJQ== +jest-serializer@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-25.2.6.tgz#3bb4cc14fe0d8358489dbbefbb8a4e708ce039b7" + integrity sha512-RMVCfZsezQS2Ww4kB5HJTMaMJ0asmC0BHlnobQC6yEtxiFKIxohFA4QSXSabKwSggaNkqxn6Z2VwdFCjhUWuiQ== -jest-snapshot@^25.2.4: - version "25.2.4" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-25.2.4.tgz#08d4517579c864df4280bcc948ceea34327a4ded" - integrity sha512-nIwpW7FZCq5p0AE3Oyqyb6jL0ENJixXzJ5/CD/XRuOqp3gS5OM3O/k+NnTrniCXxPFV4ry6s9HNfiPQBi0wcoA== +jest-snapshot@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-25.2.6.tgz#a3b99fa6fea4955b6a5fcb38c657e4daaba363f9" + integrity sha512-Zw/Ba6op5zInjPHoA2xGUrCw1G/iTHOGMhV02PzlrWhF9uTl2/jjk/bpOMkPaW8EyylmQbjQ2oj4jCfYwpDKng== dependencies: "@babel/types" "^7.0.0" - "@jest/types" "^25.2.3" + "@jest/types" "^25.2.6" "@types/prettier" "^1.19.0" chalk "^3.0.0" - expect "^25.2.4" - jest-diff "^25.2.3" - jest-get-type "^25.2.1" - jest-matcher-utils "^25.2.3" - jest-message-util "^25.2.4" - jest-resolve "^25.2.3" + expect "^25.2.6" + jest-diff "^25.2.6" + jest-get-type "^25.2.6" + jest-matcher-utils "^25.2.6" + jest-message-util "^25.2.6" + jest-resolve "^25.2.6" make-dir "^3.0.0" natural-compare "^1.4.0" - pretty-format "^25.2.3" + pretty-format "^25.2.6" semver "^6.3.0" -jest-util@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.2.3.tgz#0abf95a1d6b96f2de5a3ecd61b36c40a182dc256" - integrity sha512-7tWiMICVSo9lNoObFtqLt9Ezt5exdFlWs5fLe1G4XLY2lEbZc814cw9t4YHScqBkWMfzth8ASHKlYBxiX2rdCw== +jest-util@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.2.6.tgz#3c1c95cdfd653126728b0ed861a86610e30d569c" + integrity sha512-gpXy0H5ymuQ0x2qgl1zzHg7LYHZYUmDEq6F7lhHA8M0eIwDB2WteOcCnQsohl9c/vBKZ3JF2r4EseipCZz3s4Q== dependencies: - "@jest/types" "^25.2.3" + "@jest/types" "^25.2.6" chalk "^3.0.0" is-ci "^2.0.0" make-dir "^3.0.0" -jest-validate@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-25.2.3.tgz#ecb0f093cf8ae71d15075fb48439b6f78f1fcb5a" - integrity sha512-GObn91jzU0B0Bv4cusAwjP6vnWy78hJUM8MOSz7keRfnac/ZhQWIsUjvk01IfeXNTemCwgR57EtdjQMzFZGREg== +jest-validate@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-25.2.6.tgz#ab3631fb97e242c42b09ca53127abe0b12e9125e" + integrity sha512-a4GN7hYbqQ3Rt9iHsNLFqQz7HDV7KiRPCwPgo5nqtTIWNZw7gnT8KchG+Riwh+UTSn8REjFCodGp50KX/fRNgQ== dependencies: - "@jest/types" "^25.2.3" + "@jest/types" "^25.2.6" camelcase "^5.3.1" chalk "^3.0.0" - jest-get-type "^25.2.1" + jest-get-type "^25.2.6" leven "^3.1.0" - pretty-format "^25.2.3" + pretty-format "^25.2.6" -jest-watcher@^25.2.4: - version "25.2.4" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-25.2.4.tgz#dda85b914d470fa4145164a8f70bda4f208bafb6" - integrity sha512-p7g7s3zqcy69slVzQYcphyzkB2FBmJwMbv6k6KjI5mqd6KnUnQPfQVKuVj2l+34EeuxnbXqnrjtUFmxhcL87rg== +jest-watcher@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-25.2.6.tgz#19fc571d27f89a238ef497b9e037d8d41cf4a204" + integrity sha512-yzv5DBeo03dQnSsSrn1mdOU1LSDd1tZaCTvSE5JYfcv6Z66PdDNhO9MNDdLKA/oQlJNj0S6TiYgLdOY5wL5cMA== dependencies: - "@jest/test-result" "^25.2.4" - "@jest/types" "^25.2.3" + "@jest/test-result" "^25.2.6" + "@jest/types" "^25.2.6" ansi-escapes "^4.2.1" chalk "^3.0.0" - jest-util "^25.2.3" + jest-util "^25.2.6" string-length "^3.1.0" -jest-worker@^25.2.1: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.2.1.tgz#209617015c768652646aa33a7828cc2ab472a18a" - integrity sha512-IHnpekk8H/hCUbBlfeaPZzU6v75bqwJp3n4dUrQuQOAgOneI4tx3jV2o8pvlXnDfcRsfkFIUD//HWXpCmR+evQ== +jest-worker@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.2.6.tgz#d1292625326794ce187c38f51109faced3846c58" + integrity sha512-FJn9XDUSxcOR4cwDzRfL1z56rUofNTFs539FGASpd50RHdb6EVkhxQqktodW2mI49l+W3H+tFJDotCHUQF6dmA== dependencies: merge-stream "^2.0.0" supports-color "^7.0.0" -jest@^25.2.4: - version "25.2.4" - resolved "https://registry.yarnpkg.com/jest/-/jest-25.2.4.tgz#d10941948a2b57eb7accc2e7ae78af4a0e11b40a" - integrity sha512-Lu4LXxf4+durzN/IFilcAoQSisOwgHIXgl9vffopePpSSwFqfj1Pj4y+k3nL8oTbnvjxgDIsEcepy6he4bWqnQ== +jest@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest/-/jest-25.2.6.tgz#da597f3563dceba12913965ea398fe7f8804fb12" + integrity sha512-AA9U1qmYViBTfoKWzQBbBmck53Tsw8av7zRYdE4EUBU6r04mddPQaflpPBy/KC308HF7u8fLLxEJFt/LiFzYFQ== dependencies: - "@jest/core" "^25.2.4" + "@jest/core" "^25.2.6" import-local "^3.0.2" - jest-cli "^25.2.4" + jest-cli "^25.2.6" js-sha256@^0.9.0: version "0.9.0" @@ -4071,12 +4069,12 @@ pretty-format@^25.1.0: ansi-styles "^4.0.0" react-is "^16.12.0" -pretty-format@^25.2.3: - version "25.2.3" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.2.3.tgz#ba6e9603a0d80fa2e470b1fed55de1f9bfd81421" - integrity sha512-IP4+5UOAVGoyqC/DiomOeHBUKN6q00gfyT2qpAsRH64tgOKB2yF7FHJXC18OCiU0/YFierACup/zdCOWw0F/0w== +pretty-format@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.2.6.tgz#542a1c418d019bbf1cca2e3620443bc1323cb8d7" + integrity sha512-DEiWxLBaCHneffrIT4B+TpMvkV9RNvvJrd3lY9ew1CEQobDzEXmYT1mg0hJhljZty7kCc10z13ohOFAE8jrUDg== dependencies: - "@jest/types" "^25.2.3" + "@jest/types" "^25.2.6" ansi-regex "^5.0.0" ansi-styles "^4.0.0" react-is "^16.12.0" From 7024793cf202d1b545a061443684909321a88413 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 2 Apr 2020 15:54:58 +0000 Subject: [PATCH 34/88] Bump tslint from 6.1.0 to 6.1.1 in /api_tests Bumps [tslint](https://github.com/palantir/tslint) from 6.1.0 to 6.1.1. - [Release notes](https://github.com/palantir/tslint/releases) - [Changelog](https://github.com/palantir/tslint/blob/master/CHANGELOG.md) - [Commits](https://github.com/palantir/tslint/compare/6.1.0...6.1.1) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 3452880509..0c05cd1096 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -60,7 +60,7 @@ "tmp": "^0.1.0", "ts-jest": "^25.3.0", "ts-node": "^8.8.1", - "tslint": "^6.1.0", + "tslint": "^6.1.1", "tslint-config-prettier": "^1.18.0", "tslint-no-unused-expression-chai": "^0.1.4", "typescript": "^3.8.3" diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 53aeae1614..6479c7b4b3 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -3529,16 +3529,16 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: dependencies: brace-expansion "^1.1.7" -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - minimist@^1.1.1, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= +minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" @@ -3567,12 +3567,12 @@ mkdirp@1.x: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.3.tgz#4cf2e30ad45959dddea53ad97d518b6c8205e1ea" integrity sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g== -mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= +mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1: + version "0.5.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.4.tgz#fd01504a6797ec5c9be81ff43d204961ed64a512" + integrity sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw== dependencies: - minimist "0.0.8" + minimist "^1.2.5" moment@^2.10.6, moment@^2.24.0: version "2.24.0" @@ -5023,10 +5023,10 @@ tslint-no-unused-expression-chai@^0.1.4: dependencies: tsutils "^3.0.0" -tslint@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.0.tgz#c6c611b8ba0eed1549bf5a59ba05a7732133d851" - integrity sha512-fXjYd/61vU6da04E505OZQGb2VCN2Mq3doeWcOIryuG+eqdmFUXTYVwdhnbEu2k46LNLgUYt9bI5icQze/j0bQ== +tslint@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.1.tgz#ac03fbd17f85bfefaae348b353b25a88efe10cde" + integrity sha512-kd6AQ/IgPRpLn6g5TozqzPdGNZ0q0jtXW4//hRcj10qLYBaa3mTUU2y2MCG+RXZm8Zx+KZi0eA+YCrMyNlF4UA== dependencies: "@babel/code-frame" "^7.0.0" builtin-modules "^1.1.1" @@ -5036,7 +5036,7 @@ tslint@^6.1.0: glob "^7.1.1" js-yaml "^3.13.1" minimatch "^3.0.4" - mkdirp "^0.5.1" + mkdirp "^0.5.3" resolve "^1.3.2" semver "^5.3.0" tslib "^1.10.0" From 7a981010ee01f78fda91e9b7c9d4a3d3a4236395 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Fri, 3 Apr 2020 09:57:40 +1100 Subject: [PATCH 35/88] Allow user to choose hash function in Digest macro Also several improvements: - use unique `digest` attribute for fields and struct - test compatibility with other struct & field attributes --- Cargo.lock | 1 + digest-macro-derive/src/lib.rs | 101 ++++++++++++++++++++++++--------- digest/Cargo.toml | 4 +- digest/src/lib.rs | 50 ++++++++++++---- digest/tests/swap_digest.rs | 70 ++++++++++++++++------- 5 files changed, 165 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7698b52eb1..5cfd02c6d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -832,6 +832,7 @@ dependencies = [ "digest-macro-derive", "hex 0.4.2", "multihash", + "serde", ] [[package]] diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index a924fe3e33..59685f2291 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -3,9 +3,9 @@ extern crate proc_macro; use crate::proc_macro::TokenStream; use proc_macro2::{Delimiter, Group, Punct, Spacing}; use quote::{quote, ToTokens, TokenStreamExt}; -use syn::{Attribute, Data, Fields, Lit, Meta}; +use syn::{Attribute, Data, Fields, Lit, Meta, MetaList, NestedMeta, Type}; -#[proc_macro_derive(Digest, attributes(digest_prefix))] +#[proc_macro_derive(Digest, attributes(digest))] pub fn digest_macro_fn(input: TokenStream) -> TokenStream { let ast = syn::parse(input).unwrap(); impl_digest_macro(&ast) @@ -14,6 +14,8 @@ pub fn digest_macro_fn(input: TokenStream) -> TokenStream { fn impl_digest_macro(ast: &syn::DeriveInput) -> TokenStream { let name = &ast.ident; + let hash_type = extract_hash_type(&ast.attrs); + match &ast.data { Data::Struct(data) => { let (idents, types, bytes) = match &data.fields { @@ -25,7 +27,7 @@ fn impl_digest_macro(ast: &syn::DeriveInput) -> TokenStream { let types = fields.named.iter().map(|field| &field.ty); - let bytes = fields.named.iter().map(|field| attr_to_bytes(&field.attrs)); + let bytes = fields.named.iter().map(|field| extract_bytes(&field.attrs)); (idents, types, bytes) } _ => panic!("Only supporting named fields."), @@ -35,18 +37,21 @@ fn impl_digest_macro(ast: &syn::DeriveInput) -> TokenStream { impl ::digest::Digest for #name where #(#types: ::digest::IntoDigestInput),* { - fn digest(self) -> ::multihash::Multihash { + type Hash = #hash_type; + + fn digest(self) -> Self::Hash { + use ::digest::{Hash, IntoDigestInput}; let mut digests = vec![]; - #(digests.push(::digest::field_digest(self.#idents, #bytes.to_vec())););* + #(digests.push(::digest::field_digest::<_, Self::Hash>(self.#idents, #bytes.to_vec())););* digests.sort(); - let res = digests.into_iter().fold(vec![], |mut res, digest| { - res.append(&mut digest.into_bytes()); - res + let bytes = digests.into_iter().fold(vec![], |mut bytes, digest| { + bytes.append(&mut digest.into_digest_input()); + bytes }); - ::digest::digest(&res) + Self::Hash::hash(&bytes) } } }; @@ -63,7 +68,7 @@ fn impl_digest_macro(ast: &syn::DeriveInput) -> TokenStream { .variants .iter() .filter(|variant| variant.fields.is_empty()) - .map(|variant| attr_to_bytes(&variant.attrs)); + .map(|variant| extract_bytes(&variant.attrs)); let tuple_variant_idents = data .variants @@ -81,33 +86,57 @@ fn impl_digest_macro(ast: &syn::DeriveInput) -> TokenStream { Fields::Unnamed(_) => true, _ => false, }) - .map(|variant| attr_to_bytes(&variant.attrs)); + .map(|variant| extract_bytes(&variant.attrs)); let gen = quote! { impl ::digest::Digest for #name { - fn digest(self) -> ::multihash::Multihash { + type Hash = #hash_type; + + fn digest(self) -> Self::Hash { + use ::digest::{Hash, IntoDigestInput}; + let bytes = match self { #(Self::#unit_variant_idents => #unit_variant_bytes.to_vec()),*, #(Self::#tuple_variant_idents(data) => { let mut bytes = #tuple_variant_bytes.to_vec(); - bytes.append(&mut data.digest().into_bytes()); + bytes.append(&mut data.digest().into_digest_input()); bytes }),* }; - ::digest::digest(&bytes) + Self::Hash::hash(&bytes) } } }; gen.into() } _ => { - panic!("DigestRootMacro only supports structs & enums."); + panic!("Digest derive macro only supports structs & enums."); } } } +fn extract_hash_type(attrs: &[Attribute]) -> Type { + let meta_list = extract_meta_list(attrs); + + let path = &meta_list.nested.first(); + if let Some(NestedMeta::Meta(Meta::NameValue(name_value))) = path { + if name_value.path.is_ident("hash") { + if let Lit::Str(ref lit_str) = name_value.lit { + if let Ok(hash_type) = syn::parse_str::(&lit_str.value()) { + return hash_type; + } + } + panic!("hash type could not be resolved. Expected format: `#[digest(hash = \"MyHashType\")]` ") + } else { + panic!("Only `hash` identifier is supported for `digest()` outer attribute. Expected format: `#[digest(hash = \"MyHashType\")]`") + } + } else { + panic!("Could not find element inside `digest` attribute. Expected format: `#[digest(hash = \"MyHashType\")]`") + } +} + struct Bytes(Vec); impl ToTokens for Bytes { @@ -119,23 +148,43 @@ impl ToTokens for Bytes { } } -fn attr_to_bytes(attrs: &[Attribute]) -> Bytes { - let attr = attrs - .get(0) - .expect("digest_prefix attribute must be the only attribute present on all fields"); - let meta = attr.parse_meta().expect("Attribute is malformed"); +fn extract_bytes(attrs: &[Attribute]) -> Bytes { + let meta_list = extract_meta_list(attrs); - if let Meta::NameValue(name_value) = meta { - if name_value.path.is_ident("digest_prefix") { - if let Lit::Str(lit_str) = name_value.lit { + let path = &meta_list.nested.first(); + if let Some(NestedMeta::Meta(Meta::NameValue(name_value))) = path { + if name_value.path.is_ident("prefix") { + if let Lit::Str(ref lit_str) = name_value.lit { let str = lit_str.value(); - let bytes = - ::hex::decode(&str).expect("digest_prefix value should be in hex format"); + let bytes = ::hex::decode(&str).expect("prefix value should be in hex format"); return Bytes(bytes); } + panic!("prefix could not be resolved. Expected format: `#[digest(prefix = \"0102..0A\")]` ") + } else { + panic!("Only `prefix` identifier is supported for `digest()` field attribute. Expected format: `#[digest(prefix = \"0102..0A\")]`") } + } else { + panic!("Could not find element inside `digest` attribute. Expected format: `#[digest(hash = \"MyHashType\")]`") } - panic!("Only `digest_prefix = \"0102..0A\"` attributes are supported"); +} + +fn extract_meta_list(attrs: &[Attribute]) -> MetaList { + attrs + .iter() + .find_map(|attr| { + attr.parse_meta() + .ok() + .map(|meta| { + if let Meta::List(meta_list) = meta { + if meta_list.path.is_ident("digest") { + return Some(meta_list); + } + }; + None + }) + .unwrap_or(None) + }) + .expect("Could not find `digest` attribute.") } #[cfg(test)] diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 0f04cdea1e..5239b99ba1 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -7,5 +7,7 @@ edition = "2018" [dependencies] digest-macro-derive = { path = "../digest-macro-derive" } hex = "0.4" -multihash = "0.10" +[dev-dependencies] +multihash = "0.10" +serde = { version = "1.0", features = ["derive"] } diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 16462e9072..4492f0af19 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -10,10 +10,33 @@ /// this allows you to control how the data is transformed to a byte array. /// /// ``` -/// use digest::{Digest, IntoDigestInput}; +/// use digest::{Digest, Hash, IntoDigestInput}; +/// // multihash from libp2p for example: `use libp2p::multihash` +/// use multihash; /// +/// // Define a hash type. Hash will need to be sorted as per the digest algo described +/// // After this code block so it needs to implement `Eq`, `Ord`, `PartialEq`, `PartialOrd` +/// #[derive(Eq, Ord, PartialEq, PartialOrd)] +/// struct MyHash(multihash::Multihash); +/// +/// // Define a hash function +/// impl Hash for MyHash { +/// fn hash(bytes: &[u8]) -> Self { +/// Self(multihash::Sha3_256::digest(bytes)) +/// } +/// } +/// +/// // Define how to get a byte array from the hash type +/// impl IntoDigestInput for MyHash { +/// fn into_digest_input(self) -> Vec { +/// self.0.into_bytes() +/// } +/// } +/// +/// // Define types for the field of the struct you want to digest /// struct MyType(Vec); /// +/// // And implement `IntoDigestInput` for them /// impl IntoDigestInput for MyType { /// fn into_digest_input(self) -> Vec { /// self.0 @@ -21,10 +44,11 @@ /// } /// /// #[derive(Digest)] +/// #[digest(hash = "MyHash")] /// struct MyStruct { -/// #[digest_prefix = "00AA"] +/// #[digest(prefix = "00AA")] /// foo: MyType, -/// #[digest_prefix = "1122"] +/// #[digest(prefix = "1122")] /// bar: MyType, /// } /// ``` @@ -42,25 +66,27 @@ pub use digest_macro_derive::Digest; pub use hex; -pub use multihash; -use multihash::Multihash; - -pub fn digest(bytes: &[u8]) -> Multihash { - multihash::Sha3_256::digest(bytes) +pub trait Digest { + type Hash: Hash + IntoDigestInput; + fn digest(self) -> Self::Hash; } -pub trait Digest { - fn digest(self) -> Multihash; +pub trait Hash { + fn hash(bytes: &[u8]) -> Self; } pub trait IntoDigestInput { fn into_digest_input(self) -> Vec; } -pub fn field_digest(field: T, prefix: Vec) -> Multihash { +pub fn field_digest(field: T, prefix: Vec) -> H +where + T: IntoDigestInput, + H: Hash, +{ let mut bytes = prefix; let mut value = field.into_digest_input(); bytes.append(&mut value); - digest(&bytes) + H::hash(&bytes) } diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index b5582a9d6e..ae639dd94b 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -1,7 +1,9 @@ -use digest::{digest, field_digest, Digest, IntoDigestInput}; - -use digest::multihash::Multihash; +use digest::{field_digest, Digest, Hash, IntoDigestInput}; +// This is to ensure that it works even if other macros are used on the same +// struct +use serde::Serialize; +#[derive(Serialize)] struct MyString(String); impl IntoDigestInput for MyString { @@ -16,11 +18,29 @@ impl From<&str> for MyString { } } -#[derive(Digest)] +#[derive(Debug, PartialEq, Ord, PartialOrd, Eq)] +struct MultihashSha256(::multihash::Multihash); + +impl digest::Hash for MultihashSha256 { + fn hash(bytes: &[u8]) -> Self { + Self(multihash::Sha3_256::digest(bytes)) + } +} + +impl IntoDigestInput for MultihashSha256 { + fn into_digest_input(self) -> Vec { + self.0.into_bytes() + } +} + +#[derive(Digest, Serialize)] +#[serde(rename_all = "lowercase")] +#[digest(hash = "MultihashSha256")] struct DoubleFieldStruct { - #[digest_prefix = "0011"] + #[digest(prefix = "0011")] + #[serde(alias = "foooo")] foo: MyString, - #[digest_prefix = "FFAA"] + #[digest(prefix = "FFAA")] bar: MyString, } @@ -30,29 +50,34 @@ struct OtherDoubleFieldStruct { } impl Digest for OtherDoubleFieldStruct { - fn digest(self) -> Multihash { + type Hash = MultihashSha256; + + fn digest(self) -> Self::Hash { let mut digests = vec![]; - let foo_digest = field_digest(self.foo, [0x00u8, 0x11u8].to_vec()); + let foo_digest = field_digest::<_, Self::Hash>(self.foo, [0x00u8, 0x11u8].to_vec()); digests.push(foo_digest); - let bar_digest = field_digest(self.bar, [0xFFu8, 0xAAu8].to_vec()); + let bar_digest = field_digest::<_, Self::Hash>(self.bar, [0xFFu8, 0xAAu8].to_vec()); digests.push(bar_digest); digests.sort(); let res = digests.into_iter().fold(vec![], |mut res, digest| { - res.append(&mut digest.into_bytes()); + res.append(&mut digest.0.into_bytes()); res }); - digest(&res) + Self::Hash::hash(&res) } } -#[derive(Digest)] +#[derive(Digest, Serialize)] +#[digest(hash = "MultihashSha256")] +#[serde(rename_all = "lowercase")] enum Enum { - #[digest_prefix = "0011"] + #[serde(alias = "foooo")] + #[digest(prefix = "0011")] Foo, - #[digest_prefix = "0E0F"] + #[digest(prefix = "0E0F")] Bar, } @@ -62,13 +87,14 @@ enum OtherEnum { } impl Digest for OtherEnum { - fn digest(self) -> Multihash { + type Hash = MultihashSha256; + fn digest(self) -> Self::Hash { let bytes = match self { OtherEnum::Foo => vec![0x00u8, 0x11u8], OtherEnum::Bar => vec![0x00u8, 0x11u8], }; - digest(&bytes) + Self::Hash::hash(&bytes) } } @@ -78,8 +104,8 @@ fn given_same_strings_return_same_multihash() { let str2: MyString = "simple string".into(); assert_eq!( - field_digest(str1, "foo".into()), - field_digest(str2, "foo".into()) + field_digest::<_, MultihashSha256>(str1, "foo".into()), + field_digest::<_, MultihashSha256>(str2, "foo".into()) ) } @@ -89,8 +115,8 @@ fn given_same_strings_different_names_return_diff_multihash() { let str2: MyString = "simple string".into(); assert_ne!( - field_digest(str1, "foo".into()), - field_digest(str2, "bar".into()) + field_digest::<_, MultihashSha256>(str1, "foo".into()), + field_digest::<_, MultihashSha256>(str2, "bar".into()) ) } @@ -100,8 +126,8 @@ fn given_different_strings_return_different_multihash() { let str2: MyString = "longer string".into(); assert_ne!( - field_digest(str1, "foo".into()), - field_digest(str2, "foo".into()) + field_digest::<_, MultihashSha256>(str1, "foo".into()), + field_digest::<_, MultihashSha256>(str2, "foo".into()) ) } From 5262497da5853fa05f33ef91226d0b5241d1273b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 3 Apr 2020 19:57:51 +1100 Subject: [PATCH 36/88] Add missing .await on future --- cnd/src/swap_protocols/rfc003/create_swap.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cnd/src/swap_protocols/rfc003/create_swap.rs b/cnd/src/swap_protocols/rfc003/create_swap.rs index 45f3771f97..f616d5a7ea 100644 --- a/cnd/src/swap_protocols/rfc003/create_swap.rs +++ b/cnd/src/swap_protocols/rfc003/create_swap.rs @@ -77,7 +77,7 @@ pub async fn create_watcher( } GeneratorState::Complete(Err(e)) => { tracing::error!("swap {} failed with {:?}", id, e); - dependencies.insert_failed_swap(&id); + dependencies.insert_failed_swap(&id).await; return; } } From 566a33e3143b06ec738f4d1f12cb4b42efda2c28 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 2 Apr 2020 14:14:11 +0000 Subject: [PATCH 37/88] Bump libp2p from 0.16.2 to 0.17.0 Bumps [libp2p](https://github.com/libp2p/rust-libp2p) from 0.16.2 to 0.17.0. - [Release notes](https://github.com/libp2p/rust-libp2p/releases) - [Changelog](https://github.com/libp2p/rust-libp2p/blob/master/CHANGELOG.md) - [Commits](https://github.com/libp2p/rust-libp2p/compare/v0.16.2...v0.17.0) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 594 +++--------------- cnd/Cargo.toml | 2 +- cnd/src/network.rs | 23 +- cnd/src/network/oneshot_behaviour.rs | 13 +- .../network/protocols/announce/behaviour.rs | 57 +- libp2p-comit/Cargo.toml | 4 +- libp2p-comit/src/behaviour.rs | 47 +- libp2p-comit/src/handler.rs | 6 + 8 files changed, 195 insertions(+), 551 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 883911a821..fa0be46c11 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,11 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "adler32" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" - [[package]] name = "aes-ctr" version = "0.3.0" @@ -25,7 +19,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" dependencies = [ "block-cipher-trait", - "byteorder 1.3.4", + "byteorder", "opaque-debug", ] @@ -208,7 +202,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" dependencies = [ - "byteorder 1.3.4", + "byteorder", "safemem", ] @@ -300,28 +294,6 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a993f74b4c99c1908d156b8d2e0fb6277736b0ecbd833982fd1241d39b2766a6" -[[package]] -name = "blake2" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" -dependencies = [ - "byte-tools", - "crypto-mac", - "digest 0.8.1", - "opaque-debug", -] - -[[package]] -name = "blake2-rfc" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" -dependencies = [ - "arrayvec 0.4.12", - "constant_time_eq", -] - [[package]] name = "blake2b_simd" version = "0.5.10" @@ -352,7 +324,7 @@ checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" dependencies = [ "block-padding", "byte-tools", - "byteorder 1.3.4", + "byteorder", "generic-array", ] @@ -381,7 +353,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1d96fd22884503a21dc47fdb102c37131973d12682960c9b3405b95b6625dc7" dependencies = [ "bitcoin", - "byteorder 1.3.4", + "byteorder", "hex 0.4.2", "hex-literal", "itertools", @@ -415,28 +387,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" -[[package]] -name = "byteorder" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" - [[package]] name = "byteorder" version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" -[[package]] -name = "bytes" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -dependencies = [ - "byteorder 1.3.4", - "iovec", -] - [[package]] name = "bytes" version = "0.5.4" @@ -470,15 +426,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" -[[package]] -name = "chacha20-poly1305-aead" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77d2058ba29594f69c75e8a9018e0485e3914ca5084e3613cd64529042f5423b" -dependencies = [ - "constant_time_eq", -] - [[package]] name = "chrono" version = "0.4.11" @@ -547,7 +494,7 @@ dependencies = [ "ethbloom", "fern", "fs2", - "futures 0.3.4", + "futures", "genawaiter", "hex 0.4.2", "http-api-problem", @@ -659,15 +606,6 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" -[[package]] -name = "crc32fast" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" -dependencies = [ - "cfg-if", -] - [[package]] name = "crossbeam-channel" version = "0.4.2" @@ -741,23 +679,13 @@ dependencies = [ "stream-cipher", ] -[[package]] -name = "cuckoofilter" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dd43f7cfaffe0a386636a10baea2ee05cc50df3b77bea4a456c9572a939bf1f" -dependencies = [ - "byteorder 0.5.3", - "rand 0.3.23", -] - [[package]] name = "curve25519-dalek" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26778518a7f6cffa1d25a44b602b62b979bd88adb9e99ffec546998cf3404839" dependencies = [ - "byteorder 1.3.4", + "byteorder", "digest 0.8.1", "rand_core 0.5.1", "subtle 2.2.2", @@ -798,7 +726,7 @@ version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d7ca63eb2efea87a7f56a283acc49e2ce4b2bd54adf7465dc1d81fef13d8fc" dependencies = [ - "byteorder 1.3.4", + "byteorder", "chrono", "diesel_derives", "libsqlite3-sys", @@ -881,7 +809,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" dependencies = [ - "byteorder 1.3.4", + "byteorder", "quick-error", ] @@ -963,7 +891,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32529fc42e86ec06e5047092082aab9ad459b070c5d2a76b14f4f5ce70bf2e84" dependencies = [ - "byteorder 1.3.4", + "byteorder", "rand 0.7.3", "rustc-hex", "static_assertions 1.1.0", @@ -975,18 +903,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" -[[package]] -name = "flate2" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" -dependencies = [ - "cfg-if", - "crc32fast", - "libc", - "miniz_oxide", -] - [[package]] name = "fnv" version = "1.0.6" @@ -1040,12 +956,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -[[package]] -name = "futures" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" - [[package]] name = "futures" version = "0.3.4" @@ -1137,7 +1047,6 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22766cf25d64306bedf0384da004d05c9974ab104fcc4528f1236181c18004c5" dependencies = [ - "futures 0.1.29", "futures-channel", "futures-core", "futures-io", @@ -1149,7 +1058,6 @@ dependencies = [ "proc-macro-hack", "proc-macro-nested", "slab", - "tokio-io", ] [[package]] @@ -1158,8 +1066,8 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0a73299e4718f5452e45980fc1d6957a070abe308d3700b63b8673f47e1c2b3" dependencies = [ - "bytes 0.5.4", - "futures 0.3.4", + "bytes", + "futures", "memchr", "pin-project", ] @@ -1170,8 +1078,8 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe8859feb7140742ed1a2a85a07941100ad2b5f98a421b353931d718a34144d1" dependencies = [ - "bytes 0.5.4", - "futures 0.3.4", + "bytes", + "futures", "memchr", "pin-project", ] @@ -1260,7 +1168,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d5c295d1c0c68e4e42003d75f908f5e16a1edd1cbe0b0d02e4dc2006a384f47" dependencies = [ - "bytes 0.5.4", + "bytes", "fnv", "futures-core", "futures-sink", @@ -1291,7 +1199,7 @@ checksum = "a72b4bd7cbbf0c22190e82f02517f456a6b9be24c25a6827b5802e478b8c2d70" dependencies = [ "base64 0.11.0", "bitflags", - "bytes 0.5.4", + "bytes", "headers-core", "http", "mime 0.3.16", @@ -1384,7 +1292,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b" dependencies = [ - "bytes 0.5.4", + "bytes", "fnv", "itoa", ] @@ -1407,7 +1315,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" dependencies = [ - "bytes 0.5.4", + "bytes", "http", ] @@ -1442,7 +1350,7 @@ version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7b15203263d1faa615f9337d79c1d37959439dc46c2b4faab33286fadc2a1c5" dependencies = [ - "bytes 0.5.4", + "bytes", "futures-channel", "futures-core", "futures-util", @@ -1466,7 +1374,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3adcd308402b9553630734e9c36b77a7e48b3821251ca2493e8cd596763aafaa" dependencies = [ - "bytes 0.5.4", + "bytes", "hyper 0.13.3", "native-tls", "tokio", @@ -1554,9 +1462,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a859057dc563d1388c1e816f98a1892629075fc046ed06e845b883bb8b2916fb" +checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" [[package]] name = "itertools" @@ -1652,35 +1560,24 @@ checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018" [[package]] name = "libp2p" -version = "0.16.2" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bba17ee9cac4bb89de5812159877d9b4f0a993bf41697a5a875940cd1eb71f24" +checksum = "8a261244b8d7ff58f5d62ffa33589eb1ba7733a1dfee0902ad9fdfe62ada7009" dependencies = [ - "bytes 0.5.4", - "futures 0.3.4", + "bytes", + "futures", "lazy_static", "libp2p-core", "libp2p-core-derive", - "libp2p-deflate", "libp2p-dns", - "libp2p-floodsub", - "libp2p-gossipsub", - "libp2p-identify", - "libp2p-kad", "libp2p-mdns", "libp2p-mplex", - "libp2p-noise", - "libp2p-ping", - "libp2p-plaintext", - "libp2p-pnet", "libp2p-secio", "libp2p-swarm", "libp2p-tcp", - "libp2p-uds", - "libp2p-wasm-ext", "libp2p-yamux", + "multihash", "parity-multiaddr", - "parity-multihash", "parking_lot 0.10.0", "pin-project", "smallvec 1.2.0", @@ -1691,9 +1588,9 @@ dependencies = [ name = "libp2p-comit" version = "0.1.0" dependencies = [ - "bytes 0.5.4", + "bytes", "derivative 2.1.0", - "futures 0.3.4", + "futures", "futures_codec 0.4.0", "libp2p", "serde", @@ -1706,22 +1603,23 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.16.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b874594c4b29de1a29f27871feba8e6cd13aa54a8a1e8f8c7cf3dfac5ca287c" +checksum = "1cfe1412f2afe1366a2661abd211bb1a27ee6a664d799071282f4fba997c6858" dependencies = [ "asn1_der", "bs58", "ed25519-dalek", + "either", "fnv", - "futures 0.3.4", + "futures", "futures-timer 3.0.2", "lazy_static", "libsecp256k1", "log 0.4.8", + "multihash", "multistream-select", "parity-multiaddr", - "parity-multihash", "parking_lot 0.10.0", "pin-project", "prost", @@ -1739,132 +1637,36 @@ dependencies = [ [[package]] name = "libp2p-core-derive" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d472e9d522f588805c77801de10b957be84e10f019ca5f869fa1825b15ea9b" +checksum = "a0eeb25d5f152a826eac57c7d1cc3de10d72dc4051e90fe4c0cd139f07a069a3" dependencies = [ "quote 1.0.3", "syn 1.0.17", ] -[[package]] -name = "libp2p-deflate" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e25004d4d9837b44b22c5f1a69be1724a5168fef6cff1716b5176a972c3aa62" -dependencies = [ - "flate2", - "futures 0.3.4", - "libp2p-core", -] - [[package]] name = "libp2p-dns" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b99e552f9939b606eb4b59f7f64d9b01e3f96752f47e350fc3c5fc646ed3f649" +checksum = "647178f8683bf868f7f14d5e5718dbdc2445b9f6b24ce99da96cecd7c5d2d1a6" dependencies = [ - "futures 0.3.4", + "futures", "libp2p-core", "log 0.4.8", ] -[[package]] -name = "libp2p-floodsub" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3234f12e44f9a50351a9807b97fe7de11eb9ae4482370392ba10da6dc90722" -dependencies = [ - "cuckoofilter", - "fnv", - "futures 0.3.4", - "libp2p-core", - "libp2p-swarm", - "prost", - "prost-build", - "rand 0.7.3", - "smallvec 1.2.0", -] - -[[package]] -name = "libp2p-gossipsub" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d46cb3e0841bd951cbf4feae56cdc081e6347836a644fb260c3ec554149b4006" -dependencies = [ - "base64 0.11.0", - "byteorder 1.3.4", - "bytes 0.5.4", - "fnv", - "futures 0.3.4", - "futures_codec 0.3.4", - "libp2p-core", - "libp2p-swarm", - "log 0.4.8", - "lru", - "prost", - "prost-build", - "rand 0.7.3", - "sha2", - "smallvec 1.2.0", - "unsigned-varint", - "wasm-timer", -] - -[[package]] -name = "libp2p-identify" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfeb935a9bd41263e4f3a24b988e9f4a044f3ae89ac284e83c17fe2f84e0d66b" -dependencies = [ - "futures 0.3.4", - "libp2p-core", - "libp2p-swarm", - "log 0.4.8", - "prost", - "prost-build", - "smallvec 1.2.0", - "wasm-timer", -] - -[[package]] -name = "libp2p-kad" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464dc8412978d40f0286be72ed9ab5e0e1386a4a06e7f174526739b5c3c1f041" -dependencies = [ - "arrayvec 0.5.1", - "bytes 0.5.4", - "either", - "fnv", - "futures 0.3.4", - "futures_codec 0.3.4", - "libp2p-core", - "libp2p-swarm", - "log 0.4.8", - "parity-multihash", - "prost", - "prost-build", - "rand 0.7.3", - "sha2", - "smallvec 1.2.0", - "uint", - "unsigned-varint", - "void", - "wasm-timer", -] - [[package]] name = "libp2p-mdns" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881fcfb360c2822db9f0e6bb6f89529621556ed9a8b038313414eda5107334de" +checksum = "b752276b3bea2fca1c291f43cefc8082d8a639bb8f9052cf5adc6accfcd7b44e" dependencies = [ "async-std", "data-encoding", "dns-parser", "either", - "futures 0.3.4", + "futures", "lazy_static", "libp2p-core", "libp2p-swarm", @@ -1878,13 +1680,13 @@ dependencies = [ [[package]] name = "libp2p-mplex" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8507b37ad0eed275efcde67a023c3d85af6c80768b193845b9288e848e1af95" +checksum = "0f317db8c062beecde87a8765ca03784e6f1a55daa5b9868bf60ebf9b9a2b92f" dependencies = [ - "bytes 0.5.4", + "bytes", "fnv", - "futures 0.3.4", + "futures", "futures_codec 0.3.4", "libp2p-core", "log 0.4.8", @@ -1892,83 +1694,15 @@ dependencies = [ "unsigned-varint", ] -[[package]] -name = "libp2p-noise" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15a8a3d71f898beb6f854c8aae27aa1d198e0d1f2e49412261c2d90ef39675a" -dependencies = [ - "curve25519-dalek", - "futures 0.3.4", - "lazy_static", - "libp2p-core", - "log 0.4.8", - "prost", - "prost-build", - "rand 0.7.3", - "sha2", - "snow", - "static_assertions 1.1.0", - "x25519-dalek", - "zeroize", -] - -[[package]] -name = "libp2p-ping" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d22f2f228b3a828dca1cb8aa9fa331e0bc9c36510cb2c1916956e20dc85e8c" -dependencies = [ - "futures 0.3.4", - "libp2p-core", - "libp2p-swarm", - "log 0.4.8", - "rand 0.7.3", - "void", - "wasm-timer", -] - -[[package]] -name = "libp2p-plaintext" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56126a204d7b3382bac163143ff4125a14570b3ba76ba979103d1ae1abed1923" -dependencies = [ - "bytes 0.5.4", - "futures 0.3.4", - "futures_codec 0.3.4", - "libp2p-core", - "log 0.4.8", - "prost", - "prost-build", - "rw-stream-sink", - "unsigned-varint", - "void", -] - -[[package]] -name = "libp2p-pnet" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b916938a8868f75180aeeffcc6a516a922d165e8fa2a90b57bad989d1ccbb57a" -dependencies = [ - "futures 0.3.4", - "log 0.4.8", - "pin-project", - "rand 0.7.3", - "salsa20", - "sha3", -] - [[package]] name = "libp2p-secio" -version = "0.16.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1219e9ecb4945d7331a05f5ffe96a1f6e28051bfa1223d4c60353c251de0354e" +checksum = "74130fa95effb780850ec790b7af777b893108d9b5983ab994b61d93d2eb0336" dependencies = [ "aes-ctr", "ctr", - "futures 0.3.4", + "futures", "hmac", "js-sys", "lazy_static", @@ -1992,13 +1726,14 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.16.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "275471e7c0e88ae004660866cd54f603bd8bd1f4caef541a27f50dd8640c4d4c" +checksum = "a4ec53df8978a5d6d9dac243fb1e3adf004f8b8d28f72e6f2160df34d5f39564" dependencies = [ - "futures 0.3.4", + "futures", "libp2p-core", "log 0.4.8", + "rand 0.7.3", "smallvec 1.2.0", "void", "wasm-timer", @@ -2006,12 +1741,12 @@ dependencies = [ [[package]] name = "libp2p-tcp" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9e80ad4e3535345f3d666554ce347d3100453775611c05c60786bf9a1747a10" +checksum = "e25c9d9c5448c189bba7ecdd1ca23800516281476e82810eff711ef04abaf9eb" dependencies = [ "async-std", - "futures 0.3.4", + "futures", "futures-timer 3.0.2", "get_if_addrs", "ipnet", @@ -2019,39 +1754,13 @@ dependencies = [ "log 0.4.8", ] -[[package]] -name = "libp2p-uds" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d329564a43da9d0e055a5b938633c4a8ceab1f59cec133fbc4647917c07341" -dependencies = [ - "async-std", - "futures 0.3.4", - "libp2p-core", - "log 0.4.8", -] - -[[package]] -name = "libp2p-wasm-ext" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "923581c055bc4b8c5f42d4ce5ef43e52fe5216f1ea4bc26476cb8a966ce6220b" -dependencies = [ - "futures 0.3.4", - "js-sys", - "libp2p-core", - "parity-send-wrapper", - "wasm-bindgen", - "wasm-bindgen-futures", -] - [[package]] name = "libp2p-yamux" -version = "0.16.2" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dac30de24ccde0e67f363d71a125c587bbe6589503f664947e9b084b68a34f1" +checksum = "ee12c49426527908f81ffb6551b95f57149a8ea64f386bb7da3b123cdb9c01ba" dependencies = [ - "futures 0.3.4", + "futures", "libp2p-core", "parking_lot 0.10.0", "thiserror", @@ -2151,11 +1860,11 @@ checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" [[package]] name = "memoffset" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" +checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" dependencies = [ - "rustc_version", + "autocfg 1.0.0", ] [[package]] @@ -2204,15 +1913,6 @@ dependencies = [ "unicase 2.6.0", ] -[[package]] -name = "miniz_oxide" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5" -dependencies = [ - "adler32", -] - [[package]] name = "mio" version = "0.6.21" @@ -2278,15 +1978,15 @@ checksum = "a97fbd5d00e0e37bfb10f433af8f5aaf631e739368dc9fc28286ca81ca4948dc" [[package]] name = "multistream-select" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f938ffe420493e77c8b6cbcc3f282283f68fc889c5dcbc8e51668d5f3a01ad94" +checksum = "74cdcf7cfb3402881e15a1f95116cb033d69b33c83d481e1234777f5ef0c3d2c" dependencies = [ - "bytes 0.5.4", - "futures 0.1.29", + "bytes", + "futures", "log 0.4.8", + "pin-project", "smallvec 1.2.0", - "tokio-io", "unsigned-varint", ] @@ -2534,15 +2234,15 @@ dependencies = [ [[package]] name = "parity-multiaddr" -version = "0.7.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26df883298bc3f4e92528b4c5cc9f806b791955b136da3e5e939ed9de0fd958b" +checksum = "4db35e222f783ef4e6661873f6c165c4eb7b65e0c408349818517d5705c2d7d3" dependencies = [ "arrayref", "bs58", - "byteorder 1.3.4", + "byteorder", "data-encoding", - "parity-multihash", + "multihash", "percent-encoding 2.1.0", "serde", "static_assertions 1.1.0", @@ -2550,21 +2250,6 @@ dependencies = [ "url 2.1.1", ] -[[package]] -name = "parity-multihash" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a1cd2ba02391b81367bec529fb209019d718684fdc8ad6a712c2b536e46f775" -dependencies = [ - "blake2", - "bytes 0.5.4", - "rand 0.7.3", - "sha-1", - "sha2", - "sha3", - "unsigned-varint", -] - [[package]] name = "parity-scale-codec" version = "1.2.0" @@ -2811,7 +2496,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212" dependencies = [ - "bytes 0.5.4", + "bytes", "prost-derive", ] @@ -2821,7 +2506,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02b10678c913ecbd69350e8535c3aef91a8676c0773fc1d7b95cdd196d7f2f26" dependencies = [ - "bytes 0.5.4", + "bytes", "heck", "itertools", "log 0.4.8", @@ -2852,7 +2537,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1834f67c0697c001304b75be76f67add9c89742eda3a085ad8ee0bb38c3417aa" dependencies = [ - "bytes 0.5.4", + "bytes", "prost", ] @@ -2903,16 +2588,6 @@ dependencies = [ "proc-macro2 1.0.10", ] -[[package]] -name = "rand" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" -dependencies = [ - "libc", - "rand 0.4.6", -] - [[package]] name = "rand" version = "0.4.6" @@ -3037,7 +2712,7 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9" dependencies = [ - "byteorder 1.3.4", + "byteorder", "regex-syntax", "utf8-ranges", ] @@ -3064,7 +2739,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02b81e49ddec5109a9dcfc5f2a317ff53377c915e9ae9d4f2fb50914b85614e2" dependencies = [ "base64 0.11.0", - "bytes 0.5.4", + "bytes", "encoding_rs", "futures-core", "futures-util", @@ -3100,7 +2775,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "741ba1704ae21999c00942f9f5944f801e977f54302af346b596287599ad1862" dependencies = [ "cc", - "lazy_static", "libc", "spin", "untrusted", @@ -3167,7 +2841,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020" dependencies = [ - "futures 0.3.4", + "futures", "pin-project", "static_assertions 1.1.0", ] @@ -3184,26 +2858,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" -[[package]] -name = "salsa20" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2324b0e8c3bb9a586a571fdb3136f70e7e2c748de00a78043f86e0cff91f91fe" -dependencies = [ - "byteorder 1.3.4", - "salsa20-core", - "stream-cipher", -] - -[[package]] -name = "salsa20-core" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fe6cc1b9f5a5867853ade63099de70f042f7679e408d1ffe52821c9248e6e69" -dependencies = [ - "stream-cipher", -] - [[package]] name = "schannel" version = "0.1.17" @@ -3442,24 +3096,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc" -[[package]] -name = "snow" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb767eee7d257ba202f0b9b08673bc13b22281632ef45267b19f13100accd2f" -dependencies = [ - "arrayref", - "blake2-rfc", - "chacha20-poly1305-aead", - "rand 0.7.3", - "rand_core 0.5.1", - "ring", - "rustc_version", - "sha2", - "subtle 2.2.2", - "x25519-dalek", -] - [[package]] name = "sourcefile" version = "0.1.4" @@ -3606,18 +3242,6 @@ dependencies = [ "syn 1.0.17", ] -[[package]] -name = "synstructure" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" -dependencies = [ - "proc-macro2 1.0.10", - "quote 1.0.3", - "syn 1.0.17", - "unicode-xid 0.2.0", -] - [[package]] name = "tempfile" version = "3.1.0" @@ -3712,7 +3336,7 @@ version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa5e81d6bc4e67fe889d5783bd2a128ab2e0cfa487e0be16b6a8d177b101616" dependencies = [ - "bytes 0.5.4", + "bytes", "fnv", "futures-core", "iovec", @@ -3725,17 +3349,6 @@ dependencies = [ "tokio-macros", ] -[[package]] -name = "tokio-io" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.29", - "log 0.4.8", -] - [[package]] name = "tokio-macros" version = "0.2.4" @@ -3763,7 +3376,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" dependencies = [ - "bytes 0.5.4", + "bytes", "futures-core", "futures-sink", "log 0.4.8", @@ -3886,7 +3499,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712d261e83e727c8e2dbb75dacac67c36e35db36a958ee504f2164fc052434e1" dependencies = [ "block-cipher-trait", - "byteorder 1.3.4", + "byteorder", "opaque-debug", ] @@ -3908,7 +3521,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e75a4cdd7b87b28840dba13c483b9a88ee6bbf16ba5c951ee1ecfcf723078e0d" dependencies = [ - "byteorder 1.3.4", + "byteorder", "crunchy", "rustc-hex", "static_assertions 1.1.0", @@ -3976,11 +3589,11 @@ checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" [[package]] name = "unsigned-varint" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b7ffb36714206d2f5f05d61a2bc350415c642f2c54433f0ebf829afbe41d570" +checksum = "f38e01ad4b98f042e166c1bf9a13f9873a99d79eaa171ce7ca81e6dd0f895d8a" dependencies = [ - "bytes 0.5.4", + "bytes", "futures_codec 0.3.4", ] @@ -4081,8 +3694,8 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54cd1e2b3eb3539284d88b76a9afcf5e20f2ef2fab74db5b21a1c30d7d945e82" dependencies = [ - "bytes 0.5.4", - "futures 0.3.4", + "bytes", + "futures", "headers", "http", "hyper 0.13.3", @@ -4195,7 +3808,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "324c5e65a08699c9c4334ba136597ab22b85dccd4b65dd1e36ccf8f723a95b54" dependencies = [ - "futures 0.3.4", + "futures", "js-sys", "parking_lot 0.9.0", "pin-utils", @@ -4289,30 +3902,18 @@ dependencies = [ "winapi-build", ] -[[package]] -name = "x25519-dalek" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637ff90c9540fa3073bb577e65033069e4bae7c79d49d74aa3ffdf5342a53217" -dependencies = [ - "curve25519-dalek", - "rand_core 0.5.1", - "zeroize", -] - [[package]] name = "yamux" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d73295bc9d9acf89dd9336b3b5f5b57731ee72b587857dd4312721a0196b48e5" +checksum = "84300bb493cc878f3638b981c62b4632ec1a5c52daaa3036651e8c106d3b55ea" dependencies = [ - "bytes 0.5.4", - "futures 0.3.4", + "futures", "log 0.4.8", "nohash-hasher", "parking_lot 0.10.0", "rand 0.7.3", - "thiserror", + "static_assertions 1.1.0", ] [[package]] @@ -4320,18 +3921,3 @@ name = "zeroize" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" -dependencies = [ - "proc-macro2 1.0.10", - "quote 1.0.3", - "syn 1.0.17", - "synstructure", -] diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index f3fd9f4de8..9b471b2bf5 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -29,7 +29,7 @@ hex = "0.4" http-api-problem = { version = "0.15", features = ["with_warp"] } impl-template = "1.0.0-alpha" lazy_static = "1" -libp2p = { version = "0.16", default-features = false } +libp2p = { version = "0.17", default-features = false, features = ["tcp", "secio", "yamux", "mplex", "mdns", "dns"] } libp2p-comit = { path = "../libp2p-comit" } libsqlite3-sys = { version = ">=0.8.0, <0.13.0", features = ["bundled"] } log = { version = "0.4", features = ["serde"] } diff --git a/cnd/src/network.rs b/cnd/src/network.rs index f8e99b4ed1..05e5539dd2 100644 --- a/cnd/src/network.rs +++ b/cnd/src/network.rs @@ -34,9 +34,10 @@ use async_trait::async_trait; use futures::{ channel::oneshot::{self, Sender}, stream::StreamExt, + Future, }; use libp2p::{ - core::either::{EitherError, EitherOutput}, + core::either::EitherOutput, identity::{ed25519, Keypair}, mdns::Mdns, swarm::{ @@ -70,7 +71,6 @@ type ExpandedSwarm = libp2p::swarm::ExpandedSwarm< EitherOutput, EitherOutput, IntoProtocolsHandlerSelect, - EitherError, >; #[derive(Clone, derivative::Derivative)] @@ -112,12 +112,9 @@ impl Swarm { )?; let mut swarm = SwarmBuilder::new(transport, behaviour, local_peer_id.clone()) - .executor_fn({ - let handle = runtime.handle().clone(); - move |task| { - handle.spawn(task); - } - }) + .executor(Box::new(TokioExecutor { + handle: runtime.handle().clone(), + })) .build(); for addr in settings.network.listen.clone() { @@ -162,6 +159,16 @@ impl Swarm { // spawn the same as is done for Alice. } +struct TokioExecutor { + handle: tokio::runtime::Handle, +} + +impl libp2p::core::Executor for TokioExecutor { + fn exec(&self, future: Pin + Send>>) { + let _ = self.handle.spawn(future); + } +} + struct SwarmWorker { swarm: Arc>, } diff --git a/cnd/src/network/oneshot_behaviour.rs b/cnd/src/network/oneshot_behaviour.rs index c542ca4947..150aaf8a3a 100644 --- a/cnd/src/network/oneshot_behaviour.rs +++ b/cnd/src/network/oneshot_behaviour.rs @@ -1,6 +1,6 @@ use crate::network::oneshot_protocol; use libp2p::{ - core::{ConnectedPoint, Multiaddr, PeerId}, + core::{connection::ConnectionId, Multiaddr, PeerId}, swarm::{ NetworkBehaviour, NetworkBehaviourAction, OneShotHandler, PollParameters, ProtocolsHandler, }, @@ -56,15 +56,20 @@ where Vec::new() // Announce protocol takes care of this. } - fn inject_connected(&mut self, _: PeerId, _: ConnectedPoint) { + fn inject_connected(&mut self, _: &PeerId) { // Do nothing, announce protocol is going to take care of connections. } - fn inject_disconnected(&mut self, _: &PeerId, _: ConnectedPoint) { + fn inject_disconnected(&mut self, _: &PeerId) { // Do nothing, announce protocol is going to take care of connections. } - fn inject_node_event(&mut self, peer: PeerId, event: oneshot_protocol::OutEvent) { + fn inject_event( + &mut self, + peer: PeerId, + _: ConnectionId, + event: oneshot_protocol::OutEvent, + ) { match event { oneshot_protocol::OutEvent::Received(message) => { trace!( diff --git a/cnd/src/network/protocols/announce/behaviour.rs b/cnd/src/network/protocols/announce/behaviour.rs index d15daf0fd4..295bc6a747 100644 --- a/cnd/src/network/protocols/announce/behaviour.rs +++ b/cnd/src/network/protocols/announce/behaviour.rs @@ -10,10 +10,10 @@ use crate::{ swap_protocols::SwapId, }; use libp2p::{ - core::{ConnectedPoint, Multiaddr, PeerId}, + core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId}, swarm::{ - NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction, PollParameters, - ProtocolsHandler, + NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, + PollParameters, ProtocolsHandler, }, }; use std::{ @@ -56,6 +56,7 @@ impl Announce { Entry::Vacant(entry) => { self.events.push_back(NetworkBehaviourAction::DialPeer { peer_id: dial_info.peer_id.clone(), + condition: Default::default(), }); let mut address_hints = VecDeque::new(); @@ -88,10 +89,12 @@ impl Announce { } } ConnectionState::Connected { .. } => { - self.events.push_back(NetworkBehaviourAction::SendEvent { - peer_id: dial_info.peer_id.clone(), - event: OutboundConfig::new(swap_digest), - }); + self.events + .push_back(NetworkBehaviourAction::NotifyHandler { + peer_id: dial_info.peer_id.clone(), + handler: NotifyHandler::Any, + event: OutboundConfig::new(swap_digest), + }); } } } @@ -127,7 +130,16 @@ impl NetworkBehaviour for Announce { .unwrap_or_else(Vec::new) } - fn inject_connected(&mut self, peer_id: PeerId, endpoint: ConnectedPoint) { + fn inject_connected(&mut self, _: &PeerId) {} + + fn inject_disconnected(&mut self, _: &PeerId) {} + + fn inject_connection_established( + &mut self, + peer_id: &PeerId, + _: &ConnectionId, + endpoint: &ConnectedPoint, + ) { tracing::debug!("connected to {} at {:?}", peer_id, endpoint); let address = match endpoint { @@ -141,39 +153,46 @@ impl NetworkBehaviour for Announce { match connection_state { ConnectionState::Connected { mut addresses } => { - addresses.insert(address); + addresses.insert(address.clone()); self.connections - .insert(peer_id, ConnectionState::Connected { addresses }); + .insert(peer_id.clone(), ConnectionState::Connected { addresses }); } ConnectionState::Connecting { pending_events, address_hints: _we_no_longer_care_at_this_stage, } => { for event in pending_events { - self.events.push_back(NetworkBehaviourAction::SendEvent { - peer_id: peer_id.clone(), - event, - }) + self.events + .push_back(NetworkBehaviourAction::NotifyHandler { + peer_id: peer_id.clone(), + handler: NotifyHandler::Any, + event, + }) } let mut addresses = HashSet::new(); - addresses.insert(address); + addresses.insert(address.clone()); self.connections - .insert(peer_id, ConnectionState::Connected { addresses }); + .insert(peer_id.clone(), ConnectionState::Connected { addresses }); } } } Entry::Vacant(entry) => { let mut addresses = HashSet::new(); - addresses.insert(address); + addresses.insert(address.clone()); entry.insert(ConnectionState::Connected { addresses }); } } } - fn inject_disconnected(&mut self, peer_id: &PeerId, endpoint: ConnectedPoint) { + fn inject_connection_closed( + &mut self, + peer_id: &PeerId, + _: &ConnectionId, + endpoint: &ConnectedPoint, + ) { tracing::debug!("disconnected from {} at {:?}", peer_id, endpoint); let address = match endpoint { @@ -192,7 +211,7 @@ impl NetworkBehaviour for Announce { } } - fn inject_node_event(&mut self, peer_id: PeerId, event: HandlerEvent) { + fn inject_event(&mut self, peer_id: PeerId, _: ConnectionId, event: HandlerEvent) { match event { HandlerEvent::ReceivedConfirmation(confirmed) => { self.events.push_back(NetworkBehaviourAction::GenerateEvent( diff --git a/libp2p-comit/Cargo.toml b/libp2p-comit/Cargo.toml index 2214bccef9..23ca8e891a 100644 --- a/libp2p-comit/Cargo.toml +++ b/libp2p-comit/Cargo.toml @@ -8,9 +8,9 @@ description = "Implementation of the COMIT messaging protocol" [dependencies] bytes = "0.5" derivative = "2" -futures = { version = "0.3", features = ["alloc", "io-compat"] } +futures = { version = "0.3", default-features = false } futures_codec = "0.4" -libp2p = { version = "0.16", default-features = false } +libp2p = { version = "0.17", default-features = false } serde = { version = "1", features = ["derive"] } serde_json = "1.0" strum_macros = "0.18" diff --git a/libp2p-comit/src/behaviour.rs b/libp2p-comit/src/behaviour.rs index 86f77aeab7..c463fad6e8 100644 --- a/libp2p-comit/src/behaviour.rs +++ b/libp2p-comit/src/behaviour.rs @@ -10,8 +10,10 @@ use futures::{ Future, StreamExt, TryFutureExt, }; use libp2p::{ - core::{ConnectedPoint, Multiaddr, PeerId}, - swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}, + core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId}, + swarm::{ + DialPeerCondition, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, + }, }; use std::{ collections::{hash_map::Entry, HashMap, HashSet}, @@ -77,7 +79,10 @@ impl Comit { match self.connections.entry(peer_id.clone()) { Entry::Vacant(entry) => { self.events_sender - .unbounded_send(NetworkBehaviourAction::DialPeer { peer_id }) + .unbounded_send(NetworkBehaviourAction::DialPeer { + peer_id, + condition: DialPeerCondition::Disconnected, + }) .expect("we own the receiver"); let address_hints = address_hint @@ -112,8 +117,9 @@ impl Comit { } ConnectionState::Connected { .. } => { self.events_sender - .unbounded_send(NetworkBehaviourAction::SendEvent { + .unbounded_send(NetworkBehaviourAction::NotifyHandler { peer_id, + handler: NotifyHandler::Any, event: ProtocolInEvent::Message(OutboundMessage::Request(request)), }) .expect("we own the receiver"); @@ -170,7 +176,16 @@ impl NetworkBehaviour for Comit { .unwrap_or_else(Vec::new) } - fn inject_connected(&mut self, peer_id: PeerId, endpoint: ConnectedPoint) { + fn inject_connected(&mut self, _: &PeerId) {} + + fn inject_disconnected(&mut self, _: &PeerId) {} + + fn inject_connection_established( + &mut self, + peer_id: &PeerId, + _: &ConnectionId, + endpoint: &ConnectedPoint, + ) { tracing::debug!("connected to {} at {:?}", peer_id, endpoint); let address = match endpoint { @@ -184,9 +199,9 @@ impl NetworkBehaviour for Comit { match connection_state { ConnectionState::Connected { mut addresses } => { - addresses.insert(address); + addresses.insert(address.clone()); self.connections - .insert(peer_id, ConnectionState::Connected { addresses }); + .insert(peer_id.clone(), ConnectionState::Connected { addresses }); } ConnectionState::Connecting { pending_events, @@ -194,30 +209,36 @@ impl NetworkBehaviour for Comit { } => { for event in pending_events { self.events_sender - .unbounded_send(NetworkBehaviourAction::SendEvent { + .unbounded_send(NetworkBehaviourAction::NotifyHandler { peer_id: peer_id.clone(), + handler: NotifyHandler::Any, event, }) .expect("we own the receiver"); } let mut addresses = HashSet::new(); - addresses.insert(address); + addresses.insert(address.clone()); self.connections - .insert(peer_id, ConnectionState::Connected { addresses }); + .insert(peer_id.clone(), ConnectionState::Connected { addresses }); } } } Entry::Vacant(entry) => { let mut addresses = HashSet::new(); - addresses.insert(address); + addresses.insert(address.clone()); entry.insert(ConnectionState::Connected { addresses }); } } } - fn inject_disconnected(&mut self, peer_id: &PeerId, endpoint: ConnectedPoint) { + fn inject_connection_closed( + &mut self, + peer_id: &PeerId, + _: &ConnectionId, + endpoint: &ConnectedPoint, + ) { tracing::debug!("disconnected from {} at {:?}", peer_id, endpoint); let address = match endpoint { @@ -236,7 +257,7 @@ impl NetworkBehaviour for Comit { } } - fn inject_node_event(&mut self, peer: PeerId, event: ProtocolOutEvent) { + fn inject_event(&mut self, peer: PeerId, _connection: ConnectionId, event: ProtocolOutEvent) { match event { ProtocolOutEvent::Message(InboundMessage::Request(request)) => { self.events_sender diff --git a/libp2p-comit/src/handler.rs b/libp2p-comit/src/handler.rs index ab8793f005..54c9ee55fa 100644 --- a/libp2p-comit/src/handler.rs +++ b/libp2p-comit/src/handler.rs @@ -90,6 +90,12 @@ pub enum ProtocolInEvent { Message(OutboundMessage), } +impl Clone for ProtocolInEvent { + fn clone(&self) -> Self { + unimplemented!("we cannot implement clone because we have channels in the messages") + } +} + /// Different kinds of `OutboundOpenInfo` that we may want to pass when emitted /// an instance of `ProtocolsHandlerEvent::OutboundSubstreamRequest`. #[derive(Debug)] From cf917082bf6243185b2a5649b0ed1a2a042e9796 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2020 14:12:35 +0000 Subject: [PATCH 38/88] Bump serde_json from 1.0.50 to 1.0.51 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.50 to 1.0.51. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.50...v1.0.51) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5b61ee4c1d..6ff1269fb4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3321,9 +3321,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.50" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78a7a12c167809363ec3bd7329fc0a3369056996de43c4b37ef3cd54a6ce4867" +checksum = "da07b57ee2623368351e9a0488bb0b261322a15a6e0ae53e243cbdc0f4208da9" dependencies = [ "itoa", "ryu", From 141558a65fc0975b19d6d99767c7cd316480a94f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2020 14:12:49 +0000 Subject: [PATCH 39/88] Bump @types/jest from 25.1.4 to 25.2.1 in /api_tests Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 25.1.4 to 25.2.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 56 ++++++------------------------------------ 2 files changed, 9 insertions(+), 49 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 94f2275fd6..61056022d3 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -25,7 +25,7 @@ "@types/chai-json-schema": "^1.4.5", "@types/chai-subset": "^1.3.3", "@types/jasmine": "^3.5.10", - "@types/jest": "^25.1.4", + "@types/jest": "^25.2.1", "@types/log4js": "^2.3.5", "@types/node": "^13.9", "@types/rimraf": "^3.0.0", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index ee98fa2aa9..a5b523926e 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -325,16 +325,6 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" -"@jest/types@^25.1.0": - version "25.1.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.1.0.tgz#b26831916f0d7c381e11dbb5e103a72aed1b4395" - integrity sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^1.1.1" - "@types/yargs" "^15.0.0" - chalk "^3.0.0" - "@jest/types@^25.2.6": version "25.2.6" resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.2.6.tgz#c12f44af9bed444438091e4b59e7ed05f8659cb6" @@ -548,13 +538,13 @@ resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.5.10.tgz#a1a41012012b5da9d4b205ba9eba58f6cce2ab7b" integrity sha512-3F8qpwBAiVc5+HPJeXJpbrl+XjawGmciN5LgiO7Gv1pl1RHtjoMNqZpqEksaPJW05ViKe8snYInRs6xB25Xdew== -"@types/jest@^25.1.4": - version "25.1.4" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-25.1.4.tgz#9e9f1e59dda86d3fd56afce71d1ea1b331f6f760" - integrity sha512-QDDY2uNAhCV7TMCITrxz+MRk1EizcsevzfeS6LykIlq2V1E5oO4wXG8V2ZEd9w7Snxeeagk46YbMgZ8ESHx3sw== +"@types/jest@^25.2.1": + version "25.2.1" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-25.2.1.tgz#9544cd438607955381c1bdbdb97767a249297db5" + integrity sha512-msra1bCaAeEdkSyA0CZ6gW1ukMIvZ5YoJkdXw/qhQdsuuDlFTcEUrUw8CLCPt2rVRUfXlClVvK2gvPs9IokZaA== dependencies: - jest-diff "^25.1.0" - pretty-format "^25.1.0" + jest-diff "^25.2.1" + pretty-format "^25.2.1" "@types/log4js@^2.3.5": version "2.3.5" @@ -1825,11 +1815,6 @@ detect-newline@^3.0.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== -diff-sequences@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.1.0.tgz#fd29a46f1c913fd66c22645dc75bffbe43051f32" - integrity sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw== - diff-sequences@^25.2.6: version "25.2.6" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" @@ -2845,17 +2830,7 @@ jest-config@^25.2.6: pretty-format "^25.2.6" realpath-native "^2.0.0" -jest-diff@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.1.0.tgz#58b827e63edea1bc80c1de952b80cec9ac50e1ad" - integrity sha512-nepXgajT+h017APJTreSieh4zCqnSHEJ1iT8HDlewu630lSJ4Kjjr9KNzm+kzGwwcpsDE6Snx1GJGzzsefaEHw== - dependencies: - chalk "^3.0.0" - diff-sequences "^25.1.0" - jest-get-type "^25.1.0" - pretty-format "^25.1.0" - -jest-diff@^25.2.6: +jest-diff@^25.2.1, jest-diff@^25.2.6: version "25.2.6" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.2.6.tgz#a6d70a9ab74507715ea1092ac513d1ab81c1b5e7" integrity sha512-KuadXImtRghTFga+/adnNrv9s61HudRMR7gVSbP35UKZdn4IK2/0N0PpGZIqtmllK9aUyye54I3nu28OYSnqOg== @@ -2907,11 +2882,6 @@ jest-environment-node@^25.2.6: jest-util "^25.2.6" semver "^6.3.0" -jest-get-type@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.1.0.tgz#1cfe5fc34f148dc3a8a3b7275f6b9ce9e2e8a876" - integrity sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw== - jest-get-type@^25.2.6: version "25.2.6" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877" @@ -4059,17 +4029,7 @@ prettier@^2.0.2: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.2.tgz#1ba8f3eb92231e769b7fcd7cb73ae1b6b74ade08" integrity sha512-5xJQIPT8BraI7ZnaDwSbu5zLrB6vvi8hVV58yHQ+QK64qrY40dULy0HSRlQ2/2IdzeBpjhDkqdcFBnFeDEMVdg== -pretty-format@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.1.0.tgz#ed869bdaec1356fc5ae45de045e2c8ec7b07b0c8" - integrity sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ== - dependencies: - "@jest/types" "^25.1.0" - ansi-regex "^5.0.0" - ansi-styles "^4.0.0" - react-is "^16.12.0" - -pretty-format@^25.2.6: +pretty-format@^25.2.1, pretty-format@^25.2.6: version "25.2.6" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.2.6.tgz#542a1c418d019bbf1cca2e3620443bc1323cb8d7" integrity sha512-DEiWxLBaCHneffrIT4B+TpMvkV9RNvvJrd3lY9ew1CEQobDzEXmYT1mg0hJhljZty7kCc10z13ohOFAE8jrUDg== From 29fa852b2711d70355843e6be4e0a87771da2708 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2020 14:13:02 +0000 Subject: [PATCH 40/88] Bump tokio from 0.2.14 to 0.2.16 Bumps [tokio](https://github.com/tokio-rs/tokio) from 0.2.14 to 0.2.16. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-0.2.14...tokio-0.2.16) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5b61ee4c1d..52832e4180 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3709,9 +3709,9 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2751672f9da075d045c67fdb0068be9850ab7b231fa77bb51d6fd35da9c0bb0d" +checksum = "ee5a0dd887e37d37390c13ff8ac830f992307fe30a1fff0ab8427af67211ba28" dependencies = [ "bytes 0.5.4", "fnv", From e54bab2a32d647850fde74ed1f14ae8a23dd3c88 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2020 14:13:17 +0000 Subject: [PATCH 41/88] Bump ts-node from 8.8.1 to 8.8.2 in /api_tests Bumps [ts-node](https://github.com/TypeStrong/ts-node) from 8.8.1 to 8.8.2. - [Release notes](https://github.com/TypeStrong/ts-node/releases) - [Commits](https://github.com/TypeStrong/ts-node/compare/v8.8.1...v8.8.2) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 94f2275fd6..c6c70d2652 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -59,7 +59,7 @@ "temp-write": "^4.0.0", "tmp": "^0.1.0", "ts-jest": "^25.3.0", - "ts-node": "^8.8.1", + "ts-node": "^8.8.2", "tslint": "^6.1.1", "tslint-config-prettier": "^1.18.0", "tslint-no-unused-expression-chai": "^0.1.4", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index ee98fa2aa9..fb76cd0595 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -4986,10 +4986,10 @@ ts-jest@^25.3.0: semver "6.x" yargs-parser "^18.1.1" -ts-node@^8.8.1: - version "8.8.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.8.1.tgz#7c4d3e9ed33aa703b64b28d7f9d194768be5064d" - integrity sha512-10DE9ONho06QORKAaCBpPiFCdW+tZJuY/84tyypGtl6r+/C7Asq0dhqbRZURuUlLQtZxxDvT8eoj8cGW0ha6Bg== +ts-node@^8.8.2: + version "8.8.2" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.8.2.tgz#0b39e690bee39ea5111513a9d2bcdc0bc121755f" + integrity sha512-duVj6BpSpUpD/oM4MfhO98ozgkp3Gt9qIp3jGxwU2DFvl/3IRaEAvbLa8G60uS7C77457e/m5TMowjedeRxI1Q== dependencies: arg "^4.1.0" diff "^4.0.1" From 76c533c4682da30c35f0c515b82e77be2eedf09c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2020 15:30:25 +0000 Subject: [PATCH 42/88] Bump @types/node from 13.9.8 to 13.11.0 in /api_tests Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 13.9.8 to 13.11.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 61056022d3..8a6e367bd5 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -27,7 +27,7 @@ "@types/jasmine": "^3.5.10", "@types/jest": "^25.2.1", "@types/log4js": "^2.3.5", - "@types/node": "^13.9", + "@types/node": "^13.11", "@types/rimraf": "^3.0.0", "@types/tail": "^2.0.0", "@types/tmp": "^0.1.0", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index a5b523926e..1225a7b403 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -563,10 +563,10 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== -"@types/node@*", "@types/node@^13.9": - version "13.9.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.8.tgz#09976420fc80a7a00bf40680c63815ed8c7616f4" - integrity sha512-1WgO8hsyHynlx7nhP1kr0OFzsgKz5XDQL+Lfc3b1Q3qIln/n8cKD4m09NJ0+P1Rq7Zgnc7N0+SsMnoD1rEb0kA== +"@types/node@*", "@types/node@^13.11": + version "13.11.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.0.tgz#390ea202539c61c8fa6ba4428b57e05bc36dc47b" + integrity sha512-uM4mnmsIIPK/yeO+42F2RQhGUIs39K2RFmugcJANppXe6J1nvH87PvzPZYpza7Xhhs8Yn9yIAVdLZ84z61+0xQ== "@types/node@^10.1.0": version "10.17.17" From a5f7341cb87733d6f8c3665e4e1491306abdd04d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2020 16:37:10 +0000 Subject: [PATCH 43/88] Bump serde from 1.0.105 to 1.0.106 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.105 to 1.0.106. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.105...v1.0.106) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 160f3a35a5..8ac2be419b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3290,9 +3290,9 @@ checksum = "a0eddf2e8f50ced781f288c19f18621fa72a3779e3cb58dbf23b07469b0abeb4" [[package]] name = "serde" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e707fbbf255b8fc8c3b99abb91e7257a622caeb20a9818cbadbeeede4e0932ff" +checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399" dependencies = [ "serde_derive", ] @@ -3310,9 +3310,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8" +checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" dependencies = [ "proc-macro2 1.0.10", "quote 1.0.3", From bf5fc42baddb5603347df0d17657d335ad196f1a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2020 16:37:16 +0000 Subject: [PATCH 44/88] Bump ts-jest from 25.3.0 to 25.3.1 in /api_tests Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 25.3.0 to 25.3.1. - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/master/CHANGELOG.md) - [Commits](https://github.com/kulshekhar/ts-jest/compare/v25.3.0...v25.3.1) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 35 ++++++++++++++++++----------------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 77f8d61f9c..1d4df62c3b 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -58,7 +58,7 @@ "tail": "^2.0.3", "temp-write": "^4.0.0", "tmp": "^0.1.0", - "ts-jest": "^25.3.0", + "ts-jest": "^25.3.1", "ts-node": "^8.8.2", "tslint": "^6.1.1", "tslint-config-prettier": "^1.18.0", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index b4df417d5c..fa254d1c62 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -3419,6 +3419,14 @@ methods@^1.1.1, methods@^1.1.2, methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= +micromatch@4.x, micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -3438,14 +3446,6 @@ micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" -micromatch@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" - integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== - dependencies: - braces "^3.0.1" - picomatch "^2.0.5" - mime-db@1.40.0: version "1.40.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" @@ -4930,10 +4930,10 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" -ts-jest@^25.3.0: - version "25.3.0" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-25.3.0.tgz#c12d34573cbe34d49f10567940e44fd19d1c9178" - integrity sha512-qH/uhaC+AFDU9JfAueSr0epIFJkGMvUPog4FxSEVAtPOur1Oni5WBJMiQIkfHvc7PviVRsnlVLLY2I6221CQew== +ts-jest@^25.3.1: + version "25.3.1" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-25.3.1.tgz#58e2ed3506e4e4487c0b9b532846a5cade9656ba" + integrity sha512-O53FtKguoMUByalAJW+NWEv7c4tus5ckmhfa7/V0jBb2z8v5rDSLFC1Ate7wLknYPC1euuhY6eJjQq4FtOZrkg== dependencies: bs-logger "0.x" buffer-from "1.x" @@ -4941,10 +4941,11 @@ ts-jest@^25.3.0: json5 "2.x" lodash.memoize "4.x" make-error "1.x" + micromatch "4.x" mkdirp "1.x" resolve "1.x" semver "6.x" - yargs-parser "^18.1.1" + yargs-parser "18.x" ts-node@^8.8.2: version "8.8.2" @@ -5313,10 +5314,10 @@ yallist@^3.0.0, yallist@^3.0.3: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yargs-parser@^18.1.1: - version "18.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.1.tgz#bf7407b915427fc760fcbbccc6c82b4f0ffcbd37" - integrity sha512-KRHEsOM16IX7XuLnMOqImcPNbLVXMNHYAoFc3BKR8Ortl5gzDbtXvvEoGx9imk5E+X1VeNKNlcHr8B8vi+7ipA== +yargs-parser@18.x, yargs-parser@^18.1.1: + version "18.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.2.tgz#2f482bea2136dbde0861683abea7756d30b504f1" + integrity sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ== dependencies: camelcase "^5.0.0" decamelize "^1.2.0" From 8fa7eacc6f9f556a8424e1723da0aae85c4ef3f4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2020 17:28:17 +0000 Subject: [PATCH 45/88] Bump jest from 25.2.6 to 25.2.7 in /api_tests Bumps [jest](https://github.com/facebook/jest) from 25.2.6 to 25.2.7. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/compare/v25.2.6...v25.2.7) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 158 ++++++++++++++++++++--------------------- 2 files changed, 80 insertions(+), 80 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 155abc07c1..0fb9cc2d79 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -48,7 +48,7 @@ "ethers": "^4.0.46", "get-port": "^5.1.1", "jasmine": "^3.5.0", - "jest": "^25.2.6", + "jest": "^25.2.7", "js-sha256": "^0.9.0", "log4js": "^6.1.2", "p-timeout": "^3.2.0", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index ab5d1050b9..a0c636aca1 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -189,10 +189,10 @@ jest-util "^25.2.6" slash "^3.0.0" -"@jest/core@^25.2.6": - version "25.2.6" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-25.2.6.tgz#4bcb2919268d92c3813e1ff7c97443cde7a2873a" - integrity sha512-uMwUtpS4CWc7SadHcHEQ3VdrZ8A5u+UVbHIVUqhXcxlQ/bBC5+/T9IJGSu0o8e+/EXmFrTtl4zGr1nRPFq0Wlg== +"@jest/core@^25.2.7": + version "25.2.7" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-25.2.7.tgz#58d697687e94ee644273d15e4eed6a20e27187cd" + integrity sha512-Nd6ELJyR+j0zlwhzkfzY70m04hAur0VnMwJXVe4VmmD/SaQ6DEyal++ERQ1sgyKIKKEqRuui6k/R0wHLez4P+g== dependencies: "@jest/console" "^25.2.6" "@jest/reporters" "^25.2.6" @@ -204,18 +204,18 @@ exit "^0.1.2" graceful-fs "^4.2.3" jest-changed-files "^25.2.6" - jest-config "^25.2.6" + jest-config "^25.2.7" jest-haste-map "^25.2.6" jest-message-util "^25.2.6" jest-regex-util "^25.2.6" jest-resolve "^25.2.6" - jest-resolve-dependencies "^25.2.6" - jest-runner "^25.2.6" - jest-runtime "^25.2.6" - jest-snapshot "^25.2.6" + jest-resolve-dependencies "^25.2.7" + jest-runner "^25.2.7" + jest-runtime "^25.2.7" + jest-snapshot "^25.2.7" jest-util "^25.2.6" jest-validate "^25.2.6" - jest-watcher "^25.2.6" + jest-watcher "^25.2.7" micromatch "^4.0.2" p-each-series "^2.1.0" realpath-native "^2.0.0" @@ -293,15 +293,15 @@ "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^25.2.6": - version "25.2.6" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-25.2.6.tgz#62026007610b0323e646ad70db59c69c7ed4785c" - integrity sha512-6sHqVeXbEapfxoGb77NKCywNn9jc4WlIPtFqhwCKGhigGnpl42AuyLxclRWxbFx+V63ozzfjnemYxqHlkcoikQ== +"@jest/test-sequencer@^25.2.7": + version "25.2.7" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-25.2.7.tgz#e4331f7b4850e34289b9a5c8ec8a2c03b400da8f" + integrity sha512-s2uYGOXONDSTJQcZJ9A3Zkg3hwe53RlX1HjUNqjUy3HIqwgwCKJbnAKYsORPbhxXi3ARMKA7JNBi9arsTxXoYw== dependencies: "@jest/test-result" "^25.2.6" jest-haste-map "^25.2.6" - jest-runner "^25.2.6" - jest-runtime "^25.2.6" + jest-runner "^25.2.7" + jest-runtime "^25.2.7" "@jest/transform@^25.2.6": version "25.2.6" @@ -1991,15 +1991,15 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/expect/-/expect-25.2.6.tgz#85f022097e8ed3c5666c1bd7f9076d3a790a8a47" - integrity sha512-hMqqX3OX5Erw7CLoXXcawqi6xThhz/rYk+vEufhoCAyzDC2PW99ypYc/pvcgKjyuwbOB1wjqqClmwvlOL36Inw== +expect@^25.2.7: + version "25.2.7" + resolved "https://registry.yarnpkg.com/expect/-/expect-25.2.7.tgz#509b79f47502835f4071ff3ecc401f2eaecca709" + integrity sha512-yA+U2Ph0MkMsJ9N8q5hs9WgWI6oJYfecdXta6LkP/alY/jZZL1MHlJ2wbLh60Ucqf3G+51ytbqV3mlGfmxkpNw== dependencies: "@jest/types" "^25.2.6" ansi-styles "^4.0.0" jest-get-type "^25.2.6" - jest-matcher-utils "^25.2.6" + jest-matcher-utils "^25.2.7" jest-message-util "^25.2.6" jest-regex-util "^25.2.6" @@ -2787,32 +2787,32 @@ jest-changed-files@^25.2.6: execa "^3.2.0" throat "^5.0.0" -jest-cli@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-25.2.6.tgz#972356e70663e9b4faa07c507704441786e524e8" - integrity sha512-i31HkagK5veFOUg1ZqxxfP+ZeKDggmI5qZhK6/Cp0ohuaKFQdtS43AqqnXg13JWKCV0E38Nu/K0W4NsFlXLNEA== +jest-cli@^25.2.7: + version "25.2.7" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-25.2.7.tgz#515b61fee402c397ffa8d570532f7b039c3159f4" + integrity sha512-OOAZwY4Jkd3r5WhVM5L3JeLNFaylvHUczMLxQDVLrrVyb1Cy+DNJ6MVsb5TLh6iBklB42m5TOP+IbOgKGGOtMw== dependencies: - "@jest/core" "^25.2.6" + "@jest/core" "^25.2.7" "@jest/test-result" "^25.2.6" "@jest/types" "^25.2.6" chalk "^3.0.0" exit "^0.1.2" import-local "^3.0.2" is-ci "^2.0.0" - jest-config "^25.2.6" + jest-config "^25.2.7" jest-util "^25.2.6" jest-validate "^25.2.6" prompts "^2.0.1" realpath-native "^2.0.0" yargs "^15.3.1" -jest-config@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-25.2.6.tgz#fecff70f9fb083db1a25e7a624c3cd3035d01546" - integrity sha512-R82bUaOHU/2nPSXmvrwLZtQRRr5x1V7qEXE0i4Pybv55XDqVl2/yKNBkYPneG3uSL3n5f6EJeP0/9HNxQu/SZg== +jest-config@^25.2.7: + version "25.2.7" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-25.2.7.tgz#a14e5b96575987ce913dd9fc20ac8cd4b35a8c29" + integrity sha512-rIdPPXR6XUxi+7xO4CbmXXkE6YWprvlKc4kg1SrkCL2YV5m/8MkHstq9gBZJ19Qoa3iz/GP+0sTG/PcIwkFojg== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^25.2.6" + "@jest/test-sequencer" "^25.2.7" "@jest/types" "^25.2.6" babel-jest "^25.2.6" chalk "^3.0.0" @@ -2821,7 +2821,7 @@ jest-config@^25.2.6: jest-environment-jsdom "^25.2.6" jest-environment-node "^25.2.6" jest-get-type "^25.2.6" - jest-jasmine2 "^25.2.6" + jest-jasmine2 "^25.2.7" jest-regex-util "^25.2.6" jest-resolve "^25.2.6" jest-util "^25.2.6" @@ -2906,10 +2906,10 @@ jest-haste-map@^25.2.6: optionalDependencies: fsevents "^2.1.2" -jest-jasmine2@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-25.2.6.tgz#f0de8e922de421444e34be23a66e8887fee9b2a1" - integrity sha512-0429YtThQjol9EElh0mLMsfMBB++yFCjWuGv3xNK4QPrvralJRlpHbuhfSVaOsHC91RrRBbKfM7jSA+FiVG+Jg== +jest-jasmine2@^25.2.7: + version "25.2.7" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-25.2.7.tgz#55ff87f8f462ef0e2f16fd19430b8be8bcebef0e" + integrity sha512-HeQxEbonp8fUvik9jF0lkU9ab1u5TQdIb7YSU9Fj7SxWtqHNDGyCpF6ZZ3r/5yuertxi+R95Ba9eA91GMQ38eA== dependencies: "@babel/traverse" "^7.1.0" "@jest/environment" "^25.2.6" @@ -2918,13 +2918,13 @@ jest-jasmine2@^25.2.6: "@jest/types" "^25.2.6" chalk "^3.0.0" co "^4.6.0" - expect "^25.2.6" + expect "^25.2.7" is-generator-fn "^2.0.0" jest-each "^25.2.6" - jest-matcher-utils "^25.2.6" + jest-matcher-utils "^25.2.7" jest-message-util "^25.2.6" - jest-runtime "^25.2.6" - jest-snapshot "^25.2.6" + jest-runtime "^25.2.7" + jest-snapshot "^25.2.7" jest-util "^25.2.6" pretty-format "^25.2.6" throat "^5.0.0" @@ -2937,10 +2937,10 @@ jest-leak-detector@^25.2.6: jest-get-type "^25.2.6" pretty-format "^25.2.6" -jest-matcher-utils@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.2.6.tgz#a5156c1daa16e13ff6c55117f798b285a294a3e6" - integrity sha512-+6IbC98ZBw3X7hsfUvt+7VIYBdI0FEvhSBjWo9XTHOc1KAAHDsrSHdeyHH/Su0r/pf4OEGuWRRLPnjkhS2S19A== +jest-matcher-utils@^25.2.7: + version "25.2.7" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.2.7.tgz#53fad3c11fc42e92e374306df543026712c957a3" + integrity sha512-jNYmKQPRyPO3ny0KY1I4f0XW4XnpJ3Nx5ovT4ik0TYDOYzuXJW40axqOyS61l/voWbVT9y9nZ1THL1DlpaBVpA== dependencies: chalk "^3.0.0" jest-diff "^25.2.6" @@ -2977,14 +2977,14 @@ jest-regex-util@^25.2.6: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.2.6.tgz#d847d38ba15d2118d3b06390056028d0f2fd3964" integrity sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw== -jest-resolve-dependencies@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-25.2.6.tgz#c42272ff49e6be83a8ed9366b4c6e563a1e5604c" - integrity sha512-SJeRBCDZzXVy/DjbwBH3KzjxPw5Q/j3foDkWZYu2GIa6SHqy34qVaw1mL7SJg9r6GApwjIoKP6fGwU6c/afg0A== +jest-resolve-dependencies@^25.2.7: + version "25.2.7" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-25.2.7.tgz#9ca4c62d67cce031a27fa5d5705b4b5b5c029d23" + integrity sha512-IrnMzCAh11Xd2gAOJL+ThEW6QO8DyqNdvNkQcaCticDrOAr9wtKT7yT6QBFFjqKFgjjvaVKDs59WdgUhgYnHnQ== dependencies: "@jest/types" "^25.2.6" jest-regex-util "^25.2.6" - jest-snapshot "^25.2.6" + jest-snapshot "^25.2.7" jest-resolve@^25.2.6: version "25.2.6" @@ -2998,10 +2998,10 @@ jest-resolve@^25.2.6: realpath-native "^2.0.0" resolve "^1.15.1" -jest-runner@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-25.2.6.tgz#5ee1607e66890ccd798695cfaa708e322087c50b" - integrity sha512-sN45p3jxvpsG7UjeQFqyC+JR5+THLrIT9oXAHwQQIDWfpmZBFko2RROn1fvdQNWhuPzDeUf/oHykbhNRGo9eWg== +jest-runner@^25.2.7: + version "25.2.7" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-25.2.7.tgz#3676c01dc0104caa8a0ebb8507df382c88f2a1e2" + integrity sha512-RFEr71nMrtNwcpoHzie5+fe1w3JQCGMyT2xzNwKe3f88+bK+frM2o1v24gEcPxQ2QqB3COMCe2+1EkElP+qqqQ== dependencies: "@jest/console" "^25.2.6" "@jest/environment" "^25.2.6" @@ -3010,23 +3010,23 @@ jest-runner@^25.2.6: chalk "^3.0.0" exit "^0.1.2" graceful-fs "^4.2.3" - jest-config "^25.2.6" + jest-config "^25.2.7" jest-docblock "^25.2.6" jest-haste-map "^25.2.6" - jest-jasmine2 "^25.2.6" + jest-jasmine2 "^25.2.7" jest-leak-detector "^25.2.6" jest-message-util "^25.2.6" jest-resolve "^25.2.6" - jest-runtime "^25.2.6" + jest-runtime "^25.2.7" jest-util "^25.2.6" jest-worker "^25.2.6" source-map-support "^0.5.6" throat "^5.0.0" -jest-runtime@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-25.2.6.tgz#417e8d548c92bd10e659393a3bd5aa8cbdd71e6d" - integrity sha512-u0iNjO7VvI46341igiQP/bnm1TwdXV6IjVEo7DMVqRbTDTz4teTNOUXChuSMdoyjQcfJ3zmI7/jVktUpjnZhYw== +jest-runtime@^25.2.7: + version "25.2.7" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-25.2.7.tgz#cb10e695d036671a83aec3a3803163c354043ac9" + integrity sha512-Gw3X8KxTTFylu2T/iDSNKRUQXQiPIYUY0b66GwVYa7W8wySkUljKhibQHSq0VhmCAN7vRBEQjlVQ+NFGNmQeBw== dependencies: "@jest/console" "^25.2.6" "@jest/environment" "^25.2.6" @@ -3040,13 +3040,13 @@ jest-runtime@^25.2.6: exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.2.3" - jest-config "^25.2.6" + jest-config "^25.2.7" jest-haste-map "^25.2.6" jest-message-util "^25.2.6" jest-mock "^25.2.6" jest-regex-util "^25.2.6" jest-resolve "^25.2.6" - jest-snapshot "^25.2.6" + jest-snapshot "^25.2.7" jest-util "^25.2.6" jest-validate "^25.2.6" realpath-native "^2.0.0" @@ -3059,19 +3059,19 @@ jest-serializer@^25.2.6: resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-25.2.6.tgz#3bb4cc14fe0d8358489dbbefbb8a4e708ce039b7" integrity sha512-RMVCfZsezQS2Ww4kB5HJTMaMJ0asmC0BHlnobQC6yEtxiFKIxohFA4QSXSabKwSggaNkqxn6Z2VwdFCjhUWuiQ== -jest-snapshot@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-25.2.6.tgz#a3b99fa6fea4955b6a5fcb38c657e4daaba363f9" - integrity sha512-Zw/Ba6op5zInjPHoA2xGUrCw1G/iTHOGMhV02PzlrWhF9uTl2/jjk/bpOMkPaW8EyylmQbjQ2oj4jCfYwpDKng== +jest-snapshot@^25.2.7: + version "25.2.7" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-25.2.7.tgz#7eeafeef4dcbda1c47c8503d2bf5212b6430aac6" + integrity sha512-Rm8k7xpGM4tzmYhB6IeRjsOMkXaU8/FOz5XlU6oYwhy53mq6txVNqIKqN1VSiexzpC80oWVxVDfUDt71M6XPOA== dependencies: "@babel/types" "^7.0.0" "@jest/types" "^25.2.6" "@types/prettier" "^1.19.0" chalk "^3.0.0" - expect "^25.2.6" + expect "^25.2.7" jest-diff "^25.2.6" jest-get-type "^25.2.6" - jest-matcher-utils "^25.2.6" + jest-matcher-utils "^25.2.7" jest-message-util "^25.2.6" jest-resolve "^25.2.6" make-dir "^3.0.0" @@ -3101,10 +3101,10 @@ jest-validate@^25.2.6: leven "^3.1.0" pretty-format "^25.2.6" -jest-watcher@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-25.2.6.tgz#19fc571d27f89a238ef497b9e037d8d41cf4a204" - integrity sha512-yzv5DBeo03dQnSsSrn1mdOU1LSDd1tZaCTvSE5JYfcv6Z66PdDNhO9MNDdLKA/oQlJNj0S6TiYgLdOY5wL5cMA== +jest-watcher@^25.2.7: + version "25.2.7" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-25.2.7.tgz#01db4332d34d14c03c9ef22255125a3b07f997bc" + integrity sha512-RdHuW+f49tahWtluTnUdZ2iPliebleROI2L/J5phYrUS6DPC9RB3SuUtqYyYhGZJsbvRSuLMIlY/cICJ+PIecw== dependencies: "@jest/test-result" "^25.2.6" "@jest/types" "^25.2.6" @@ -3121,14 +3121,14 @@ jest-worker@^25.2.6: merge-stream "^2.0.0" supports-color "^7.0.0" -jest@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest/-/jest-25.2.6.tgz#da597f3563dceba12913965ea398fe7f8804fb12" - integrity sha512-AA9U1qmYViBTfoKWzQBbBmck53Tsw8av7zRYdE4EUBU6r04mddPQaflpPBy/KC308HF7u8fLLxEJFt/LiFzYFQ== +jest@^25.2.7: + version "25.2.7" + resolved "https://registry.yarnpkg.com/jest/-/jest-25.2.7.tgz#3929a5f35cdd496f7756876a206b99a94e1e09ae" + integrity sha512-XV1n/CE2McCikl4tfpCY950RytHYvxdo/wvtgmn/qwA8z1s16fuvgFL/KoPrrmkqJTaPMUlLVE58pwiaTX5TdA== dependencies: - "@jest/core" "^25.2.6" + "@jest/core" "^25.2.7" import-local "^3.0.2" - jest-cli "^25.2.6" + jest-cli "^25.2.7" js-sha256@^0.9.0: version "0.9.0" From 6ebaeb584960b0530e949695ace28d9818c94b66 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Mon, 6 Apr 2020 10:50:17 +1000 Subject: [PATCH 46/88] Improve config for LND Improve the cnd configuration of LND by doing: - Add the TLS certificate path and macaroon path to LND configuration. - Don't use shared data structure for LND between `file.rs` and `settings.rs`. - Update unit tests. --- cnd/src/config.rs | 45 ++++++++++++++++--- cnd/src/config/file.rs | 16 +++++-- cnd/src/config/settings.rs | 91 ++++++++++++++++---------------------- 3 files changed, 88 insertions(+), 64 deletions(-) diff --git a/cnd/src/config.rs b/cnd/src/config.rs index 84e34f9bda..74238a1b21 100644 --- a/cnd/src/config.rs +++ b/cnd/src/config.rs @@ -90,7 +90,7 @@ pub struct Parity { pub node_url: Url, } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +#[derive(Clone, Debug, PartialEq, Serialize)] pub struct Lightning { pub network: bitcoin::Network, pub lnd: Lnd, @@ -108,23 +108,36 @@ impl Default for Lightning { impl From for file::Lightning { fn from(lightning: Lightning) -> Self { file::Lightning { - lnd: Some(lightning.lnd), + lnd: Some(file::Lnd { + rest_api_url: lightning.lnd.rest_api_url, + dir: lightning.lnd.dir, + }), network: lightning.network, } } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +#[derive(Clone, Debug, PartialEq, Serialize)] pub struct Lnd { pub rest_api_url: Url, pub dir: PathBuf, + pub cert_path: PathBuf, + pub readonly_macaroon_path: PathBuf, } impl Default for Lnd { fn default() -> Self { + Self::new(bitcoin::Network::Regtest) + } +} + +impl Lnd { + fn new(network: bitcoin::Network) -> Self { Self { rest_api_url: LND_URL.clone(), dir: default_lnd_dir(), + cert_path: default_lnd_cert_path(default_lnd_dir()), + readonly_macaroon_path: default_lnd_readonly_macaroon_path(default_lnd_dir(), network), } } } @@ -133,6 +146,24 @@ fn default_lnd_dir() -> PathBuf { crate::lnd_dir().expect("no home directory") } +fn default_lnd_cert_path(lnd_dir: PathBuf) -> PathBuf { + lnd_dir.join("tls.cert") +} + +fn default_lnd_readonly_macaroon_path(lnd_dir: PathBuf, network: bitcoin::Network) -> PathBuf { + let network_dir = match network { + bitcoin::Network::Bitcoin => "mainnet", + bitcoin::Network::Testnet => "testnet", + bitcoin::Network::Regtest => "regtest", + }; + lnd_dir + .join("data") + .join("chain") + .join("bitcoin") + .join(network_dir) + .join("readonly.macaroon") +} + #[cfg(test)] mod tests { use super::*; @@ -178,7 +209,7 @@ mod tests { "#, ); - let expected = Lnd { + let expected = file::Lnd { rest_api_url: LND_URL.clone(), dir: PathBuf::from("~/.local/share/comit/lnd"), }; @@ -197,12 +228,12 @@ mod tests { "#, ); - let expected = Lightning { + let expected = file::Lightning { network: bitcoin::Network::Regtest, - lnd: Lnd { + lnd: Some(file::Lnd { rest_api_url: LND_URL.clone(), dir: PathBuf::from("/path/to/lnd"), - }, + }), }; assert_eq!(actual, Ok(expected)); diff --git a/cnd/src/config/file.rs b/cnd/src/config/file.rs index 2b62c0c52c..878670e993 100644 --- a/cnd/src/config/file.rs +++ b/cnd/src/config/file.rs @@ -1,11 +1,15 @@ use crate::{ - config::{Bitcoind, Data, Lnd, Network, Parity}, + config::{Bitcoind, Data, Network, Parity}, swap_protocols::ledger::ethereum, }; use config as config_rs; use log::LevelFilter; use serde::{Deserialize, Serialize}; -use std::{ffi::OsStr, net::SocketAddr, path::Path}; +use std::{ + ffi::OsStr, + net::SocketAddr, + path::{Path, PathBuf}, +}; /// This struct aims to represent the configuration file as it appears on disk. /// @@ -42,6 +46,12 @@ pub struct Lightning { pub lnd: Option, } +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +pub struct Lnd { + pub rest_api_url: reqwest::Url, + pub dir: PathBuf, +} + impl File { pub fn default() -> Self { File { @@ -141,7 +151,7 @@ pub enum None { mod tests { use super::*; use crate::{ - config::{Bitcoind, Lnd, Parity, Settings}, + config::{Bitcoind, Parity, Settings}, swap_protocols::ledger::ethereum, }; use reqwest::Url; diff --git a/cnd/src/config/settings.rs b/cnd/src/config/settings.rs index b98b663c77..70e91f5b70 100644 --- a/cnd/src/config/settings.rs +++ b/cnd/src/config/settings.rs @@ -1,12 +1,11 @@ use crate::config::{ - file, Bitcoin, Bitcoind, Data, Ethereum, File, Lightning, Lnd, Network, Parity, + default_lnd_cert_path, default_lnd_readonly_macaroon_path, file, Bitcoin, Bitcoind, Data, + Ethereum, File, Lightning, Lnd, Network, Parity, }; use anyhow::Context; use log::LevelFilter; -use std::{ - net::{IpAddr, Ipv4Addr, SocketAddr}, - path::PathBuf, -}; +use reqwest::Url; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; /// This structs represents the settings as they are used through out the code. /// @@ -72,6 +71,14 @@ fn derive_url_ethereum(ethereum: Option) -> Ethereum { } } +fn check_url_lnd(lnd_url: Url) -> anyhow::Result { + if lnd_url.scheme() == "https" { + Ok(lnd_url) + } else { + Err(anyhow::anyhow!("HTTPS scheme is expected for lnd url.")) + } +} + impl From for File { fn from(settings: Settings) -> Self { let Settings { @@ -218,61 +225,19 @@ impl Settings { lnd: match lightning.lnd { None => Lnd::default(), Some(lnd) => Lnd { - rest_api_url: lnd.rest_api_url, - dir: lnd.dir, + rest_api_url: check_url_lnd(lnd.rest_api_url)?, + dir: lnd.dir.clone(), + cert_path: default_lnd_cert_path(lnd.dir.clone()), + readonly_macaroon_path: default_lnd_readonly_macaroon_path( + lnd.dir, + lightning.network, + ), }, }, }, }, }) } - - pub fn lnd_macaroon_path(&self) -> Option { - let macaroon = "readonly.macaroon"; - let dirs = self.lnd_known_location(); - locate_file(dirs, macaroon) - } - - pub fn lnd_tls_cert_path(&self) -> Option { - let cert = "tls.cert"; - let dirs = self.lnd_known_location(); - locate_file(dirs, cert) - } - - pub fn lnd_tls_key_path(&self) -> Option { - let key = "tls.key"; - let dirs = self.lnd_known_location(); - locate_file(dirs, key) - } - - fn lnd_known_location(&self) -> Vec { - let mut v = vec![]; - - if let Some(cnd_data_dir) = crate::data_dir() { - // We want to use generic terms for like `tls.cert` for lnd files - // so put them all in a directory. - let lnd_dir = cnd_data_dir.join("lnd"); - v.push(lnd_dir); - } - - if let Some(lnd_dir) = crate::lnd_dir() { - let network = format!("{}", self.lightning.network); - v.push( - lnd_dir - .join("data") - .join("chain") - .join("bitcoin") - .join(&network), - ); - } - v - } -} - -/// Looks sequentially in `dirs` for `file`. -fn locate_file(dirs: Vec, file: &str) -> Option { - let path = dirs.iter().find(|dir| dir.join(file).exists()); - path.cloned() } #[cfg(test)] @@ -489,4 +454,22 @@ mod tests { lnd: Lnd::default(), }) } + + #[test] + fn error_on_http_url_for_lnd() { + let config_file = File { + lightning: Some(file::Lightning { + network: bitcoin::Network::Regtest, + lnd: Some(file::Lnd { + rest_api_url: "http://localhost:8000/".parse().unwrap(), + dir: Default::default(), + }), + }), + ..File::default() + }; + + let settings = Settings::from_config_file_and_defaults(config_file); + + assert_that(&settings).is_err(); + } } From 8b9cf1dc513c6d5ed57fd9d37ca4be073154f925 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Mon, 6 Apr 2020 11:58:05 +1000 Subject: [PATCH 47/88] Add support of `#[digest(ignore)]` attribute for structs --- digest-macro-derive/src/lib.rs | 20 +++++++++++++++++--- digest/tests/swap_digest.rs | 7 +++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index 59685f2291..baed97bdef 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -25,9 +25,21 @@ fn impl_digest_macro(ast: &syn::DeriveInput) -> TokenStream { .iter() .map(|field| field.ident.as_ref().expect("Named field")); - let types = fields.named.iter().map(|field| &field.ty); + let fields = fields.named.iter().filter(|field| { + let meta_list = extract_meta_list(&field.attrs); + + let path = &meta_list.nested.first(); + if let Some(NestedMeta::Meta(Meta::Path(path))) = path { + if path.is_ident("ignore") { + return false; + } + } + true + }); + + let types = fields.clone().map(|field| &field.ty); - let bytes = fields.named.iter().map(|field| extract_bytes(&field.attrs)); + let bytes = fields.map(|field| extract_bytes(&field.attrs)); (idents, types, bytes) } _ => panic!("Only supporting named fields."), @@ -159,7 +171,9 @@ fn extract_bytes(attrs: &[Attribute]) -> Bytes { let bytes = ::hex::decode(&str).expect("prefix value should be in hex format"); return Bytes(bytes); } - panic!("prefix could not be resolved. Expected format: `#[digest(prefix = \"0102..0A\")]` ") + panic!( + "prefix could not be resolved. Expected format: `#[digest(prefix = \"0102..0A\")]`" + ) } else { panic!("Only `prefix` identifier is supported for `digest()` field attribute. Expected format: `#[digest(prefix = \"0102..0A\")]`") } diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index ae639dd94b..9e867285c9 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -42,6 +42,8 @@ struct DoubleFieldStruct { foo: MyString, #[digest(prefix = "FFAA")] bar: MyString, + #[digest(ignore)] + ignore: MyString, } struct OtherDoubleFieldStruct { @@ -136,10 +138,12 @@ fn given_same_double_field_struct_return_same_multihash() { let struct1 = DoubleFieldStruct { foo: "first field".into(), bar: "second field".into(), + ignore: "Does not matter".into(), }; let struct2 = DoubleFieldStruct { foo: "first field".into(), bar: "second field".into(), + ignore: "So it can be whatever you want".into(), }; assert_eq!(struct1.digest(), struct2.digest()) @@ -150,10 +154,12 @@ fn given_different_double_field_struct_return_different_multihash() { let struct1 = DoubleFieldStruct { foo: "first field".into(), bar: "second field".into(), + ignore: "Does not matter".into(), }; let struct2 = DoubleFieldStruct { foo: "first field".into(), bar: "different field".into(), + ignore: "So it can be whatever you want".into(), }; assert_ne!(struct1.digest(), struct2.digest()) @@ -164,6 +170,7 @@ fn given_two_double_field_struct_with_same_data_return_same_multihash() { let struct1 = DoubleFieldStruct { foo: "foo field".into(), bar: "bar field".into(), + ignore: "this field does not matter".into(), }; let struct2 = OtherDoubleFieldStruct { bar: "bar field".into(), From 82219affd43f38075ec14b9448f12f04169ab627 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Mon, 6 Apr 2020 14:36:03 +1000 Subject: [PATCH 48/88] Write lnd rest port in config & fund both party with ln-btc --- api_tests/src/actors/actor.ts | 6 +- api_tests/src/config.ts | 79 ++++++++++++++++++++----- api_tests/src/create_actors.ts | 4 +- api_tests/src/e2e_test_environment.ts | 11 ++++ api_tests/src/ledgers/lightning.ts | 2 + api_tests/src/ledgers/lnd_instance.ts | 14 +++-- api_tests/src/utils.ts | 3 + api_tests/tests/e2e/bitcoin_ethereum.ts | 7 +-- 8 files changed, 100 insertions(+), 26 deletions(-) diff --git a/api_tests/src/actors/actor.ts b/api_tests/src/actors/actor.ts index 95fbdb20d6..1c67a7da49 100644 --- a/api_tests/src/actors/actor.ts +++ b/api_tests/src/actors/actor.ts @@ -29,6 +29,8 @@ import { defaultLedgerKindForAsset, } from "./defaults"; +export type ActorNames = "alice" | "bob" | "charlie"; + export class Actor { public static defaultActionConfig = { maxTimeoutSecs: 20, @@ -36,7 +38,7 @@ export class Actor { }; public static async newInstance( - name: string, + name: ActorNames, ledgerConfig: LedgerConfig, projectRoot: string, cndLogFile: string, @@ -83,7 +85,7 @@ export class Actor { constructor( private readonly logger: Logger, private readonly cndInstance: CndInstance, - private name: string + private readonly name: ActorNames ) { this.wallets = new Wallets({}); const socket = cndInstance.getConfigFile().http_api.socket; diff --git a/api_tests/src/config.ts b/api_tests/src/config.ts index cd82a79017..56a61d03bc 100644 --- a/api_tests/src/config.ts +++ b/api_tests/src/config.ts @@ -3,6 +3,8 @@ import { BitcoinNodeConfig } from "./ledgers/bitcoin"; import { EthereumNodeConfig } from "./ledgers/ethereum"; import { LedgerConfig } from "./utils"; import getPort from "get-port"; +import { LightningNodeConfig } from "./ledgers/lightning"; +import { ActorNames } from "./actors/actor"; export interface CndConfigFile { http_api: HttpApi; @@ -18,14 +20,14 @@ export interface HttpApi { export class E2ETestActorConfig { public readonly data: string; - public static async for(name: string) { + public static async for(name: ActorNames) { return new E2ETestActorConfig(await getPort(), await getPort(), name); } constructor( public readonly httpApiPort: number, public readonly comitPort: number, - public readonly name: string + public readonly name: ActorNames ) { this.httpApiPort = httpApiPort; this.comitPort = comitPort; @@ -50,14 +52,55 @@ export class E2ETestActorConfig { logging: { level: "Trace", }, - ...createLedgerConnectors(ledgerConfig), + ...this.createLedgerConnectors(ledgerConfig), }; } + + private createLedgerConnectors( + ledgerConfig: LedgerConfig + ): LedgerConnectors { + const config: LedgerConnectors = {}; + + if (ledgerConfig.bitcoin) { + config.bitcoin = bitcoinConnector(ledgerConfig.bitcoin); + } + + if (ledgerConfig.ethereum) { + config.ethereum = ethereumConnector(ledgerConfig.ethereum); + } + + switch (this.name) { + case "alice": { + if (ledgerConfig.aliceLnd) { + config.lightning = lightningConnector( + ledgerConfig.aliceLnd + ); + } + break; + } + case "bob": { + if (ledgerConfig.bobLnd) { + config.lightning = lightningConnector(ledgerConfig.bobLnd); + } + break; + } + case "charlie": + { + console.warn( + "generating lnd config for charlie is not supported at this stage" + ); + } + break; + } + + return config; + } } interface LedgerConnectors { bitcoin?: BitcoinConnector; ethereum?: EthereumConnector; + lightning?: LightningConnector; } interface Parity { @@ -78,18 +121,14 @@ interface BitcoinConnector { bitcoind: Bitcoind; } -function createLedgerConnectors(ledgerConfig: LedgerConfig): LedgerConnectors { - const config: LedgerConnectors = {}; - - if (ledgerConfig.bitcoin) { - config.bitcoin = bitcoinConnector(ledgerConfig.bitcoin); - } - - if (ledgerConfig.ethereum) { - config.ethereum = ethereumConnector(ledgerConfig.ethereum); - } +interface Lnd { + rest_api_url: string; + dir: string; +} - return config; +interface LightningConnector { + network: string; + lnd: Lnd; } function bitcoinConnector(nodeConfig: BitcoinNodeConfig): BitcoinConnector { @@ -109,3 +148,15 @@ function ethereumConnector(nodeConfig: EthereumNodeConfig): EthereumConnector { }, }; } + +function lightningConnector( + nodeConfig: LightningNodeConfig +): LightningConnector { + return { + network: "regtest", + lnd: { + rest_api_url: `https://localhost:${nodeConfig.restPort}`, + dir: nodeConfig.dataDir, + }, + }; +} diff --git a/api_tests/src/create_actors.ts b/api_tests/src/create_actors.ts index 0d6435d5e5..bb4ce44558 100644 --- a/api_tests/src/create_actors.ts +++ b/api_tests/src/create_actors.ts @@ -1,12 +1,12 @@ import { Actors } from "./actors"; -import { Actor } from "./actors/actor"; +import { Actor, ActorNames } from "./actors/actor"; import { HarnessGlobal } from "./utils"; declare var global: HarnessGlobal; export async function createActors( testName: string, - actorNames: string[] + actorNames: ActorNames[] ): Promise { const actorsMap = new Map(); diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index ff94c2af95..6bb80fe09c 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -185,7 +185,14 @@ export default class E2ETestEnvironment extends NodeEnvironment { quantity: "15000000", }); + await bob.mint({ + name: AssetKind.Bitcoin, + ledger: LedgerKind.Lightning, + quantity: "15000000", + }); + await alice.openChannel(bob, 15000000); + await bob.openChannel(alice, 15000000); } /** @@ -213,6 +220,8 @@ export default class E2ETestEnvironment extends NodeEnvironment { this.aliceLightning.config.lnd, this.aliceLightning.config.p2pSocket ); + + this.global.ledgerConfigs.aliceLnd = this.aliceLightning.config; } /** @@ -240,6 +249,8 @@ export default class E2ETestEnvironment extends NodeEnvironment { this.bobLightning.config.lnd, this.bobLightning.config.p2pSocket ); + + this.global.ledgerConfigs.bobLnd = this.bobLightning.config; } private static async cleanLogDir(logDir: string) { diff --git a/api_tests/src/ledgers/lightning.ts b/api_tests/src/ledgers/lightning.ts index 74cc301b2f..94b102fafe 100644 --- a/api_tests/src/ledgers/lightning.ts +++ b/api_tests/src/ledgers/lightning.ts @@ -39,4 +39,6 @@ export interface LightningNodeConfig { p2pSocket: string; // sucks that we have to leak here that the instance is LND under the hood but we can't do much about that :) lnd: Lnd; + restPort: number; + dataDir: string; } diff --git a/api_tests/src/ledgers/lnd_instance.ts b/api_tests/src/ledgers/lnd_instance.ts index 30c55d64b6..e171c1883a 100644 --- a/api_tests/src/ledgers/lnd_instance.ts +++ b/api_tests/src/ledgers/lnd_instance.ts @@ -25,6 +25,7 @@ export class LndInstance implements LightningInstance { logger, bitcoindDataDir, await getPort(), + await getPort(), await getPort() ); } @@ -35,7 +36,8 @@ export class LndInstance implements LightningInstance { private readonly logger: Logger, private readonly bitcoindDataDir: string, private readonly lndP2pPort: number, - private readonly lndRpcPort: number + private readonly lndRpcPort: number, + private readonly lndRestPort: number ) {} public async start() { @@ -178,16 +180,20 @@ export class LndInstance implements LightningInstance { return this.lndP2pPort; } + get restPort() { + return this.lndRestPort; + } + get config(): LightningNodeConfig { return { p2pSocket: this.p2pSocket, lnd: this.lnd, + restPort: this.restPort, + dataDir: this.dataDir, }; } private async createConfigFile() { - // We don't use REST but want a random port so we don't get used port errors. - const restPort = await getPort(); const output = `[Application Options] debuglevel=trace @@ -198,7 +204,7 @@ listen=127.0.0.1:${this.lndP2pPort} rpclisten=127.0.0.1:${this.lndRpcPort} ; REST interface -restlisten=127.0.0.1:${restPort} +restlisten=127.0.0.1:${this.lndRestPort} ; Do not seek out peers on the network nobootstrap=true diff --git a/api_tests/src/utils.ts b/api_tests/src/utils.ts index 4e8f0ef11a..16d7b589c9 100644 --- a/api_tests/src/utils.ts +++ b/api_tests/src/utils.ts @@ -11,6 +11,7 @@ import { LightningWallet } from "./wallets/lightning"; import { BitcoinNodeConfig } from "./ledgers/bitcoin"; import { EthereumNodeConfig } from "./ledgers/ethereum"; import { Logger } from "log4js"; +import { LightningNodeConfig } from "./ledgers/lightning"; export interface HarnessGlobal extends Global.Global { ledgerConfigs: LedgerConfig; @@ -30,6 +31,8 @@ export interface HarnessGlobal extends Global.Global { export interface LedgerConfig { bitcoin?: BitcoinNodeConfig; ethereum?: EthereumNodeConfig; + aliceLnd?: LightningNodeConfig; + bobLnd?: LightningNodeConfig; } export const unlinkAsync = promisify(fs.unlink); diff --git a/api_tests/tests/e2e/bitcoin_ethereum.ts b/api_tests/tests/e2e/bitcoin_ethereum.ts index 4b224d1ab6..e228fa26d2 100644 --- a/api_tests/tests/e2e/bitcoin_ethereum.ts +++ b/api_tests/tests/e2e/bitcoin_ethereum.ts @@ -6,7 +6,6 @@ import { twoActorTest } from "../../src/actor_test"; import { AssetKind } from "../../src/asset"; import { sleep } from "../../src/utils"; -import { expect } from "chai"; import { LedgerKind } from "../../src/ledgers/ledger"; // ******************************************** // @@ -56,7 +55,7 @@ describe("E2E: Sanity - LND Alice pays Bob", () => { await bob.lnSettleInvoice(secret, secretHash); const pay = await paymentPromise; - expect(pay.paymentPreimage.toString("hex")).equals(secret); + expect(pay.paymentPreimage.toString("hex")).toEqual(secret); await bob.lnAssertInvoiceSettled(secretHash); }) @@ -64,7 +63,7 @@ describe("E2E: Sanity - LND Alice pays Bob", () => { }); // ******************************************** // -// Bitcoin/bitcoin Alpha Ledger/ Alpha Asset // +// Bitcoin/bitcoin Alpha Ledger/Alpha Asset // // Ethereum/ether Beta Ledger/Beta Asset // // ******************************************** // describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { @@ -423,7 +422,7 @@ describe("E2E: Ethereum/ether - Bitcoin/bitcoin", () => { const responsePromise = alice.redeemWithHighFee(); - return expect(responsePromise).to.be.rejected; + return expect(responsePromise).rejects.toThrow(); }) ); }); From 2bb7ee149406c2fe4bc9c571c33f7a9cb1d238f2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2020 17:49:34 +0000 Subject: [PATCH 49/88] Bump prettier from 2.0.2 to 2.0.4 in /api_tests Bumps [prettier](https://github.com/prettier/prettier) from 2.0.2 to 2.0.4. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/2.0.2...2.0.4) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 62818c0f30..6e91f891a2 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -52,7 +52,7 @@ "js-sha256": "^0.9.0", "log4js": "^6.1.2", "p-timeout": "^3.2.0", - "prettier": "^2.0.2", + "prettier": "^2.0.4", "rimraf": "^3.0.2", "satoshi-bitcoin": "^1.0.4", "tail": "^2.0.3", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index b3a2581ed5..468eaa692a 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -4024,10 +4024,10 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prettier@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.2.tgz#1ba8f3eb92231e769b7fcd7cb73ae1b6b74ade08" - integrity sha512-5xJQIPT8BraI7ZnaDwSbu5zLrB6vvi8hVV58yHQ+QK64qrY40dULy0HSRlQ2/2IdzeBpjhDkqdcFBnFeDEMVdg== +prettier@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.4.tgz#2d1bae173e355996ee355ec9830a7a1ee05457ef" + integrity sha512-SVJIQ51spzFDvh4fIbCLvciiDMCrRhlN3mbZvv/+ycjvmF5E73bKdGfU8QDLNmjYJf+lsGnDBC4UUnvTe5OO0w== pretty-format@^25.2.1, pretty-format@^25.2.6: version "25.2.6" From 873e61ae034b63d073e46c97ffb11c2fba5b4c71 Mon Sep 17 00:00:00 2001 From: rishflab Date: Sun, 5 Apr 2020 11:19:28 +1000 Subject: [PATCH 50/88] Check for redeem/refund spent outpoint using identity Decide whether refund or redeem transaction using identity rather than checking for a 1 or 0 on the witness stack. Closes #2270 --- cnd/src/bitcoin.rs | 3 ++ cnd/src/btsieve/bitcoin.rs | 25 +++++------------ .../rfc003/bitcoin/htlc_events.rs | 28 +++++++++++-------- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/cnd/src/bitcoin.rs b/cnd/src/bitcoin.rs index 3381370512..4be97e1690 100644 --- a/cnd/src/bitcoin.rs +++ b/cnd/src/bitcoin.rs @@ -26,6 +26,9 @@ impl PublicKey { { secp256k1::PublicKey::from_secret_key(secp, secret_key).into() } + pub fn to_bytes(&self) -> Vec { + self.0.to_bytes() + } } impl From for PublicKey { diff --git a/cnd/src/btsieve/bitcoin.rs b/cnd/src/btsieve/bitcoin.rs index 4726258670..68d15579f3 100644 --- a/cnd/src/btsieve/bitcoin.rs +++ b/cnd/src/btsieve/bitcoin.rs @@ -5,11 +5,13 @@ pub use self::{ bitcoind_connector::{BitcoindConnector, ChainInfo}, cache::Cache, }; -use crate::btsieve::{ - find_relevant_blocks, BlockByHash, BlockHash, LatestBlock, Predates, PreviousBlockHash, +use crate::{ + btsieve::{ + find_relevant_blocks, BlockByHash, BlockHash, LatestBlock, Predates, PreviousBlockHash, + }, + identity, }; use bitcoin::{ - blockdata::script::Instruction, consensus::{encode::deserialize, Decodable}, BitcoinHash, OutPoint, }; @@ -40,7 +42,7 @@ pub async fn watch_for_spent_outpoint( blockchain_connector: &C, start_of_swap: NaiveDateTime, from_outpoint: OutPoint, - unlock_script: Vec>, + identity: identity::Bitcoin, ) -> anyhow::Result<(bitcoin::Transaction, bitcoin::TxIn)> where C: LatestBlock + BlockByHash, @@ -50,20 +52,7 @@ where .input .iter() .filter(|txin| txin.previous_output == from_outpoint) - .find(|txin| { - unlock_script.iter().all(|item| { - txin.witness.contains(item) - || unlock_script.iter().all(|item| { - txin.script_sig - .iter(true) - .any(|instruction| match instruction { - Instruction::PushBytes(data) => (item as &[u8]) == data, - Instruction::Op(_) => false, - Instruction::Error(_) => false, - }) - }) - }) - }) + .find(|txin| txin.witness.contains(&identity.to_bytes())) .cloned() }) .await?; diff --git a/cnd/src/swap_protocols/rfc003/bitcoin/htlc_events.rs b/cnd/src/swap_protocols/rfc003/bitcoin/htlc_events.rs index d414808e9e..9a5023d893 100644 --- a/cnd/src/swap_protocols/rfc003/bitcoin/htlc_events.rs +++ b/cnd/src/swap_protocols/rfc003/bitcoin/htlc_events.rs @@ -92,12 +92,14 @@ where htlc_deployment: &Deployed, start_of_swap: NaiveDateTime, ) -> anyhow::Result> { - let (transaction, _) = - watch_for_spent_outpoint(self, start_of_swap, htlc_deployment.location, vec![vec![ - 1u8, - ]]) - .instrument(tracing::info_span!("htlc_redeemed")) - .await?; + let (transaction, _) = watch_for_spent_outpoint( + self, + start_of_swap, + htlc_deployment.location, + htlc_params.redeem_identity, + ) + .instrument(tracing::info_span!("htlc_redeemed")) + .await?; let secret = extract_secret(&transaction, &htlc_params.secret_hash) .expect("Redeem transaction must contain secret"); @@ -118,14 +120,18 @@ where { async fn htlc_refunded( &self, - _htlc_params: &HtlcParams, + htlc_params: &HtlcParams, htlc_deployment: &Deployed, start_of_swap: NaiveDateTime, ) -> anyhow::Result> { - let (transaction, _) = - watch_for_spent_outpoint(self, start_of_swap, htlc_deployment.location, vec![vec![]]) - .instrument(tracing::info_span!("htlc_refunded")) - .await?; + let (transaction, _) = watch_for_spent_outpoint( + self, + start_of_swap, + htlc_deployment.location, + htlc_params.refund_identity, + ) + .instrument(tracing::info_span!("htlc_refunded")) + .await?; Ok(Refunded { transaction }) } From 317735787ee025266f6e38e3cee9e3a666b1129b Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Mon, 30 Mar 2020 11:24:29 +1100 Subject: [PATCH 51/88] Replace H256 and H160 with own Hash and Address --- cnd/src/btsieve/ethereum.rs | 13 +- cnd/src/btsieve/ethereum/web3_connector.rs | 6 +- cnd/src/comit_api.rs | 2 +- cnd/src/ethereum.rs | 206 +++++++++++++++++- cnd/src/http_api.rs | 8 +- .../http_api/routes/rfc003/handlers/action.rs | 9 +- .../routes/rfc003/handlers/post_swap.rs | 2 +- cnd/src/network.rs | 16 +- .../network/protocols/ethereum_identity.rs | 2 +- cnd/src/quickcheck.rs | 20 +- cnd/src/swap_protocols/rfc003/ethereum.rs | 12 +- .../rfc003/ethereum/htlc_events.rs | 8 +- cnd/tests/ethereum_helper/connector_mock.rs | 12 +- libp2p-comit/src/frame/header.rs | 6 +- libp2p-comit/src/frame/request.rs | 2 +- libp2p-comit/src/substream/inbound.rs | 34 +-- libp2p-comit/src/substream/outbound.rs | 3 +- 17 files changed, 270 insertions(+), 91 deletions(-) diff --git a/cnd/src/btsieve/ethereum.rs b/cnd/src/btsieve/ethereum.rs index 92823d186b..a9b13b08ea 100644 --- a/cnd/src/btsieve/ethereum.rs +++ b/cnd/src/btsieve/ethereum.rs @@ -6,16 +6,13 @@ use crate::{ btsieve::{ find_relevant_blocks, BlockByHash, BlockHash, LatestBlock, Predates, PreviousBlockHash, }, - ethereum::{Address, Bytes, Input, Log, Transaction, TransactionReceipt, H256, U256}, + ethereum::{Address, Block, Bytes, Hash, Input, Log, Transaction, TransactionReceipt, U256}, }; use anyhow; use async_trait::async_trait; use chrono::NaiveDateTime; use genawaiter::{sync::Gen, GeneratorState}; -type Hash = H256; -type Block = crate::ethereum::Block; - #[async_trait] pub trait ReceiptByHash: Send + Sync + 'static { async fn receipt_by_hash(&self, transaction_hash: Hash) -> anyhow::Result; @@ -24,7 +21,7 @@ pub trait ReceiptByHash: Send + Sync + 'static { impl BlockHash for Block { type BlockHash = Hash; - fn block_hash(&self) -> H256 { + fn block_hash(&self) -> Hash { self.hash .expect("Connector returned latest block with null hash") } @@ -33,7 +30,7 @@ impl BlockHash for Block { impl PreviousBlockHash for Block { type BlockHash = Hash; - fn previous_block_hash(&self) -> H256 { + fn previous_block_hash(&self) -> Hash { self.parent_hash } } @@ -174,7 +171,7 @@ where topic.as_ref().map_or(true, |topic| { block .logs_bloom - .contains_input(Input::Raw(topic.0.as_ref())) + .contains_input(Input::Raw(&topic.0.as_bytes())) }) }); if !maybe_contains_transaction { @@ -227,7 +224,7 @@ impl Predates for Block { #[derive(Clone, Copy, Default, Eq, PartialEq, serde::Serialize, serdebug::SerDebug)] #[serde(transparent)] -pub struct Topic(pub H256); +pub struct Topic(pub Hash); /// Event works similar to web3 filters: /// https://web3js.readthedocs.io/en/1.0/web3-eth-subscribe.html?highlight=filter#subscribe-logs diff --git a/cnd/src/btsieve/ethereum/web3_connector.rs b/cnd/src/btsieve/ethereum/web3_connector.rs index ad1b3e44f8..b38431c712 100644 --- a/cnd/src/btsieve/ethereum/web3_connector.rs +++ b/cnd/src/btsieve/ethereum/web3_connector.rs @@ -1,7 +1,7 @@ use crate::{ btsieve::{ethereum::ReceiptByHash, BlockByHash, LatestBlock}, config::validation::FetchNetworkId, - ethereum::{TransactionReceipt, H256}, + ethereum::{Hash, TransactionReceipt}, jsonrpc, swap_protocols::ledger::ethereum::ChainId, }; @@ -45,7 +45,7 @@ impl LatestBlock for Web3Connector { #[async_trait] impl BlockByHash for Web3Connector { type Block = crate::ethereum::Block; - type BlockHash = crate::ethereum::H256; + type BlockHash = crate::ethereum::Hash; async fn block_by_hash(&self, block_hash: Self::BlockHash) -> anyhow::Result { let block = self @@ -64,7 +64,7 @@ impl BlockByHash for Web3Connector { #[async_trait] impl ReceiptByHash for Web3Connector { - async fn receipt_by_hash(&self, transaction_hash: H256) -> anyhow::Result { + async fn receipt_by_hash(&self, transaction_hash: Hash) -> anyhow::Result { let receipt = self .client .send(jsonrpc::Request::new("eth_getTransactionReceipt", vec![ diff --git a/cnd/src/comit_api.rs b/cnd/src/comit_api.rs index 676e4ec5af..7e102f4b28 100644 --- a/cnd/src/comit_api.rs +++ b/cnd/src/comit_api.rs @@ -168,7 +168,7 @@ mod tests { #[test] fn erc20_quantity_to_header() -> Result<(), serde_json::Error> { let quantity = asset::Erc20::new( - Address::zero(), + Address::from([0u8; 20]), asset::Erc20Quantity::from_wei(U256::from(100_000_000_000_000u64)), ); let header = AssetKind::from(quantity).to_header()?; diff --git a/cnd/src/ethereum.rs b/cnd/src/ethereum.rs index 7177f0098f..1e27fffc51 100644 --- a/cnd/src/ethereum.rs +++ b/cnd/src/ethereum.rs @@ -2,21 +2,141 @@ #![forbid(unsafe_code)] pub use ethbloom::{Bloom as H2048, Input}; -pub use primitive_types::{H160, H256, U128, U256}; +use hex::FromHexError; +pub use primitive_types::U256; use serde::{Deserialize, Serialize}; use serde_hex::{CompactPfx, SerHex, SerHexSeq, StrictPfx}; - -pub type Address = H160; +use std::{ + fmt, + fmt::{Display, Formatter, LowerHex}, + str::FromStr, +}; #[derive(Debug, Default, Copy, Clone, PartialEq, Deserialize)] pub struct H64(#[serde(with = "SerHex::")] [u8; 8]); +#[derive( + Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, +)] +pub struct Address(#[serde(with = "SerHex::")] [u8; 20]); + +impl Address { + pub fn from_slice(src: &[u8]) -> Self { + let mut address = Address([0u8; 20]); + address.0.copy_from_slice(src); + address + } +} + +impl From<[u8; 20]> for Address { + fn from(bytes: [u8; 20]) -> Self { + Address(bytes) + } +} + +impl From
for [u8; 20] { + fn from(s: Address) -> Self { + s.0 + } +} + +impl FromStr for Address { + type Err = FromHexError; + + fn from_str(s: &str) -> Result { + hex::decode(s).map(|v| Address::from_slice(v.as_slice())) + } +} + +impl From
for Hash { + fn from(address: Address) -> Self { + let mut h256 = Hash([0u8; 32]); + h256.0[(32 - 20)..32].copy_from_slice(&address.0); + h256 + } +} + +impl LowerHex for Address { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + if f.alternate() { + write!(f, "0x")?; + } + for i in &self.0[..] { + write!(f, "{:02x}", i)?; + } + Ok(()) + } +} + +#[derive( + Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, +)] +pub struct Hash(#[serde(with = "SerHex::")] [u8; 32]); + +impl From<[u8; 32]> for Hash { + fn from(bytes: [u8; 32]) -> Self { + Hash(bytes) + } +} + +impl From for [u8; 32] { + fn from(s: Hash) -> Self { + s.0 + } +} + +impl Hash { + pub fn from_slice(src: &[u8]) -> Self { + let mut h256 = Hash([0u8; 32]); + h256.0.copy_from_slice(src); + h256 + } + + pub fn as_bytes(&self) -> &[u8] { + &self.0 + } +} + +impl FromStr for Hash { + type Err = FromHexError; + + fn from_str(s: &str) -> Result { + hex::decode(s).map(|v| Hash::from_slice(v.as_slice())) + } +} + +impl LowerHex for Hash { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + if f.alternate() { + write!(f, "0x")?; + } + for i in &self.0[..] { + write!(f, "{:02x}", i)?; + } + Ok(()) + } +} + +impl Display for Hash { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "0x")?; + for i in &self.0[0..2] { + write!(f, "{:02x}", i)?; + } + write!(f, "…")?; + for i in &self.0[32 - 2..32] { + write!(f, "{:02x}", i)?; + } + Ok(()) + } +} + /// "Receipt" of an executed transaction: details of its execution. #[derive(Debug, Default, Clone, PartialEq, Deserialize)] pub struct TransactionReceipt { /// Contract address created, or `None` if not a deployment. #[serde(rename = "contractAddress")] - pub contract_address: Option, + pub contract_address: Option
, /// Logs generated within this transaction. pub logs: Vec, /// Status: either 1 (success) or 0 (failure). @@ -34,9 +154,9 @@ impl TransactionReceipt { #[derive(Debug, Default, Clone, PartialEq, Deserialize)] pub struct Transaction { /// Hash - pub hash: H256, + pub hash: Hash, /// Recipient (None when contract creation) - pub to: Option, + pub to: Option
, /// Transfered value pub value: U256, /// Input data @@ -47,9 +167,9 @@ pub struct Transaction { #[derive(Debug, Clone, PartialEq, Deserialize)] pub struct Log { /// H160 - pub address: H160, + pub address: Address, /// Topics - pub topics: Vec, + pub topics: Vec, /// Data pub data: Bytes, } @@ -60,10 +180,10 @@ pub struct Log { #[derive(Debug, Default, Clone, PartialEq, Deserialize)] pub struct Block { /// Hash of the block - pub hash: Option, + pub hash: Option, /// Hash of the parent #[serde(rename = "parentHash")] - pub parent_hash: H256, + pub parent_hash: Hash, /// Logs bloom #[serde(rename = "logsBloom")] pub logs_bloom: H2048, @@ -85,8 +205,70 @@ impl>> From for Bytes { #[cfg(test)] mod tests { - use super::Log; - use crate::ethereum::TransactionReceipt; + use super::*; + + #[test] + fn deserialise_address() { + let json = + serde_json::Value::String("0xc5549e335b2786520f4c5d706c76c9ee69d0a028".to_owned()); + let _: Address = Address::deserialize(&json).unwrap(); + } + + #[test] + fn deserialise_address_when_not_using_reference_to_deserialize_fails() { + // This is due to a bug in serde-jex, keep this test until https://github.com/fspmarshall/serde-hex/pull/8 + // is fixed. + let json = + serde_json::Value::String("0xc5549e335b2786520f4c5d706c76c9ee69d0a028".to_owned()); + + let deserialized = serde_json::from_value::
(json); + matches!(deserialized, Err(_)); + } + + #[test] + fn from_string_address() { + let json = + serde_json::Value::String("0xc5549e335b2786520f4c5d706c76c9ee69d0a028".to_owned()); + let deserialized: Address = Address::deserialize(&json).unwrap(); + + let from_string = Address::from_str("c5549e335b2786520f4c5d706c76c9ee69d0a028").unwrap(); + + assert_eq!(from_string, deserialized); + } + + #[test] + fn deserialise_hash() { + let json = serde_json::Value::String( + "0x3ae3b6ffb04204f52dee42000e8b971c0f7c2b4aa8dd9455e41a30ee4b31e8a9".to_owned(), + ); + let _: Hash = Hash::deserialize(&json).unwrap(); + } + + #[test] + fn deserialise_hash_when_not_using_reference_to_deserialize_fails() { + // This is due to a bug in serde-jex, keep this test until https://github.com/fspmarshall/serde-hex/pull/8 + // is fixed. + let json = serde_json::Value::String( + "0x3ae3b6ffb04204f52dee42000e8b971c0f7c2b4aa8dd9455e41a30ee4b31e8a9".to_owned(), + ); + + let deserialized = serde_json::from_value::(json); + matches!(deserialized, Err(_)); + } + + #[test] + fn from_string_hash() { + let json = serde_json::Value::String( + "0x3ae3b6ffb04204f52dee42000e8b971c0f7c2b4aa8dd9455e41a30ee4b31e8a9".to_owned(), + ); + let deserialized: Hash = Hash::deserialize(&json).unwrap(); + + let from_string = + Hash::from_str("3ae3b6ffb04204f52dee42000e8b971c0f7c2b4aa8dd9455e41a30ee4b31e8a9") + .unwrap(); + + assert_eq!(from_string, deserialized); + } #[test] fn deserialise_log() { diff --git a/cnd/src/http_api.rs b/cnd/src/http_api.rs index d237df86ac..81c1e8a41b 100644 --- a/cnd/src/http_api.rs +++ b/cnd/src/http_api.rs @@ -97,7 +97,7 @@ impl Serialize for Http { } impl_serialize_type_with_fields!(htlc_location::Bitcoin { "txid" => txid, "vout" => vout }); -impl_serialize_http!(crate::ethereum::H160); +impl_serialize_http!(crate::ethereum::Address); impl_serialize_http!(SwapId); impl Serialize for Http { @@ -489,7 +489,7 @@ mod tests { asset, asset::ethereum::FromWei, bitcoin::PublicKey, - ethereum::{H160, H256, U256}, + ethereum::{Address, Hash, U256}, http_api::{Http, HttpAsset, HttpLedger}, swap_protocols::{ ledger::{bitcoin, ethereum, Ethereum}, @@ -591,7 +591,7 @@ mod tests { output: vec![], }; let ethereum_tx = transaction::Ethereum { - hash: H256::repeat_byte(1), + hash: Hash::from([1u8; 32]), ..transaction::Ethereum::default() }; @@ -618,7 +618,7 @@ mod tests { .parse() .unwrap(); - let ethereum_identity = H160::repeat_byte(7); + let ethereum_identity = Address::from([7u8; 20]); let bitcoin_identity = Http(bitcoin_identity); let ethereum_identity = Http(ethereum_identity); diff --git a/cnd/src/http_api/routes/rfc003/handlers/action.rs b/cnd/src/http_api/routes/rfc003/handlers/action.rs index d4262c2dcf..0beb9f24d1 100644 --- a/cnd/src/http_api/routes/rfc003/handlers/action.rs +++ b/cnd/src/http_api/routes/rfc003/handlers/action.rs @@ -26,7 +26,7 @@ use crate::{ }; use anyhow::Context; use libp2p_comit::frame::Response; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use std::{ fmt::{self, Debug, Display}, string::ToString, @@ -75,8 +75,8 @@ pub async fn handle_action( match action { Action::Accept(_) => { - let body = serde_json::from_value::(body) - .context("failed to deserialize accept body")?; + let body = + AcceptBody::deserialize(&body).context("failed to deserialize accept body")?; let channel = dependencies .pending_request_for(swap_id) @@ -112,7 +112,8 @@ pub async fn handle_action( Ok(ActionResponseBody::None) } Action::Decline(_) => { - let body = serde_json::from_value::(body)?; + let body = DeclineBody::deserialize(&body) + .context("failed to deserialize decline body")?; let channel = dependencies .pending_request_for(swap_id) diff --git a/cnd/src/http_api/routes/rfc003/handlers/post_swap.rs b/cnd/src/http_api/routes/rfc003/handlers/post_swap.rs index f222548589..85a7d24a33 100644 --- a/cnd/src/http_api/routes/rfc003/handlers/post_swap.rs +++ b/cnd/src/http_api/routes/rfc003/handlers/post_swap.rs @@ -128,7 +128,7 @@ pub async fn handle_post_swap( let seed = dependencies.derive_swap_seed(id); let secret_hash = seed.derive_secret().hash(); - let body = serde_json::from_value(body)?; + let body = SwapRequestBody::deserialize(&body)?; match body { SwapRequestBody { diff --git a/cnd/src/network.rs b/cnd/src/network.rs index f8e99b4ed1..65b6da2181 100644 --- a/cnd/src/network.rs +++ b/cnd/src/network.rs @@ -50,7 +50,7 @@ use libp2p_comit::{ handler::{ComitHandler, ProtocolInEvent, ProtocolOutEvent}, BehaviourOutEvent, Comit, PendingInboundRequest, }; -use serde::{de::DeserializeOwned, Serialize}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::{ collections::{HashMap, HashSet}, convert::{TryFrom, TryInto}, @@ -1012,9 +1012,10 @@ impl SendRequest for Swarm { match decision { Some(Decision::Accepted) => { - match serde_json::from_value::>( - response.body().clone(), - ) { + let accept_body = + rfc003::messages::AcceptResponseBody::deserialize(response.body()); + + match accept_body { Ok(body) => Ok(Ok(rfc003::Accept { swap_id: id, beta_ledger_refund_identity: body.beta_ledger_refund_identity, @@ -1025,9 +1026,10 @@ impl SendRequest for Swarm { } Some(Decision::Declined) => { - match serde_json::from_value::( - response.body().clone(), - ) { + let decline_body = + rfc003::messages::DeclineResponseBody::deserialize(response.body()); + + match decline_body { Ok(body) => Ok(Err(rfc003::Decline { swap_id: id, reason: body.reason, diff --git a/cnd/src/network/protocols/ethereum_identity.rs b/cnd/src/network/protocols/ethereum_identity.rs index eb37b59f38..fc1c629c25 100644 --- a/cnd/src/network/protocols/ethereum_identity.rs +++ b/cnd/src/network/protocols/ethereum_identity.rs @@ -16,7 +16,7 @@ impl Message { pub fn new(swap_id: SwapId, address: identity::Ethereum) -> Self { Self { swap_id, - address: address.0, + address: address.into(), } } } diff --git a/cnd/src/quickcheck.rs b/cnd/src/quickcheck.rs index d996553e5e..5071f34e86 100644 --- a/cnd/src/quickcheck.rs +++ b/cnd/src/quickcheck.rs @@ -2,7 +2,7 @@ use crate::{ asset, asset::ethereum::FromWei, db::Swap, - ethereum::Bytes, + ethereum::{Address, Bytes}, identity, swap_protocols::{ ledger, @@ -167,31 +167,23 @@ impl Arbitrary for Quickcheck { fn arbitrary(g: &mut G) -> Self { let bytes = *Quickcheck::<[u8; 20]>::arbitrary(g); - Quickcheck(identity::Ethereum::from(bytes)) + Quickcheck(Address::from(bytes)) } } -impl Arbitrary for Quickcheck { - fn arbitrary(g: &mut G) -> Self { - let bytes = *Quickcheck::<[u8; 16]>::arbitrary(g); - - Quickcheck(crate::ethereum::U128::from(&bytes)) - } -} - -impl Arbitrary for Quickcheck { +impl Arbitrary for Quickcheck { fn arbitrary(g: &mut G) -> Self { let bytes = *Quickcheck::<[u8; 32]>::arbitrary(g); - Quickcheck(crate::ethereum::H256::from(&bytes)) + Quickcheck(crate::ethereum::Hash::from(bytes)) } } impl Arbitrary for Quickcheck { fn arbitrary(g: &mut G) -> Self { Quickcheck(transaction::Ethereum { - hash: *Quickcheck::::arbitrary(g), - to: Option::>::arbitrary(g).map(|i| i.0), + hash: *Quickcheck::::arbitrary(g), + to: Option::>::arbitrary(g).map(|i| i.0), value: *Quickcheck::::arbitrary(g), input: Bytes(Arbitrary::arbitrary(g)), }) diff --git a/cnd/src/swap_protocols/rfc003/ethereum.rs b/cnd/src/swap_protocols/rfc003/ethereum.rs index c53c9e9fb1..bbfe3fa46a 100644 --- a/cnd/src/swap_protocols/rfc003/ethereum.rs +++ b/cnd/src/swap_protocols/rfc003/ethereum.rs @@ -10,8 +10,10 @@ use blockchain_contracts::ethereum::rfc003::{erc20_htlc::Erc20Htlc, ether_htlc:: impl From> for EtherHtlc { fn from(htlc_params: HtlcParams) -> Self { - let refund_address = blockchain_contracts::ethereum::Address(htlc_params.refund_identity.0); - let redeem_address = blockchain_contracts::ethereum::Address(htlc_params.redeem_identity.0); + let refund_address = + blockchain_contracts::ethereum::Address(htlc_params.refund_identity.into()); + let redeem_address = + blockchain_contracts::ethereum::Address(htlc_params.redeem_identity.into()); EtherHtlc::new( htlc_params.expiry.into(), @@ -30,8 +32,10 @@ impl HtlcParams { impl From> for Erc20Htlc { fn from(htlc_params: HtlcParams) -> Self { - let refund_address = blockchain_contracts::ethereum::Address(htlc_params.refund_identity.0); - let redeem_address = blockchain_contracts::ethereum::Address(htlc_params.redeem_identity.0); + let refund_address = + blockchain_contracts::ethereum::Address(htlc_params.refund_identity.into()); + let redeem_address = + blockchain_contracts::ethereum::Address(htlc_params.redeem_identity.into()); let token_contract_address = blockchain_contracts::ethereum::Address(htlc_params.asset.token_contract.into()); diff --git a/cnd/src/swap_protocols/rfc003/ethereum/htlc_events.rs b/cnd/src/swap_protocols/rfc003/ethereum/htlc_events.rs index 63bd684da1..cb866c2aa9 100644 --- a/cnd/src/swap_protocols/rfc003/ethereum/htlc_events.rs +++ b/cnd/src/swap_protocols/rfc003/ethereum/htlc_events.rs @@ -4,7 +4,7 @@ use crate::{ btsieve::ethereum::{ watch_for_contract_creation, watch_for_event, Cache, Event, Topic, Web3Connector, }, - ethereum::{H256, U256}, + ethereum::{Hash, U256}, htlc_location, identity, swap_protocols::{ ledger::Ethereum, @@ -24,10 +24,10 @@ use std::cmp::Ordering; use tracing_futures::Instrument; lazy_static::lazy_static! { - static ref REDEEM_LOG_MSG: H256 = blockchain_contracts::ethereum::rfc003::REDEEMED_LOG_MSG.parse().expect("to be valid hex"); - static ref REFUND_LOG_MSG: H256 = blockchain_contracts::ethereum::rfc003::REFUNDED_LOG_MSG.parse().expect("to be valid hex"); + static ref REDEEM_LOG_MSG: Hash = blockchain_contracts::ethereum::rfc003::REDEEMED_LOG_MSG.parse().expect("to be valid hex"); + static ref REFUND_LOG_MSG: Hash = blockchain_contracts::ethereum::rfc003::REFUNDED_LOG_MSG.parse().expect("to be valid hex"); /// keccak('Transfer(address,address,uint256)') - static ref TRANSFER_LOG_MSG: H256 = "ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef".parse().expect("to be valid hex"); + static ref TRANSFER_LOG_MSG: Hash = "ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef".parse().expect("to be valid hex"); } #[async_trait::async_trait] diff --git a/cnd/tests/ethereum_helper/connector_mock.rs b/cnd/tests/ethereum_helper/connector_mock.rs index f47a4daa2d..2e39837dd4 100644 --- a/cnd/tests/ethereum_helper/connector_mock.rs +++ b/cnd/tests/ethereum_helper/connector_mock.rs @@ -2,15 +2,15 @@ use anyhow::Context; use async_trait::async_trait; use cnd::{ btsieve::{ethereum::ReceiptByHash, BlockByHash, LatestBlock}, - ethereum::{Block, TransactionReceipt, H256}, + ethereum::{Block, Hash, TransactionReceipt}, }; use futures::{stream::BoxStream, StreamExt}; use std::{collections::HashMap, time::Duration}; use tokio::{stream, sync::Mutex, time::throttle}; pub struct EthereumConnectorMock { - all_blocks: HashMap, - receipts: HashMap, + all_blocks: HashMap, + receipts: HashMap, latest_blocks: Mutex>, } @@ -18,7 +18,7 @@ impl EthereumConnectorMock { pub fn new( latest_blocks: Vec, all_blocks: Vec, - receipts: Vec<(H256, TransactionReceipt)>, + receipts: Vec<(Hash, TransactionReceipt)>, ) -> Self { let all_blocks = all_blocks .into_iter() @@ -61,7 +61,7 @@ impl LatestBlock for EthereumConnectorMock { #[async_trait] impl BlockByHash for EthereumConnectorMock { type Block = Block; - type BlockHash = H256; + type BlockHash = Hash; async fn block_by_hash(&self, block_hash: Self::BlockHash) -> anyhow::Result { self.all_blocks @@ -73,7 +73,7 @@ impl BlockByHash for EthereumConnectorMock { #[async_trait] impl ReceiptByHash for EthereumConnectorMock { - async fn receipt_by_hash(&self, transaction_hash: H256) -> anyhow::Result { + async fn receipt_by_hash(&self, transaction_hash: Hash) -> anyhow::Result { self.receipts .get(&transaction_hash) .cloned() diff --git a/libp2p-comit/src/frame/header.rs b/libp2p-comit/src/frame/header.rs index bb047ccf43..19b43f0e3b 100644 --- a/libp2p-comit/src/frame/header.rs +++ b/libp2p-comit/src/frame/header.rs @@ -72,7 +72,7 @@ impl Header { where V: DeserializeOwned, { - serde_json::from_value(self.inner.value()) + V::deserialize(&self.inner.value()) } /// Returns the parameter with the provided key converted into the type `P`. @@ -91,7 +91,7 @@ impl Header { .take_parameter(key) .unwrap_or(serde_json::Value::Null); - serde_json::from_value(parameter) + P::deserialize(¶meter) } /// Returns the parameter with the provided key converted into the type `P` @@ -105,7 +105,7 @@ impl Header { { self.inner .take_parameter(key) - .map(serde_json::from_value) + .map(|v| P::deserialize(&v)) .unwrap_or_else(|| Ok(P::default())) } diff --git a/libp2p-comit/src/frame/request.rs b/libp2p-comit/src/frame/request.rs index b3f0dd7403..8015742242 100644 --- a/libp2p-comit/src/frame/request.rs +++ b/libp2p-comit/src/frame/request.rs @@ -145,7 +145,7 @@ impl Request { where B: DeserializeOwned, { - B::deserialize(self.body) + B::deserialize(&self.body) } } diff --git a/libp2p-comit/src/substream/inbound.rs b/libp2p-comit/src/substream/inbound.rs index c3600a8089..682b2bd169 100644 --- a/libp2p-comit/src/substream/inbound.rs +++ b/libp2p-comit/src/substream/inbound.rs @@ -7,6 +7,7 @@ use crate::{ }; use futures::{channel::oneshot, task::Poll, Future, Sink, Stream}; use libp2p::swarm::ProtocolsHandlerEvent; +use serde::Deserialize; use std::{ collections::{HashMap, HashSet}, pin::Pin, @@ -52,23 +53,22 @@ impl Advance for State { WaitingMessage { mut stream } => match stream.as_mut().poll_next(cx) { Poll::Ready(Some(Ok(frame))) => match frame.kind { FrameKind::Request => { - let request = - serde_json::from_value::(frame.payload) - .map_err(handler::Error::MalformedFrame) - .and_then(|request| { - known_headers - .get(request.request_type()) - .ok_or_else(|| { - handler::Error::UnknownRequestType( - request.request_type().to_owned(), - ) - }) - .and_then(|known_headers| { - request - .ensure_no_unknown_mandatory_headers(known_headers) - .map_err(handler::Error::UnknownMandatoryHeader) - }) - }); + let request = UnvalidatedInboundRequest::deserialize(&frame.payload) + .map_err(handler::Error::MalformedFrame) + .and_then(|request| { + known_headers + .get(request.request_type()) + .ok_or_else(|| { + handler::Error::UnknownRequestType( + request.request_type().to_owned(), + ) + }) + .and_then(|known_headers| { + request + .ensure_no_unknown_mandatory_headers(known_headers) + .map_err(handler::Error::UnknownMandatoryHeader) + }) + }); match request { Ok(request) => { diff --git a/libp2p-comit/src/substream/outbound.rs b/libp2p-comit/src/substream/outbound.rs index f8164a316c..aaf4f8b569 100644 --- a/libp2p-comit/src/substream/outbound.rs +++ b/libp2p-comit/src/substream/outbound.rs @@ -7,6 +7,7 @@ use crate::{ }; use futures::{channel::oneshot, Sink, Stream}; use libp2p::swarm::ProtocolsHandlerEvent; +use serde::Deserialize; use std::{ collections::{HashMap, HashSet}, pin::Pin, @@ -85,7 +86,7 @@ impl Advance for State { } => match stream.as_mut().poll_next(cx) { Poll::Ready(Some(Ok(frame))) => { let response = match frame.kind { - FrameKind::Response => serde_json::from_value(frame.payload), + FrameKind::Response => Response::deserialize(&frame.payload), FrameKind::Request => { return Advanced::error(stream, handler::Error::UnexpectedFrame(frame)) } From 06470e8b522aa0b17199a681b2a08ea2e7463e22 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 7 Apr 2020 14:12:55 +0000 Subject: [PATCH 52/88] Bump tracing-subscriber from 0.2.3 to 0.2.4 Bumps [tracing-subscriber](https://github.com/tokio-rs/tracing) from 0.2.3 to 0.2.4. - [Release notes](https://github.com/tokio-rs/tracing/releases) - [Commits](https://github.com/tokio-rs/tracing/compare/tracing-subscriber-0.2.3...tracing-subscriber-0.2.4) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bac3dc12df..a4b3d131bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3463,9 +3463,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dedebcf5813b02261d6bab3a12c6a8ae702580c0405a2e8ec16c3713caf14c20" +checksum = "cfc50df245be6f0adf35c399cb16dea60e2c7d6cc83ff5dc22d727df06dd6f0c" dependencies = [ "ansi_term", "chrono", From acafdcbb2707912448b806ce2bc7d585895210fb Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 7 Apr 2020 14:13:20 +0000 Subject: [PATCH 53/88] Bump async-trait from 0.1.29 to 0.1.30 Bumps [async-trait](https://github.com/dtolnay/async-trait) from 0.1.29 to 0.1.30. - [Release notes](https://github.com/dtolnay/async-trait/releases) - [Commits](https://github.com/dtolnay/async-trait/compare/0.1.29...0.1.30) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bac3dc12df..8672acdac2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -164,9 +164,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab5c215748dc1ad11a145359b1067107ae0f8ca5e99844fa64067ed5bf198e3" +checksum = "da71fef07bc806586090247e971229289f64c210a278ee5ae419314eb386b31d" dependencies = [ "proc-macro2 1.0.10", "quote 1.0.3", From e9bde50490bf7212189f14ab0a587114e8ec9fdf Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 7 Apr 2020 15:53:23 +0000 Subject: [PATCH 54/88] Bump async-mutex from 0.1.4 to 0.2.1 in /api_tests Bumps [async-mutex](https://github.com/DirtyHairy/async-mutex) from 0.1.4 to 0.2.1. - [Release notes](https://github.com/DirtyHairy/async-mutex/releases) - [Changelog](https://github.com/DirtyHairy/async-mutex/blob/master/CHANGELOG.md) - [Commits](https://github.com/DirtyHairy/async-mutex/compare/v0.1.4...v0.2.1) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 6e91f891a2..13549cf425 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -32,7 +32,7 @@ "@types/tail": "^2.0.0", "@types/tmp": "^0.1.0", "@wcjiang/whereis": "^1.0.0", - "async-mutex": "^0.1.4", + "async-mutex": "^0.2.1", "bcoin": "https://github.com/bcoin-org/bcoin#2496acc7a98a43f00a7b5728eb256877c1bbf001", "bignumber.js": "^9.0.0", "bitcoin-core": "^3.0.0", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 468eaa692a..c2b2a8d094 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -842,10 +842,12 @@ astral-regex@^1.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== -async-mutex@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.1.4.tgz#a47d1eebf584f7dcdd760e3642dc2c58613bef5c" - integrity sha512-zVWTmAnxxHaeB2B1te84oecI8zTDJ/8G49aVBblRX6be0oq6pAybNcUSxwfgVOmOjSCvN4aYZAqwtyNI8e1YGw== +async-mutex@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.2.1.tgz#ffa0bc669f54f7692812b0ce83de487564677c08" + integrity sha512-8GAyGD9/Fr4TgMigfCAXsyjvPturIqHDDw7Mim6DtNRbwxY2ul/D4b4CF1qjaMvomd/SJs/8EM23M+RGDEpaKA== + dependencies: + tslib "^1.11.1" asynckit@^0.4.0: version "0.4.0" @@ -4965,10 +4967,10 @@ ts-protoc-gen@^0.8.0: dependencies: google-protobuf "^3.6.1" -tslib@^1.10.0, tslib@^1.8.1: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== +tslib@^1.10.0, tslib@^1.11.1, tslib@^1.8.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" + integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== tslint-config-prettier@^1.18.0: version "1.18.0" From 2a3cf714a4b5e58eb0e34d33a2947dfd358c3053 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Mon, 6 Apr 2020 10:51:32 +1000 Subject: [PATCH 55/88] Improve Ethereum diagnostics In order to assist debugging, add a levenshtein distance calculation and warn if we try to match against a transaction that is 'close'. While we are at it add appropriate tracing spans. --- Cargo.lock | 7 ++ cnd/Cargo.toml | 1 + cnd/src/btsieve/ethereum.rs | 91 ++++++++++++++----- cnd/src/ethereum.rs | 6 ++ .../rfc003/ethereum/htlc_events.rs | 18 +++- 5 files changed, 98 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bac3dc12df..1e42e5ee75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -500,6 +500,7 @@ dependencies = [ "http-api-problem", "impl-template", "lazy_static", + "levenshtein", "libp2p", "libp2p-comit", "libsqlite3-sys", @@ -1540,6 +1541,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "levenshtein" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66189c12161c65c0023ceb53e2fccc0013311bcb36a7cbd0f9c5e938b408ac96" + [[package]] name = "lexical-core" version = "0.4.6" diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index 9b471b2bf5..995b4754be 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -29,6 +29,7 @@ hex = "0.4" http-api-problem = { version = "0.15", features = ["with_warp"] } impl-template = "1.0.0-alpha" lazy_static = "1" +levenshtein = "1" libp2p = { version = "0.17", default-features = false, features = ["tcp", "secio", "yamux", "mplex", "mdns", "dns"] } libp2p-comit = { path = "../libp2p-comit" } libsqlite3-sys = { version = ">=0.8.0, <0.13.0", features = ["bundled"] } diff --git a/cnd/src/btsieve/ethereum.rs b/cnd/src/btsieve/ethereum.rs index 92823d186b..bfb46b2b4b 100644 --- a/cnd/src/btsieve/ethereum.rs +++ b/cnd/src/btsieve/ethereum.rs @@ -41,7 +41,7 @@ impl PreviousBlockHash for Block { pub async fn watch_for_contract_creation( blockchain_connector: &C, start_of_swap: NaiveDateTime, - bytecode: Bytes, + bytecode: &Bytes, ) -> anyhow::Result<(Transaction, Address)> where C: LatestBlock + BlockByHash + ReceiptByHash, @@ -50,7 +50,32 @@ where matching_transaction_and_receipt(blockchain_connector, start_of_swap, |transaction| { // transaction.to address is None if, and only if, the transaction // creates a contract. - transaction.to.is_none() && transaction.input == bytecode + + let is_contract_creation = transaction.to.is_none(); + let is_expected_contract = &transaction.input == bytecode; + + if !is_contract_creation { + tracing::trace!("rejected because transaction doesn't create a contract"); + } + + if !is_expected_contract { + tracing::trace!("rejected because contract code doesn't match"); + + // only compute levenshtein distance if we are on trace level, converting to hex is expensive at this scale + if tracing::level_enabled!(tracing::level_filters::LevelFilter::TRACE) { + let actual = hex::encode(&transaction.input); + let expected = hex::encode(&bytecode); + + let distance = levenshtein::levenshtein(&actual, &expected); + + // We probably need to find a meaningful value here, expiry is 4 bytes. + if distance < 10 { + tracing::warn!("found contract with slightly different parameters (levenshtein-distance < 10), this could be a bug!") + } + } + } + + is_contract_creation && is_expected_contract }) .await?; @@ -124,19 +149,33 @@ where loop { match block_generator.async_resume().await { GeneratorState::Yielded(block) => { + let block_hash = block + .hash + .ok_or_else(|| anyhow::anyhow!("block without hash"))?; + + let span = + tracing::trace_span!("new_block", blockhash = format_args!("{:x}", block_hash)); + let _enter = span.enter(); + + tracing::trace!("checking {} transactions", block.transactions.len()); + for transaction in block.transactions.into_iter() { + let tx_hash = transaction.hash; + let span = tracing::trace_span!( + "matching_transaction", + txhash = format_args!("{:x}", tx_hash) + ); + let _enter = span.enter(); + if matcher(&transaction) { - let receipt = fetch_receipt(connector, transaction.hash).await?; + let receipt = fetch_receipt(connector, tx_hash).await?; if !receipt.is_status_ok() { // This can be caused by a failed attempt to complete an action, // for example, sending a transaction with low gas. - tracing::warn!( - "transaction matched {:x} but status was NOT OK", - transaction.hash, - ); + tracing::warn!("transaction matched but status was NOT OK"); continue; } - tracing::trace!("transaction matched {:x}", transaction.hash,); + tracing::info!("transaction matched"); return Ok((transaction, receipt)); } } @@ -170,6 +209,10 @@ where .hash .ok_or_else(|| anyhow::anyhow!("block without hash"))?; + let span = + tracing::trace_span!("new_block", blockhash = format_args!("{:x}", block_hash)); + let _enter = span.enter(); + let maybe_contains_transaction = topics.iter().all(|topic| { topic.as_ref().map_or(true, |topic| { block @@ -179,31 +222,37 @@ where }); if !maybe_contains_transaction { tracing::trace!( - "bloom filter indicates that block does not contain transaction: - {:x}", - block_hash, + "bloom filter indicates that this block will not contain an instance of the event" + ); continue; + } else { + tracing::trace!( + "bloom filter indicates that this block might contain an instance of the event" + ); } - tracing::trace!( - "bloom filter indicates that we should check the block for transactions: {:x}", - block_hash, - ); + tracing::trace!("checking {} transactions", block.transactions.len()); + for transaction in block.transactions.into_iter() { - let receipt = fetch_receipt(connector, transaction.hash).await?; + let tx_hash = transaction.hash; + + let span = tracing::trace_span!( + "matching_transaction", + txhash = format_args!("{:x}", tx_hash) + ); + let _enter = span.enter(); + + let receipt = fetch_receipt(connector, tx_hash).await?; let status_is_ok = receipt.is_status_ok(); if let Some(log) = matcher(receipt) { if !status_is_ok { // This can be caused by a failed attempt to complete an action, // for example, sending a transaction with low gas. - tracing::warn!( - "transaction matched {:x} but status was NOT OK", - transaction.hash, - ); + tracing::warn!("transaction matched but status was NOT OK"); continue; } - tracing::trace!("transaction matched {:x}", transaction.hash,); + tracing::info!("transaction matched"); return Ok((transaction, log)); } } diff --git a/cnd/src/ethereum.rs b/cnd/src/ethereum.rs index 7177f0098f..0b87d4f24a 100644 --- a/cnd/src/ethereum.rs +++ b/cnd/src/ethereum.rs @@ -77,6 +77,12 @@ pub struct Block { #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct Bytes(#[serde(with = "SerHexSeq::")] pub Vec); +impl AsRef<[u8]> for Bytes { + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } +} + impl>> From for Bytes { fn from(data: T) -> Self { Bytes(data.into()) diff --git a/cnd/src/swap_protocols/rfc003/ethereum/htlc_events.rs b/cnd/src/swap_protocols/rfc003/ethereum/htlc_events.rs index 63bd684da1..4f79bac37e 100644 --- a/cnd/src/swap_protocols/rfc003/ethereum/htlc_events.rs +++ b/cnd/src/swap_protocols/rfc003/ethereum/htlc_events.rs @@ -80,9 +80,14 @@ impl htlc_params: &HtlcParams, start_of_swap: NaiveDateTime, ) -> anyhow::Result> { + let expected_bytecode = htlc_params.bytecode(); + let (transaction, location) = - watch_for_contract_creation(self, start_of_swap, htlc_params.bytecode()) - .instrument(tracing::info_span!("htlc_deployed")) + watch_for_contract_creation(self, start_of_swap, &expected_bytecode) + .instrument(tracing::trace_span!( + "htlc_deployed", + expected_bytecode = %hex::encode(&expected_bytecode.0) + )) .await?; Ok(Deployed { @@ -215,9 +220,14 @@ impl htlc_params: &HtlcParams, start_of_swap: NaiveDateTime, ) -> anyhow::Result> { + let expected_bytecode = htlc_params.clone().bytecode(); + let (transaction, location) = - watch_for_contract_creation(self, start_of_swap, htlc_params.clone().bytecode()) - .instrument(tracing::info_span!("htlc_deployed")) + watch_for_contract_creation(self, start_of_swap, &expected_bytecode) + .instrument(tracing::trace_span!( + "htlc_deployed", + expected_bytecode = %hex::encode(&expected_bytecode.0) + )) .await?; Ok(Deployed { From 43f81daa4948de0a4cd5ce4be2e96f0f3bc6a085 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 18 Mar 2020 12:37:33 +1100 Subject: [PATCH 56/88] Pass around config for Lnd instead of an instance Turns out, we only use the instance to get the data out again! --- api_tests/src/e2e_test_environment.ts | 6 ++---- api_tests/src/ledgers/lightning.ts | 6 +++--- api_tests/src/ledgers/lnd_instance.ts | 21 +++------------------ api_tests/src/wallets/lightning.ts | 18 +++++++----------- 4 files changed, 15 insertions(+), 36 deletions(-) diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index 6bb80fe09c..df2949ef80 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -217,8 +217,7 @@ export default class E2ETestEnvironment extends NodeEnvironment { this.logger ), this.logger, - this.aliceLightning.config.lnd, - this.aliceLightning.config.p2pSocket + this.aliceLightning.config ); this.global.ledgerConfigs.aliceLnd = this.aliceLightning.config; @@ -246,8 +245,7 @@ export default class E2ETestEnvironment extends NodeEnvironment { this.logger ), this.logger, - this.bobLightning.config.lnd, - this.bobLightning.config.p2pSocket + this.bobLightning.config ); this.global.ledgerConfigs.bobLnd = this.bobLightning.config; diff --git a/api_tests/src/ledgers/lightning.ts b/api_tests/src/ledgers/lightning.ts index 94b102fafe..b655df3778 100644 --- a/api_tests/src/ledgers/lightning.ts +++ b/api_tests/src/ledgers/lightning.ts @@ -1,4 +1,3 @@ -import { Lnd } from "comit-sdk"; import LedgerInstance from "./ledger_instance"; /** @@ -37,8 +36,9 @@ export interface LightningInstance { export interface LightningNodeConfig { p2pSocket: string; - // sucks that we have to leak here that the instance is LND under the hood but we can't do much about that :) - lnd: Lnd; + grpcSocket: string; + tlsCertPath: string; + macaroonPath: string; restPort: number; dataDir: string; } diff --git a/api_tests/src/ledgers/lnd_instance.ts b/api_tests/src/ledgers/lnd_instance.ts index e171c1883a..1ea2de7456 100644 --- a/api_tests/src/ledgers/lnd_instance.ts +++ b/api_tests/src/ledgers/lnd_instance.ts @@ -10,8 +10,6 @@ import { Logger } from "log4js"; export class LndInstance implements LightningInstance { private process: ChildProcess; - public lnd: Lnd; - private publicKey?: string; public static async new( dataDir: string, @@ -69,11 +67,6 @@ export class LndInstance implements LightningInstance { "LNWL: Done catching up block hashes" ); - await this.initAuthenticatedLndConnection(); - - this.publicKey = (await this.lnd.lnrpc.getInfo()).identityPubkey; - this.logger.info("lnd is ready:", this.publicKey); - this.logger.debug("lnd started with PID", this.process.pid); } @@ -117,16 +110,6 @@ export class LndInstance implements LightningInstance { this.logger.debug("Lnd wallet initialized!"); } - private async initAuthenticatedLndConnection() { - const config = { - server: this.grpcSocket, - tls: this.tlsCertPath(), - macaroonPath: this.adminMacaroonPath(), - }; - - this.lnd = await Lnd.init(config); - } - public async stop() { this.logger.debug("Stopping lnd instance"); this.process.kill("SIGTERM"); @@ -187,7 +170,9 @@ export class LndInstance implements LightningInstance { get config(): LightningNodeConfig { return { p2pSocket: this.p2pSocket, - lnd: this.lnd, + grpcSocket: this.grpcSocket, + tlsCertPath: this.tlsCertPath(), + macaroonPath: this.adminMacaroonPath(), restPort: this.restPort, dataDir: this.dataDir, }; diff --git a/api_tests/src/wallets/lightning.ts b/api_tests/src/wallets/lightning.ts index 52c51046e6..31d0bda308 100644 --- a/api_tests/src/wallets/lightning.ts +++ b/api_tests/src/wallets/lightning.ts @@ -3,26 +3,22 @@ import { Asset } from "../asset"; import BigNumber from "bignumber.js"; import { BitcoinWallet } from "./bitcoin"; import { sleep } from "../utils"; -import { - LightningWallet as LightningWalletSdk, - Lnd, - Outpoint, -} from "comit-sdk"; +import { LightningWallet as LightningWalletSdk, Outpoint } from "comit-sdk"; import { AddressType } from "@radar/lnrpc"; import { Logger } from "log4js"; +import { LightningNodeConfig } from "../ledgers/lightning"; export class LightningWallet implements Wallet { public static async newInstance( bitcoinWallet: BitcoinWallet, logger: Logger, - lnd: Lnd, - lndp2pSocket: string + config: LightningNodeConfig ) { const inner = await LightningWalletSdk.newInstance( - lnd.config.tls, - lnd.config.macaroonPath, - lnd.config.server, - lndp2pSocket + config.tlsCertPath, + config.macaroonPath, + config.grpcSocket, + config.p2pSocket ); logger.debug("lnd getinfo:", await inner.lnd.lnrpc.getInfo()); From ba30f8725d6e26266e8761c9c94f0461882fd1de Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 18 Mar 2020 15:54:35 +1100 Subject: [PATCH 57/88] Actually check for minting to be successful 1. There was a bug in the previous code where we used `minus` instead of `plus`. 2. We can just use `.wait` here to do the same thing. --- api_tests/src/wallets/ethereum.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/api_tests/src/wallets/ethereum.ts b/api_tests/src/wallets/ethereum.ts index 3917f2ae6e..5fde0f590b 100644 --- a/api_tests/src/wallets/ethereum.ts +++ b/api_tests/src/wallets/ethereum.ts @@ -2,7 +2,7 @@ import { BigNumber, EthereumWallet as EthereumWalletSdk } from "comit-sdk"; import { Asset } from "comit-sdk"; import { ethers } from "ethers"; import { BigNumber as BigNumberEthers } from "ethers/utils"; -import { pollUntilMinted, Wallet } from "./index"; +import { Wallet } from "./index"; import { TransactionRequest } from "ethers/providers"; import { HarnessGlobal, sleep } from "../utils"; import { Logger } from "log4js"; @@ -88,22 +88,23 @@ export class EthereumWallet implements Wallet { } private async mintEther(asset: Asset): Promise { - const startingBalance = await this.getBalanceByAsset(asset); const minimumExpectedBalance = asset.quantity; // make sure we have at least twice as much const value = new BigNumberEthers(minimumExpectedBalance).mul(2); - await this.sendTransaction({ + const response = await this.sendTransaction({ to: this.account(), value, gasLimit: 21000, }); - await pollUntilMinted( - this, - startingBalance.minus(new BigNumber(minimumExpectedBalance)), - asset - ); + await response.wait(1); + + const balance = await this.getBalanceByAsset(asset); + + if (balance.lte(minimumExpectedBalance)) { + throw new Error("Failed to mint Ether"); + } this.logger.info("Minted", asset.quantity, "ether for", this.account()); } From 96e5b711197d2301f1bc618d6ea08f022977c7e9 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 18 Mar 2020 15:04:37 +1100 Subject: [PATCH 58/88] Document why we generate 101 blocks --- api_tests/src/ledgers/bitcoin.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/api_tests/src/ledgers/bitcoin.ts b/api_tests/src/ledgers/bitcoin.ts index 819cfb71f9..0c019a4c6b 100644 --- a/api_tests/src/ledgers/bitcoin.ts +++ b/api_tests/src/ledgers/bitcoin.ts @@ -27,6 +27,7 @@ export default class BitcoinLedger implements LedgerInstance { password, }); + // only coins after the first 101 are spendable await client.generateToAddress(101, await client.getNewAddress()); const miner = setInterval(async () => { From 4aa6f3dd22cf078e44597b949824aa98ce21dbd4 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 23 Mar 2020 19:30:07 +1100 Subject: [PATCH 59/88] Remove dead LndInstance from Actor class This is a left-over from previous times and no longer needed. --- api_tests/src/actors/actor.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/api_tests/src/actors/actor.ts b/api_tests/src/actors/actor.ts index 1c67a7da49..93bf8c8166 100644 --- a/api_tests/src/actors/actor.ts +++ b/api_tests/src/actors/actor.ts @@ -19,7 +19,6 @@ import { Ledger, LedgerKind } from "../ledgers/ledger"; import { LedgerConfig, sleep } from "../utils"; import { Wallet, Wallets } from "../wallets"; import { Actors } from "./index"; -import { LndInstance } from "../ledgers/lnd_instance"; import { sha256 } from "js-sha256"; import { InvoiceState } from "@radar/lnrpc"; import { @@ -80,8 +79,6 @@ export class Actor { private readonly startingBalances: Map; private readonly expectedBalanceChanges: Map; - public lndInstance: LndInstance; - constructor( private readonly logger: Logger, private readonly cndInstance: CndInstance, @@ -582,9 +579,6 @@ export class Actor { public async stop() { this.logger.debug("Stopping actor"); this.cndInstance.stop(); - if (this.lndInstance && this.lndInstance.isRunning()) { - await this.lndInstance.stop(); - } } public async restart() { From e19da98ab72d66c938d93a4952e70e83982bbb15 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 18 Mar 2020 17:21:36 +1100 Subject: [PATCH 60/88] Wait for log files to exist before search for lines In some cases, we ran into errors where the log reader tried to read the file before it existed. Additionally, the design of `LogReader` suggested that its instance can actually be reuse, which is false. If the line we are looking for has been emitted in the log file before we start looking for it, we never find it. We circumvent both problems by removing the LogReader alltogether and only exposing a single function. --- api_tests/src/cnd/cnd_instance.ts | 5 ++- api_tests/src/ledgers/bitcoind_instance.ts | 5 ++- api_tests/src/ledgers/lnd_instance.ts | 19 +++-------- api_tests/src/ledgers/log_reader.ts | 39 ---------------------- api_tests/src/ledgers/parity_instance.ts | 5 ++- api_tests/src/wait_for_log_message.ts | 38 +++++++++++++++++++++ 6 files changed, 49 insertions(+), 62 deletions(-) delete mode 100644 api_tests/src/ledgers/log_reader.ts create mode 100644 api_tests/src/wait_for_log_message.ts diff --git a/api_tests/src/cnd/cnd_instance.ts b/api_tests/src/cnd/cnd_instance.ts index 00a6927c56..7326442097 100644 --- a/api_tests/src/cnd/cnd_instance.ts +++ b/api_tests/src/cnd/cnd_instance.ts @@ -5,7 +5,7 @@ import tempWrite from "temp-write"; import { promisify } from "util"; import { CndConfigFile } from "../config"; import { sleep } from "../utils"; -import { LogReader } from "../ledgers/log_reader"; +import waitForLogMessage from "../wait_for_log_message"; import { Logger } from "log4js"; const openAsync = promisify(fs.open); @@ -45,8 +45,7 @@ export class CndInstance { ], }); - const logReader = new LogReader(this.logFile); - await logReader.waitForLogMessage("Starting HTTP server on"); + await waitForLogMessage(this.logFile, "Starting HTTP server on"); // we emit the log _before_ we start the http server, let's make sure it actually starts up await sleep(1000); diff --git a/api_tests/src/ledgers/bitcoind_instance.ts b/api_tests/src/ledgers/bitcoind_instance.ts index ed3592b938..3a63424192 100644 --- a/api_tests/src/ledgers/bitcoind_instance.ts +++ b/api_tests/src/ledgers/bitcoind_instance.ts @@ -1,11 +1,11 @@ import { ChildProcess, spawn } from "child_process"; import * as fs from "fs"; -import { LogReader } from "./log_reader"; import * as path from "path"; import { openAsync, writeFileAsync } from "../utils"; import getPort from "get-port"; import { BitcoinInstance, BitcoinNodeConfig } from "./bitcoin"; import { Logger } from "log4js"; +import waitForLogMessage from "../wait_for_log_message"; export class BitcoindInstance implements BitcoinInstance { private process: ChildProcess; @@ -72,8 +72,7 @@ export class BitcoindInstance implements BitcoinInstance { ); }); - const logReader = new LogReader(this.logPath()); - await logReader.waitForLogMessage("init message: Done loading"); + await waitForLogMessage(this.logPath(), "init message: Done loading"); const result = fs.readFileSync( path.join(this.dataDir, "regtest", ".cookie"), diff --git a/api_tests/src/ledgers/lnd_instance.ts b/api_tests/src/ledgers/lnd_instance.ts index 1ea2de7456..4357c28d72 100644 --- a/api_tests/src/ledgers/lnd_instance.ts +++ b/api_tests/src/ledgers/lnd_instance.ts @@ -2,7 +2,7 @@ import { ChildProcess, spawn } from "child_process"; import { waitUntilFileExists, writeFileAsync } from "../utils"; import * as path from "path"; import getPort from "get-port"; -import { LogReader } from "./log_reader"; +import waitForLogMessage from "../wait_for_log_message"; import { Lnd } from "comit-sdk"; import whereis from "@wcjiang/whereis"; import { LightningInstance, LightningNodeConfig } from "./lightning"; @@ -43,18 +43,15 @@ export class LndInstance implements LightningInstance { await this.execBinary(); - this.logger.debug("Waiting for lnd log file to exist:", this.logPath()); - await waitUntilFileExists(this.logPath()); + const logFile = this.logPath(); this.logger.debug("Waiting for lnd password RPC server"); - await this.logReader().waitForLogMessage( - "RPCS: password RPC server listening" - ); + await waitForLogMessage(logFile, "RPCS: password RPC server listening"); await this.initWallet(); this.logger.debug("Waiting for lnd unlocked RPC server"); - await this.logReader().waitForLogMessage("RPCS: RPC server listening"); + await waitForLogMessage(logFile, "RPCS: RPC server listening"); this.logger.debug( "Waiting for admin macaroon file to exist:", @@ -63,9 +60,7 @@ export class LndInstance implements LightningInstance { await waitUntilFileExists(this.adminMacaroonPath()); this.logger.debug("Waiting for lnd to catch up with blocks"); - await this.logReader().waitForLogMessage( - "LNWL: Done catching up block hashes" - ); + await waitForLogMessage(logFile, "LNWL: Done catching up block hashes"); this.logger.debug("lnd started with PID", this.process.pid); } @@ -210,8 +205,4 @@ bitcoind.dir=${this.bitcoindDataDir} const config = path.join(this.dataDir, "lnd.conf"); await writeFileAsync(config, output); } - - private logReader() { - return new LogReader(this.logPath()); - } } diff --git a/api_tests/src/ledgers/log_reader.ts b/api_tests/src/ledgers/log_reader.ts deleted file mode 100644 index 5ae8769d0b..0000000000 --- a/api_tests/src/ledgers/log_reader.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Tail } from "tail"; - -export class LogReader { - private tail: Tail; - - constructor(logFile: string) { - // By default tail uses `fs.watch` that watches the inode - // However, it looks like on Mac OS, the inode get changed at some point - // To counter that then we use `fs.watchFile` which is actually considered - // less efficient. Hence only using it on Mac. - const useWatchFile = process.platform === "darwin" ? true : false; - - const options = { fromBeginning: true, follow: true, useWatchFile }; - this.tail = new Tail(logFile, options); - } - - public async waitForLogMessage(line: string) { - await this.findTextInLog(line); - this.unwatch(); - } - - private async findTextInLog(text: string) { - return new Promise((resolve, reject) => { - this.tail.on("line", (data: string) => { - if (data.includes(text)) { - resolve(); - } - }); - - this.tail.on("error", (err: any) => { - reject(err); - }); - }); - } - - private unwatch() { - this.tail.unwatch(); - } -} diff --git a/api_tests/src/ledgers/parity_instance.ts b/api_tests/src/ledgers/parity_instance.ts index 79d1081ed2..afdba240f4 100644 --- a/api_tests/src/ledgers/parity_instance.ts +++ b/api_tests/src/ledgers/parity_instance.ts @@ -1,7 +1,7 @@ import { ChildProcess, spawn } from "child_process"; import * as fs from "fs"; import tmp from "tmp"; -import { LogReader } from "./log_reader"; +import waitForLogMessage from "../wait_for_log_message"; import { promisify } from "util"; import { sleep } from "../utils"; import getPort from "get-port"; @@ -77,8 +77,7 @@ export class ParityInstance implements EthereumInstance { ); }); - const logReader = new LogReader(this.logFile); - await logReader.waitForLogMessage("Public node URL:"); + await waitForLogMessage(this.logFile, "Public node URL:"); this.logger.info("parity started with PID", this.process.pid); } diff --git a/api_tests/src/wait_for_log_message.ts b/api_tests/src/wait_for_log_message.ts new file mode 100644 index 0000000000..521e2fcd6a --- /dev/null +++ b/api_tests/src/wait_for_log_message.ts @@ -0,0 +1,38 @@ +import { Tail } from "tail"; +import { timeout, waitUntilFileExists } from "./utils"; + +export default async function waitForLogMessage(logFile: string, line: string) { + await timeout(10000, waitUntilFileExists(logFile)); + + // By default tail uses `fs.watch` that watches the inode + // However, it looks like on Mac OS, the inode get changed at some point + // To counter that then we use `fs.watchFile` which is actually considered + // less efficient. Hence only using it on Mac. + const useWatchFile = process.platform === "darwin" ? true : false; + + const options = { + fromBeginning: true, + follow: true, + useWatchFile, + }; + + const tail = new Tail(logFile, options); + + await timeout(60000, findTextInLog(tail, line)); + + tail.unwatch(); +} + +async function findTextInLog(tail: Tail, text: string) { + return new Promise((resolve, reject) => { + tail.on("line", (data: string) => { + if (data.includes(text)) { + resolve(); + } + }); + + tail.on("error", (err: any) => { + reject(err); + }); + }); +} From 1ee06ecea26237bbc6ad6139196fa0402f55e71c Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 23 Mar 2020 19:37:02 +1100 Subject: [PATCH 61/88] Update parity to version 2.7.2 and start it with --force-direct Parity has an auto-update mechanism where it actually downloads the latest version and executes that binary instead of the current one. It spawning a new process makes it impossible for us to kill it with the PID we got from starting it. The latest version (2.7.2 at this stage), seems to allow us to circumvent this probem with the --force-direct flag. --- api_tests/src/ledgers/parity_instance.ts | 2 ++ blockchain_nodes/ensure_parity.sh | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/api_tests/src/ledgers/parity_instance.ts b/api_tests/src/ledgers/parity_instance.ts index afdba240f4..f0715e9e93 100644 --- a/api_tests/src/ledgers/parity_instance.ts +++ b/api_tests/src/ledgers/parity_instance.ts @@ -48,6 +48,8 @@ export class ParityInstance implements EthereumInstance { this.process = spawn( bin, [ + `--force-direct`, + `--no-download`, `--config=${this.projectRoot}/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/config.toml`, `--chain=${this.projectRoot}/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chain.json`, `--base-path=${this.projectRoot}/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum`, diff --git a/blockchain_nodes/ensure_parity.sh b/blockchain_nodes/ensure_parity.sh index 382730e5aa..944ac5a22f 100755 --- a/blockchain_nodes/ensure_parity.sh +++ b/blockchain_nodes/ensure_parity.sh @@ -3,8 +3,8 @@ set -e case "$OSTYPE" in - darwin*) OS="OSX"; url="https://releases.parity.io/ethereum/v2.5.9/x86_64-apple-darwin/parity";; - linux*) OS="Linux"; url="https://releases.parity.io/ethereum/v2.5.9/x86_64-unknown-linux-gnu/parity";; + darwin*) OS="OSX"; url="https://releases.parity.io/ethereum/v2.7.2/x86_64-apple-darwin/parity";; + linux*) OS="Linux"; url="https://releases.parity.io/ethereum/v2.7.2/x86_64-unknown-linux-gnu/parity";; *) echo "unknown: $OSTYPE. Sorry, this is currently not supported"; exit 1 ;; esac From c5014addc4dae79487eae5e9e5cc9bec8b620c75 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 23 Mar 2020 19:40:18 +1100 Subject: [PATCH 62/88] Use standard bitcoind logfile Bitcoind already logs to a file, there is not need for us to capture stdout and print it to a file again. --- api_tests/src/ledgers/bitcoind_instance.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/api_tests/src/ledgers/bitcoind_instance.ts b/api_tests/src/ledgers/bitcoind_instance.ts index 3a63424192..0a5a143a6d 100644 --- a/api_tests/src/ledgers/bitcoind_instance.ts +++ b/api_tests/src/ledgers/bitcoind_instance.ts @@ -1,7 +1,7 @@ import { ChildProcess, spawn } from "child_process"; import * as fs from "fs"; import * as path from "path"; -import { openAsync, writeFileAsync } from "../utils"; +import { writeFileAsync } from "../utils"; import getPort from "get-port"; import { BitcoinInstance, BitcoinNodeConfig } from "./bitcoin"; import { Logger } from "log4js"; @@ -53,14 +53,9 @@ export class BitcoindInstance implements BitcoinInstance { await this.createConfigFile(this.dataDir); - const log = this.logPath(); this.process = spawn(bin, [`-datadir=${this.dataDir}`], { cwd: this.projectRoot, - stdio: [ - "ignore", // stdin - await openAsync(log, "w"), // stdout - await openAsync(log, "w"), // stderr - ], + stdio: "ignore", }); this.process.on("exit", (code: number, signal: number) => { @@ -106,7 +101,7 @@ export class BitcoindInstance implements BitcoinInstance { } private logPath() { - return path.join(this.dataDir, "bitcoind.log"); + return path.join(this.dataDir, "regtest", "debug.log"); } public getDataDir() { From 5c2f4e06f24c84c751af76f906808b1d5310b8d0 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 17 Mar 2020 19:03:29 +1100 Subject: [PATCH 63/88] Only start one instance of Parity, Bitcoind and one lnd per actor By utilizing file-locks on directories, we can ensure that any number of parallel test suites only ever get to run one instance of the ledger. The remaining test suites will take the config and pass that to the tests. We store the PID of each ledger in a file inside the lock directory, this also includes a sub-process that we spawn for the Bitcoin miner. This is important, because same as with the other nodes, this process must keep going until the last test executed. To cleanup our environment, we kill all processes with PIDs that we find in those PID files before and after we execute the tests, just in case if we for some reason did not exit cleanly and failed to cleanup after ourselves. --- api_tests/.gitignore | 2 + api_tests/.prettierignore | 1 + api_tests/jest.config-e2e.js | 12 - .../{jest.config-dry.js => jest.config.js} | 9 +- api_tests/package.json | 12 +- api_tests/src/actor_test.ts | 2 +- api_tests/src/bitcoin_miner.ts | 31 ++ api_tests/src/config.ts | 8 +- api_tests/src/create_actors.ts | 8 +- api_tests/src/dry_test_environment.ts | 106 ----- api_tests/src/e2e_test_environment.ts | 311 -------------- api_tests/src/environment/kill_nodes.ts | 29 ++ api_tests/src/environment/setup.ts | 25 ++ api_tests/src/environment/teardown.ts | 14 + api_tests/src/ledgers/bitcoin.ts | 73 ---- .../src/ledgers/bitcoin_miner_instance.ts | 41 ++ api_tests/src/ledgers/bitcoind_instance.ts | 17 +- api_tests/src/ledgers/ethereum.ts | 60 --- api_tests/src/ledgers/index.ts | 28 ++ api_tests/src/ledgers/ledger_instance.ts | 11 - api_tests/src/ledgers/ledger_lock.ts | 22 + api_tests/src/ledgers/lightning.ts | 44 -- api_tests/src/ledgers/lnd_instance.ts | 28 +- api_tests/src/ledgers/parity_instance.ts | 21 +- api_tests/src/test_environment.ts | 398 ++++++++++++++++++ api_tests/src/utils.ts | 14 +- api_tests/src/wait_for_log_message.ts | 10 +- api_tests/src/wallets/bitcoin.ts | 2 +- api_tests/src/wallets/ethereum.ts | 30 +- api_tests/src/wallets/index.ts | 3 +- api_tests/src/wallets/lightning.ts | 2 +- api_tests/tests/{e2e => }/bitcoin_ethereum.ts | 189 +-------- api_tests/tests/ethereum_bitcoin.ts | 132 ++++++ api_tests/tests/{dry => }/lightning_routes.ts | 8 +- api_tests/tests/lnd_sanity.ts | 62 +++ api_tests/tests/{dry => }/multiple_peers.ts | 8 +- api_tests/tests/{dry => }/peers_using_ip.ts | 10 +- api_tests/tests/{dry => }/rfc003_schema.ts | 28 +- api_tests/tests/{dry => }/sanity.ts | 8 +- api_tests/yarn.lock | 61 ++- 40 files changed, 952 insertions(+), 928 deletions(-) delete mode 100644 api_tests/jest.config-e2e.js rename api_tests/{jest.config-dry.js => jest.config.js} (50%) create mode 100644 api_tests/src/bitcoin_miner.ts delete mode 100644 api_tests/src/dry_test_environment.ts create mode 100644 api_tests/src/environment/kill_nodes.ts create mode 100644 api_tests/src/environment/setup.ts create mode 100644 api_tests/src/environment/teardown.ts delete mode 100644 api_tests/src/ledgers/bitcoin.ts create mode 100644 api_tests/src/ledgers/bitcoin_miner_instance.ts delete mode 100644 api_tests/src/ledgers/ethereum.ts create mode 100644 api_tests/src/ledgers/index.ts delete mode 100644 api_tests/src/ledgers/ledger_instance.ts create mode 100644 api_tests/src/ledgers/ledger_lock.ts create mode 100644 api_tests/src/test_environment.ts rename api_tests/tests/{e2e => }/bitcoin_ethereum.ts (62%) create mode 100644 api_tests/tests/ethereum_bitcoin.ts rename api_tests/tests/{dry => }/lightning_routes.ts (94%) create mode 100644 api_tests/tests/lnd_sanity.ts rename api_tests/tests/{dry => }/multiple_peers.ts (94%) rename api_tests/tests/{dry => }/peers_using_ip.ts (94%) rename api_tests/tests/{dry => }/rfc003_schema.ts (92%) rename api_tests/tests/{dry => }/sanity.ts (97%) diff --git a/api_tests/.gitignore b/api_tests/.gitignore index 9cb9f76f23..1b96f3bb29 100644 --- a/api_tests/.gitignore +++ b/api_tests/.gitignore @@ -4,3 +4,5 @@ log gen/ yarn-error.log dist/ +locks/ +!jest.config.js diff --git a/api_tests/.prettierignore b/api_tests/.prettierignore index 1d493a9707..0ab6eaa5d1 100644 --- a/api_tests/.prettierignore +++ b/api_tests/.prettierignore @@ -1,2 +1,3 @@ gen/ dist/ +locks/ diff --git a/api_tests/jest.config-e2e.js b/api_tests/jest.config-e2e.js deleted file mode 100644 index 904245bcca..0000000000 --- a/api_tests/jest.config-e2e.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = { - preset: "ts-jest", - roots: ["/tests/e2e"], - testRegex: "\\.ts$", - transform: { - "^.+\\.(t|j)s$": "ts-jest", - }, - moduleFileExtensions: ["ts", "js", "json", "node"], - testEnvironment: "/dist/src/e2e_test_environment", - testTimeout: 63000, - setupFilesAfterEnv: ["/src/configure_jasmine.ts"], -}; diff --git a/api_tests/jest.config-dry.js b/api_tests/jest.config.js similarity index 50% rename from api_tests/jest.config-dry.js rename to api_tests/jest.config.js index d98be2b1f2..978b428aef 100644 --- a/api_tests/jest.config-dry.js +++ b/api_tests/jest.config.js @@ -1,12 +1,15 @@ module.exports = { preset: "ts-jest", - roots: ["/tests/dry"], + roots: ["/tests"], testRegex: "\\.ts$", transform: { "^.+\\.(t|j)s$": "ts-jest", }, moduleFileExtensions: ["ts", "js", "json", "node"], - testEnvironment: "/dist/src/dry_test_environment", - testTimeout: 63000, + testEnvironment: "/dist/src/test_environment", + globalSetup: "/src/environment/setup.ts", + globalTeardown: "/src/environment/teardown.ts", setupFilesAfterEnv: ["/src/configure_jasmine.ts"], + testTimeout: 123000, + bail: true, }; diff --git a/api_tests/package.json b/api_tests/package.json index 13549cf425..7147d37259 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -6,10 +6,8 @@ "scripts": { "check": "tsc && prettier --check '**/*.{ts,json,yml}' && tslint --project .", "pretest": "cargo build --bin cnd && tsc", - "dry": "jest --config jest.config-dry.js --maxWorkers=4", - "e2e": "jest --config jest.config-e2e.js --runInBand --forceExit --bail", - "test": "yarn dry && yarn e2e", - "ci": "tsc && yarn dry && yarn e2e", + "test": "jest --forceExit", + "ci": "tsc && jest --forceExit", "fix": "tslint --project . --fix && prettier --write '**/*.{ts,js,json,yml}'" }, "engines": { @@ -24,15 +22,16 @@ "@types/chai-as-promised": "^7.1.2", "@types/chai-json-schema": "^1.4.5", "@types/chai-subset": "^1.3.3", + "@types/glob": "^7.1.1", "@types/jasmine": "^3.5.10", "@types/jest": "^25.2.1", "@types/log4js": "^2.3.5", "@types/node": "^13.11", + "@types/proper-lockfile": "^4.1.1", "@types/rimraf": "^3.0.0", "@types/tail": "^2.0.0", "@types/tmp": "^0.1.0", "@wcjiang/whereis": "^1.0.0", - "async-mutex": "^0.2.1", "bcoin": "https://github.com/bcoin-org/bcoin#2496acc7a98a43f00a7b5728eb256877c1bbf001", "bignumber.js": "^9.0.0", "bitcoin-core": "^3.0.0", @@ -47,12 +46,15 @@ "comit-sdk": "^0.15.2", "ethers": "^4.0.46", "get-port": "^5.1.1", + "glob": "^7.1.6", "jasmine": "^3.5.0", "jest": "^25.2.7", "js-sha256": "^0.9.0", "log4js": "^6.1.2", "p-timeout": "^3.2.0", "prettier": "^2.0.4", + "process-exists": "^4.0.0", + "proper-lockfile": "^4.1.1", "rimraf": "^3.0.2", "satoshi-bitcoin": "^1.0.4", "tail": "^2.0.3", diff --git a/api_tests/src/actor_test.ts b/api_tests/src/actor_test.ts index 9e3f5dfa00..8213b9cd36 100644 --- a/api_tests/src/actor_test.ts +++ b/api_tests/src/actor_test.ts @@ -24,7 +24,7 @@ function nActorTest( const actors = await createActors(name, actorNames); try { - await pTimeout(testFn(actors), 60_000); + await pTimeout(testFn(actors), 120_000); } catch (e) { for (const actorName of actorNames) { await actors.getActorByName(actorName).dumpState(); diff --git a/api_tests/src/bitcoin_miner.ts b/api_tests/src/bitcoin_miner.ts new file mode 100644 index 0000000000..bc4342d0b1 --- /dev/null +++ b/api_tests/src/bitcoin_miner.ts @@ -0,0 +1,31 @@ +import BitcoinRpcClient from "bitcoin-core"; +import { readFileAsync, sleep } from "./utils"; +import { BitcoinNodeConfig } from "./ledgers"; + +const configFile = process.argv[2]; + +// tslint:disable-next-line:no-floating-promises +run(configFile); + +async function run(configFile: string) { + const config: BitcoinNodeConfig = await readFileAsync(configFile, { + encoding: "utf-8", + }).then(JSON.parse); + + const client = new BitcoinRpcClient({ + network: "regtest", + host: "localhost", + port: config.rpcPort, + username: config.username, + password: config.password, + }); + + // only coins after the first 101 are spendable + await client.generateToAddress(101, await client.getNewAddress()); + + while (true) { + await client.generateToAddress(1, await client.getNewAddress()); + + await sleep(1000); + } +} diff --git a/api_tests/src/config.ts b/api_tests/src/config.ts index 56a61d03bc..39672c18eb 100644 --- a/api_tests/src/config.ts +++ b/api_tests/src/config.ts @@ -1,9 +1,11 @@ import * as tmp from "tmp"; -import { BitcoinNodeConfig } from "./ledgers/bitcoin"; -import { EthereumNodeConfig } from "./ledgers/ethereum"; import { LedgerConfig } from "./utils"; import getPort from "get-port"; -import { LightningNodeConfig } from "./ledgers/lightning"; +import { + BitcoinNodeConfig, + EthereumNodeConfig, + LightningNodeConfig, +} from "./ledgers"; import { ActorNames } from "./actors/actor"; export interface CndConfigFile { diff --git a/api_tests/src/create_actors.ts b/api_tests/src/create_actors.ts index bb4ce44558..1d71a308d4 100644 --- a/api_tests/src/create_actors.ts +++ b/api_tests/src/create_actors.ts @@ -12,12 +12,8 @@ export async function createActors( const listPromises: Promise[] = []; for (const name of actorNames) { - const cndLogFile = global.getLogFile([ - "tests", - testName, - `cnd-${name}.log`, - ]); - const actorLogger = global.getLogger(`tests/${testName}/${name}`); + const cndLogFile = global.getLogFile([testName, `cnd-${name}.log`]); + const actorLogger = global.getLogger([testName, name]); listPromises.push( Actor.newInstance( diff --git a/api_tests/src/dry_test_environment.ts b/api_tests/src/dry_test_environment.ts deleted file mode 100644 index ea7096ee15..0000000000 --- a/api_tests/src/dry_test_environment.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { Config } from "@jest/types"; -import { execAsync, HarnessGlobal, mkdirAsync, rimrafAsync } from "./utils"; -import NodeEnvironment from "jest-environment-node"; -import { Mutex } from "async-mutex"; -import path from "path"; -import { configure, shutdown as loggerShutdown } from "log4js"; - -// ************************ // -// Setting global variables // -// ************************ // - -export default class DryTestEnvironment extends NodeEnvironment { - private docblockPragmas: Record; - private projectRoot: string; - public global: HarnessGlobal; - - constructor(config: Config.ProjectConfig, context: any) { - super(config); - - this.docblockPragmas = context.docblockPragmas; - } - - async setup() { - await super.setup(); - - // retrieve project root by using git - const { stdout } = await execAsync("git rev-parse --show-toplevel", { - encoding: "utf8", - }); - this.projectRoot = stdout.trim(); - - // setup global variables - this.global.projectRoot = this.projectRoot; - this.global.ledgerConfigs = {}; - this.global.parityAccountMutex = new Mutex(); - - const suiteConfig = this.extractDocblockPragmas(this.docblockPragmas); - const logDir = path.join( - this.projectRoot, - "api_tests", - "log", - suiteConfig.logDir - ); - - await DryTestEnvironment.cleanLogDir(logDir); - - const log4js = configure({ - appenders: { - multi: { - type: "multiFile", - base: logDir, - property: "categoryName", - extension: ".log", - layout: { - type: "pattern", - pattern: "%d %5.10p: %m", - }, - timeout: 5000, - }, - }, - categories: { - default: { appenders: ["multi"], level: "debug" }, - }, - }); - - const logger = log4js.getLogger("test_environment"); - logger.info("Starting up test environment"); - - this.global.getLogFile = (pathElements) => - path.join(logDir, ...pathElements); - this.global.getDataDir = async (program) => { - const dir = path.join(logDir, program); - await mkdirAsync(dir, { recursive: true }); - - return dir; - }; - this.global.getLogger = (category) => log4js.getLogger(category); - } - - private static async cleanLogDir(logDir: string) { - await rimrafAsync(logDir); - await mkdirAsync(logDir, { recursive: true }); - } - - async teardown() { - await super.teardown(); - - loggerShutdown(); - } - - private extractDocblockPragmas( - docblockPragmas: Record - ): { logDir: string; ledgers: string[] } { - const docblockLedgers = docblockPragmas.ledgers!; - const ledgers = docblockLedgers ? docblockLedgers.split(",") : []; - - const logDir = this.docblockPragmas.logDir!; - if (!logDir) { - throw new Error( - "Test file did not specify a log directory. Did you miss adding @logDir" - ); - } - - return { ledgers, logDir }; - } -} diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index df2949ef80..e69de29bb2 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -1,311 +0,0 @@ -import { Config } from "@jest/types"; -import { execAsync, HarnessGlobal, mkdirAsync, rimrafAsync } from "./utils"; -import NodeEnvironment from "jest-environment-node"; -import { Mutex } from "async-mutex"; -import path from "path"; -import { LightningWallet } from "./wallets/lightning"; -import { BitcoinWallet } from "./wallets/bitcoin"; -import { AssetKind } from "./asset"; -import { LedgerKind } from "./ledgers/ledger"; -import BitcoinLedger from "./ledgers/bitcoin"; -import { BitcoindInstance } from "./ledgers/bitcoind_instance"; -import EthereumLedger from "./ledgers/ethereum"; -import LightningLedger from "./ledgers/lightning"; -import { ParityInstance } from "./ledgers/parity_instance"; -import { LndInstance } from "./ledgers/lnd_instance"; -import { configure, Logger, shutdown as loggerShutdown } from "log4js"; - -// ************************ // -// Setting global variables // -// ************************ // - -export default class E2ETestEnvironment extends NodeEnvironment { - private docblockPragmas: Record; - private projectRoot: string; - public global: HarnessGlobal; - - private bitcoinLedger?: BitcoinLedger; - private ethereumLedger?: EthereumLedger; - private aliceLightning?: LightningLedger; - private bobLightning?: LightningLedger; - - private logger: Logger; - - constructor(config: Config.ProjectConfig, context: any) { - super(config); - - this.docblockPragmas = context.docblockPragmas; - } - - async setup() { - await super.setup(); - - // retrieve project root by using git - const { stdout } = await execAsync("git rev-parse --show-toplevel", { - encoding: "utf8", - }); - this.projectRoot = stdout.trim(); - - // setup global variables - this.global.projectRoot = this.projectRoot; - this.global.ledgerConfigs = {}; - this.global.lndWallets = {}; - this.global.parityAccountMutex = new Mutex(); - - const suiteConfig = this.extractDocblockPragmas(this.docblockPragmas); - - const logDir = path.join( - this.projectRoot, - "api_tests", - "log", - suiteConfig.logDir - ); - await E2ETestEnvironment.cleanLogDir(logDir); - - const log4js = configure({ - appenders: { - multi: { - type: "multiFile", - base: logDir, - property: "categoryName", - extension: ".log", - layout: { - type: "pattern", - pattern: "%d %5.10p: %m", - }, - timeout: 5000, - }, - }, - categories: { - default: { appenders: ["multi"], level: "debug" }, - }, - }); - this.global.getLogFile = (pathElements) => - path.join(logDir, ...pathElements); - this.global.getDataDir = async (program) => { - const dir = path.join(logDir, program); - await mkdirAsync(dir, { recursive: true }); - - return dir; - }; - this.global.getLogger = (category) => log4js.getLogger(category); - - this.logger = log4js.getLogger("test_environment"); - this.logger.info("Starting up test environment"); - - await this.startLedgers(suiteConfig.ledgers); - } - - /** - * Initializes all required ledgers with as much parallelism as possible. - * - * @param ledgers The list of ledgers to initialize - */ - private async startLedgers(ledgers: string[]) { - const startEthereum = ledgers.includes("ethereum"); - const startBitcoin = ledgers.includes("bitcoin"); - const startLightning = ledgers.includes("lightning"); - - const tasks = []; - - if (startEthereum) { - tasks.push(this.startEthereum()); - } - - if (startBitcoin && !startLightning) { - tasks.push(this.startBitcoin()); - } - - if (startBitcoin && startLightning) { - tasks.push(this.startBitcoinAndLightning()); - } - - await Promise.all(tasks); - } - - /** - * Start the Bitcoin Ledger - * - * Once this function returns, the necessary configuration values have been set inside the test environment. - */ - private async startBitcoin() { - this.bitcoinLedger = await BitcoinLedger.start( - await BitcoindInstance.new( - this.projectRoot, - await this.global.getDataDir("bitcoind"), - this.logger - ), - this.logger - ); - this.global.ledgerConfigs.bitcoin = this.bitcoinLedger.config; - } - /** - * Start the Ethereum Ledger - * - * Once this function returns, the necessary configuration values have been set inside the test environment. - */ - private async startEthereum() { - this.ethereumLedger = await EthereumLedger.start( - await ParityInstance.new( - this.projectRoot, - this.global.getLogFile(["parity.log"]), - this.logger - ), - this.logger - ); - this.global.ledgerConfigs.ethereum = this.ethereumLedger.config; - this.global.tokenContract = this.ethereumLedger.config.tokenContract; - } - - /** - * First starts the Bitcoin and then the Lightning ledgers. - * - * The Lightning ledgers depend on Bitcoin to be up and running. - */ - private async startBitcoinAndLightning() { - await this.startBitcoin(); - - // Lightning nodes can be started in parallel - await Promise.all([ - this.startAliceLightning(), - this.startBobLightning(), - ]); - - await this.setupLightningChannels(); - } - - private async setupLightningChannels() { - const { alice, bob } = this.global.lndWallets; - - await alice.connectPeer(bob); - - await alice.mint({ - name: AssetKind.Bitcoin, - ledger: LedgerKind.Lightning, - quantity: "15000000", - }); - - await bob.mint({ - name: AssetKind.Bitcoin, - ledger: LedgerKind.Lightning, - quantity: "15000000", - }); - - await alice.openChannel(bob, 15000000); - await bob.openChannel(alice, 15000000); - } - - /** - * Start the Lightning Ledger for Alice - * - * This function assumes that the Bitcoin ledger is initialized. - * Once this function returns, the necessary configuration values have been set inside the test environment. - */ - private async startAliceLightning() { - this.aliceLightning = await LightningLedger.start( - await LndInstance.new( - await this.global.getDataDir("lnd-alice"), - "lnd-alice", - this.logger, - await this.global.getDataDir("bitcoind") - ) - ); - - this.global.lndWallets.alice = await LightningWallet.newInstance( - await BitcoinWallet.newInstance( - this.bitcoinLedger.config, - this.logger - ), - this.logger, - this.aliceLightning.config - ); - - this.global.ledgerConfigs.aliceLnd = this.aliceLightning.config; - } - - /** - * Start the Lightning Ledger for Bob - * - * This function assumes that the Bitcoin ledger is initialized. - * Once this function returns, the necessary configuration values have been set inside the test environment. - */ - private async startBobLightning() { - this.bobLightning = await LightningLedger.start( - await LndInstance.new( - await this.global.getDataDir("lnd-bob"), - "lnd-bob", - this.logger, - await this.global.getDataDir("bitcoind") - ) - ); - - this.global.lndWallets.bob = await LightningWallet.newInstance( - await BitcoinWallet.newInstance( - this.bitcoinLedger.config, - this.logger - ), - this.logger, - this.bobLightning.config - ); - - this.global.ledgerConfigs.bobLnd = this.bobLightning.config; - } - - private static async cleanLogDir(logDir: string) { - await rimrafAsync(logDir); - await mkdirAsync(logDir, { recursive: true }); - } - - async teardown() { - await super.teardown(); - this.logger.info("Tearing down test environment"); - - await this.cleanupAll(); - - loggerShutdown(); - - this.logger.info("Tearing down complete"); - } - - async cleanupAll() { - const tasks = []; - - if (this.bitcoinLedger) { - tasks.push(this.bitcoinLedger.stop()); - } - - if (this.ethereumLedger) { - tasks.push(this.ethereumLedger.stop()); - } - - if (this.aliceLightning) { - tasks.push(this.aliceLightning.stop()); - } - - if (this.bobLightning) { - tasks.push(this.bobLightning.stop()); - } - - for (const [, wallet] of Object.entries(this.global.lndWallets)) { - tasks.push(wallet.close()); - } - - await Promise.all(tasks); - } - - private extractDocblockPragmas( - docblockPragmas: Record - ): { logDir: string; ledgers: string[] } { - const docblockLedgers = docblockPragmas.ledgers!; - const ledgers = docblockLedgers ? docblockLedgers.split(",") : []; - - const logDir = this.docblockPragmas.logDir!; - if (!logDir) { - throw new Error( - "Test file did not specify a log directory. Did you miss adding @logDir" - ); - } - - return { ledgers, logDir }; - } -} diff --git a/api_tests/src/environment/kill_nodes.ts b/api_tests/src/environment/kill_nodes.ts new file mode 100644 index 0000000000..f6fe9c7e80 --- /dev/null +++ b/api_tests/src/environment/kill_nodes.ts @@ -0,0 +1,29 @@ +import glob from "glob"; +import { readFileAsync, rimrafAsync } from "../utils"; +import { promisify } from "util"; +import processExists from "process-exists"; +import path from "path"; + +const globAsync = promisify(glob); + +export default async function killNodes(locksDir: any) { + const pidFiles = await globAsync("**/*.pid", { + cwd: locksDir, + }); + + for (const pidFile of pidFiles) { + const content = await readFileAsync(path.join(locksDir, pidFile), { + encoding: "utf-8", + }); + const pid = parseInt(content, 10); + + if (await processExists(pid)) { + process.stderr.write( + `Found pid file ${pidFile}, sending SIGINT to process with PID ${pid}\n` + ); + process.kill(pid, "SIGTERM"); + } + } + + await rimrafAsync(locksDir); +} diff --git a/api_tests/src/environment/setup.ts b/api_tests/src/environment/setup.ts new file mode 100644 index 0000000000..5a23883b14 --- /dev/null +++ b/api_tests/src/environment/setup.ts @@ -0,0 +1,25 @@ +import { mkdirAsync, rimrafAsync } from "../utils"; +import path from "path"; +import killNodes from "./kill_nodes"; + +export default async (config: any) => { + const root = config.rootDir; + + const logDir = path.join(root, "log"); + const locksDir = path.join(root, "locks"); + + // make sure we have a clean log dir + await rimrafAsync(logDir); + await mkdirAsync(logDir, { recursive: true }); + + // make sure we don't have any left-over processes + await killNodes(locksDir); + await mkdirAsync(locksDir, { recursive: true }); + + process.on("SIGINT", () => { + process.stderr.write("SIGINT caught, cleaning up environment ...\n"); + + // tslint:disable-next-line:no-floating-promises cannot await in a signal listener + killNodes(locksDir).then(() => process.exit(1)); + }); +}; diff --git a/api_tests/src/environment/teardown.ts b/api_tests/src/environment/teardown.ts new file mode 100644 index 0000000000..c2b95c6373 --- /dev/null +++ b/api_tests/src/environment/teardown.ts @@ -0,0 +1,14 @@ +import { rimrafAsync } from "../utils"; +import path from "path"; +import killNodes from "./kill_nodes"; + +export default async (config: any) => { + const root = config.rootDir; + + const locksDir = path.join(root, "locks"); + + // make sure we don't have any left-over processes + await killNodes(locksDir); + + await rimrafAsync(locksDir); +}; diff --git a/api_tests/src/ledgers/bitcoin.ts b/api_tests/src/ledgers/bitcoin.ts deleted file mode 100644 index 0c019a4c6b..0000000000 --- a/api_tests/src/ledgers/bitcoin.ts +++ /dev/null @@ -1,73 +0,0 @@ -import BitcoinRpcClient from "bitcoin-core"; -import LedgerInstance from "./ledger_instance"; -import { Logger } from "log4js"; - -/** - * An instance of the Bitcoin ledger for use in the e2e tests. - * - * This class is compatible with anything that implements {@link BitcoinInstance}. - * - * For the e2e tests to work properly, we need to continuously mine bitcoin blocks. - * This class takes care of spawning a miner after the Bitcoin blockchain has - * been setup, regardless of how that is achieved (Docker container, bitcoind instance, etc). - */ -export default class BitcoinLedger implements LedgerInstance { - public static async start(instance: BitcoinInstance, logger: Logger) { - await instance.start(); - - const { rpcPort, username, password, rpcUrl } = instance.config; - - logger.info("Bitcoin instance started at", rpcUrl); - - const client = new BitcoinRpcClient({ - network: "regtest", - host: "localhost", - port: rpcPort, - username, - password, - }); - - // only coins after the first 101 are spendable - await client.generateToAddress(101, await client.getNewAddress()); - - const miner = setInterval(async () => { - await client.generateToAddress(1, await client.getNewAddress()); - }, 1000); - - logger.info("Bitcoin miner initialized"); - - return new BitcoinLedger(instance, miner); - } - - constructor( - private readonly instance: BitcoinInstance, - private readonly miner: NodeJS.Timeout - ) {} - - public async stop(): Promise { - await this.instance.stop(); - clearInterval(this.miner); - } - - public get config(): BitcoinNodeConfig { - return this.instance.config; - } -} - -export interface BitcoinInstance { - config: BitcoinNodeConfig; - - start(): Promise; - stop(): Promise; -} - -export interface BitcoinNodeConfig { - network: string; - username: string; - password: string; - host: string; - rpcPort: number; - rpcUrl: string; - p2pPort: number; - dataDir: string; -} diff --git a/api_tests/src/ledgers/bitcoin_miner_instance.ts b/api_tests/src/ledgers/bitcoin_miner_instance.ts new file mode 100644 index 0000000000..2dc7ab37db --- /dev/null +++ b/api_tests/src/ledgers/bitcoin_miner_instance.ts @@ -0,0 +1,41 @@ +import { spawn } from "child_process"; +import { existsAsync, writeFileAsync } from "../utils"; +import { Logger } from "log4js"; + +export default class BitcoinMinerInstance { + public static async start( + tsNode: string, + minerPath: string, + bitcoindConfigFile: string, + pidFile: string, + logger: Logger + ) { + if (!(await existsAsync(tsNode))) { + throw new Error(`ts-node binary does not exist: ${tsNode}`); + } + + if (!(await existsAsync(minerPath))) { + throw new Error(`miner script does not exist: ${minerPath}`); + } + + if (!(await existsAsync(bitcoindConfigFile))) { + throw new Error( + `bitcoind config file does not exist: ${bitcoindConfigFile}` + ); + } + + const miner = spawn(tsNode, [minerPath, bitcoindConfigFile], { + stdio: "ignore", + }); + + await writeFileAsync(pidFile, miner.pid, { + encoding: "utf-8", + }); + + miner.unref(); + + miner.on("exit", (code) => { + logger.warn("bitcoin miner exited with code ", code); + }); + } +} diff --git a/api_tests/src/ledgers/bitcoind_instance.ts b/api_tests/src/ledgers/bitcoind_instance.ts index 0a5a143a6d..2460fd981e 100644 --- a/api_tests/src/ledgers/bitcoind_instance.ts +++ b/api_tests/src/ledgers/bitcoind_instance.ts @@ -3,11 +3,11 @@ import * as fs from "fs"; import * as path from "path"; import { writeFileAsync } from "../utils"; import getPort from "get-port"; -import { BitcoinInstance, BitcoinNodeConfig } from "./bitcoin"; import { Logger } from "log4js"; import waitForLogMessage from "../wait_for_log_message"; +import { BitcoinNodeConfig, LedgerInstance } from "./index"; -export class BitcoindInstance implements BitcoinInstance { +export class BitcoindInstance implements LedgerInstance { private process: ChildProcess; private username: string; private password: string; @@ -15,11 +15,13 @@ export class BitcoindInstance implements BitcoinInstance { public static async new( projectRoot: string, dataDir: string, + pidFile: string, logger: Logger ): Promise { return new BitcoindInstance( projectRoot, dataDir, + pidFile, logger, await getPort({ port: 18444 }), await getPort({ port: 18443 }), @@ -31,6 +33,7 @@ export class BitcoindInstance implements BitcoinInstance { constructor( private readonly projectRoot: string, private readonly dataDir: string, + private readonly pidFile: string, private readonly logger: Logger, public readonly p2pPort: number, public readonly rpcPort: number, @@ -79,6 +82,10 @@ export class BitcoindInstance implements BitcoinInstance { this.password = password; this.logger.info("bitcoind started with PID", this.process.pid); + + await writeFileAsync(this.pidFile, this.process.pid, { + encoding: "utf-8", + }); } public get config(): BitcoinNodeConfig { @@ -94,12 +101,6 @@ export class BitcoindInstance implements BitcoinInstance { }; } - public async stop() { - this.logger.info("Stopping bitcoind instance"); - - this.process.kill("SIGINT"); - } - private logPath() { return path.join(this.dataDir, "regtest", "debug.log"); } diff --git a/api_tests/src/ledgers/ethereum.ts b/api_tests/src/ledgers/ethereum.ts deleted file mode 100644 index 1e15244bc1..0000000000 --- a/api_tests/src/ledgers/ethereum.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { EthereumWallet } from "../wallets/ethereum"; -import LedgerInstance from "./ledger_instance"; -import { Logger } from "log4js"; - -/** - * An instance of the Ethereum ledger for use in the e2e tests. - * - * This class is compatible with anything that implements {@link EthereumInstance}. - * - * Some of the e2e tests need an ERC20 token deployed to work properly. - * This class takes care of deploying such contract after the Ethereum - * blockchain is up and running. - * - * This class serves as an abstraction layer on top of Ethereum, regardless - * of which implementation is used (Docker container, parity, geth, etc). - */ -export default class EthereumLedger implements LedgerInstance { - public static async start(instance: EthereumInstance, logger: Logger) { - await instance.start(); - - const rpcUrl = instance.rpcUrl; - - logger.info("Ethereum node started at", rpcUrl); - - const erc20Wallet = new EthereumWallet(rpcUrl, logger); - const erc20TokenContract = await erc20Wallet.deployErc20TokenContract(); - - logger.info("ERC20 token contract deployed at", erc20TokenContract); - - return new EthereumLedger(instance, erc20TokenContract); - } - - constructor( - private readonly instance: EthereumInstance, - private readonly erc20TokenContract: string - ) {} - - public async stop(): Promise { - await this.instance.stop(); - } - - public get config(): EthereumNodeConfig { - return { - rpc_url: this.instance.rpcUrl, - tokenContract: this.erc20TokenContract, - }; - } -} - -export interface EthereumInstance { - rpcUrl: string; - - start(): Promise; - stop(): Promise; -} - -export interface EthereumNodeConfig { - rpc_url: string; - tokenContract: string; -} diff --git a/api_tests/src/ledgers/index.ts b/api_tests/src/ledgers/index.ts new file mode 100644 index 0000000000..be1004c475 --- /dev/null +++ b/api_tests/src/ledgers/index.ts @@ -0,0 +1,28 @@ +export interface BitcoinNodeConfig { + network: string; + username: string; + password: string; + host: string; + rpcPort: number; + rpcUrl: string; + p2pPort: number; + dataDir: string; +} + +export interface LightningNodeConfig { + p2pSocket: string; + grpcSocket: string; + tlsCertPath: string; + macaroonPath: string; + restPort: number; + dataDir: string; +} + +export interface EthereumNodeConfig { + rpc_url: string; + tokenContract: string; +} + +export interface LedgerInstance { + start(): Promise; +} diff --git a/api_tests/src/ledgers/ledger_instance.ts b/api_tests/src/ledgers/ledger_instance.ts deleted file mode 100644 index c977a89b29..0000000000 --- a/api_tests/src/ledgers/ledger_instance.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Defines an instance of a ledger - */ -export default interface LedgerInstance { - /** - * Stop the underlying ledger. - * - * This method must never fail. - */ - stop(): Promise; -} diff --git a/api_tests/src/ledgers/ledger_lock.ts b/api_tests/src/ledgers/ledger_lock.ts new file mode 100644 index 0000000000..3479b3523f --- /dev/null +++ b/api_tests/src/ledgers/ledger_lock.ts @@ -0,0 +1,22 @@ +import { lock } from "proper-lockfile"; +import * as path from "path"; + +/** + * Locks the given directory for exclusive access. + * + * This function provides default parameters to the retries configuration that are suitable for + * waiting for ledgers to start up. We have to be fairly generous with these timeouts to prevent + * the lock from failing to quickly if it cannot be acquired. + */ +export default async function ledgerLock( + lockDir: string +): Promise<() => Promise> { + return lock(lockDir, { + lockfilePath: path.join(lockDir, "lock"), + retries: { + retries: 10, + minTimeout: 200, + maxTimeout: 8000, + }, + }); +} diff --git a/api_tests/src/ledgers/lightning.ts b/api_tests/src/ledgers/lightning.ts index b655df3778..e69de29bb2 100644 --- a/api_tests/src/ledgers/lightning.ts +++ b/api_tests/src/ledgers/lightning.ts @@ -1,44 +0,0 @@ -import LedgerInstance from "./ledger_instance"; - -/** - * An instance of the Lightning ledger for use in the e2e tests. - * - * This class is compatible with anything that implements {@link LightningInstance}. - * - * Compared to {@link BitcoinLedger} and {@link EthereumLedger}, there is nothing - * to be done after a {@link LightningInstance} is started. If this ever changes, - * this class is the place where to put this information. - */ -export default class LightningLedger implements LedgerInstance { - public static async start(instance: LightningInstance) { - await instance.start(); - - return new LightningLedger(instance); - } - - constructor(private readonly instance: LightningInstance) {} - - async stop(): Promise { - return this.instance.stop(); - } - - get config(): LightningNodeConfig { - return this.instance.config; - } -} - -export interface LightningInstance { - config: LightningNodeConfig; - - start(): Promise; - stop(): Promise; -} - -export interface LightningNodeConfig { - p2pSocket: string; - grpcSocket: string; - tlsCertPath: string; - macaroonPath: string; - restPort: number; - dataDir: string; -} diff --git a/api_tests/src/ledgers/lnd_instance.ts b/api_tests/src/ledgers/lnd_instance.ts index 4357c28d72..725c1236b2 100644 --- a/api_tests/src/ledgers/lnd_instance.ts +++ b/api_tests/src/ledgers/lnd_instance.ts @@ -5,23 +5,23 @@ import getPort from "get-port"; import waitForLogMessage from "../wait_for_log_message"; import { Lnd } from "comit-sdk"; import whereis from "@wcjiang/whereis"; -import { LightningInstance, LightningNodeConfig } from "./lightning"; import { Logger } from "log4js"; +import { LightningNodeConfig, LedgerInstance } from "./index"; -export class LndInstance implements LightningInstance { +export class LndInstance implements LedgerInstance { private process: ChildProcess; public static async new( dataDir: string, - name: string, logger: Logger, - bitcoindDataDir: string + bitcoindDataDir: string, + pidFile: string ) { return new LndInstance( dataDir, - name, logger, bitcoindDataDir, + pidFile, await getPort(), await getPort(), await getPort() @@ -30,9 +30,9 @@ export class LndInstance implements LightningInstance { private constructor( private readonly dataDir: string, - private readonly name: string, private readonly logger: Logger, private readonly bitcoindDataDir: string, + private readonly pidFile: string, private readonly lndP2pPort: number, private readonly lndRpcPort: number, private readonly lndRestPort: number @@ -59,10 +59,14 @@ export class LndInstance implements LightningInstance { ); await waitUntilFileExists(this.adminMacaroonPath()); - this.logger.debug("Waiting for lnd to catch up with blocks"); - await waitForLogMessage(logFile, "LNWL: Done catching up block hashes"); + this.logger.debug("Waiting for lightning server to start"); + await waitForLogMessage(logFile, "[INF] BTCN: Server listening on "); this.logger.debug("lnd started with PID", this.process.pid); + + await writeFileAsync(this.pidFile, this.process.pid, { + encoding: "utf-8", + }); } private async execBinary() { @@ -93,7 +97,7 @@ export class LndInstance implements LightningInstance { const lnd = await Lnd.init(config); const { cipherSeedMnemonic } = await lnd.lnrpc.genSeed({ - seedEntropy: Buffer.alloc(16, this.name), + seedEntropy: Buffer.alloc(16, this.lndP2pPort), }); const walletPassword = Buffer.from("password", "utf8"); this.logger.debug( @@ -105,12 +109,6 @@ export class LndInstance implements LightningInstance { this.logger.debug("Lnd wallet initialized!"); } - public async stop() { - this.logger.debug("Stopping lnd instance"); - this.process.kill("SIGTERM"); - this.process = null; - } - public isRunning() { return this.process != null; } diff --git a/api_tests/src/ledgers/parity_instance.ts b/api_tests/src/ledgers/parity_instance.ts index f0715e9e93..a7c581e86c 100644 --- a/api_tests/src/ledgers/parity_instance.ts +++ b/api_tests/src/ledgers/parity_instance.ts @@ -3,25 +3,27 @@ import * as fs from "fs"; import tmp from "tmp"; import waitForLogMessage from "../wait_for_log_message"; import { promisify } from "util"; -import { sleep } from "../utils"; +import { writeFileAsync } from "../utils"; import getPort from "get-port"; -import { EthereumInstance } from "./ethereum"; import { Logger } from "log4js"; +import { LedgerInstance } from "./index"; const openAsync = promisify(fs.open); -export class ParityInstance implements EthereumInstance { +export class ParityInstance implements LedgerInstance { private process: ChildProcess; private dbDir: any; public static async new( projectRoot: string, logFile: string, + pidFile: string, logger: Logger ) { return new ParityInstance( projectRoot, logFile, + pidFile, logger, await getPort({ port: 8545 }), await getPort() @@ -31,6 +33,7 @@ export class ParityInstance implements EthereumInstance { constructor( private readonly projectRoot: string, private readonly logFile: string, + private readonly pidFile: string, private readonly logger: Logger, public readonly rpcPort: number, public readonly p2pPort: number @@ -82,17 +85,13 @@ export class ParityInstance implements EthereumInstance { await waitForLogMessage(this.logFile, "Public node URL:"); this.logger.info("parity started with PID", this.process.pid); + + await writeFileAsync(this.pidFile, this.process.pid, { + encoding: "utf-8", + }); } public get rpcUrl() { return `http://localhost:${this.rpcPort}`; } - - public async stop() { - this.logger.info("Stopping parity instance"); - - this.process.kill("SIGTERM"); - await sleep(3000); - this.process.kill("SIGKILL"); - } } diff --git a/api_tests/src/test_environment.ts b/api_tests/src/test_environment.ts new file mode 100644 index 0000000000..223abbb896 --- /dev/null +++ b/api_tests/src/test_environment.ts @@ -0,0 +1,398 @@ +import { Config } from "@jest/types"; +import { + existsAsync, + HarnessGlobal, + mkdirAsync, + readFileAsync, + writeFileAsync, +} from "./utils"; +import NodeEnvironment from "jest-environment-node"; +import path from "path"; +import { LightningWallet } from "./wallets/lightning"; +import { BitcoinWallet } from "./wallets/bitcoin"; +import { AssetKind } from "./asset"; +import { LedgerKind } from "./ledgers/ledger"; +import { BitcoindInstance } from "./ledgers/bitcoind_instance"; +import { configure, Logger, shutdown as loggerShutdown } from "log4js"; +import { EnvironmentContext } from "@jest/environment"; +import ledgerLock from "./ledgers/ledger_lock"; +import BitcoinMinerInstance from "./ledgers/bitcoin_miner_instance"; +import { EthereumWallet } from "./wallets/ethereum"; +import { LedgerInstance, LightningNodeConfig } from "./ledgers"; +import { ParityInstance } from "./ledgers/parity_instance"; +import { LndInstance } from "./ledgers/lnd_instance"; + +export default class TestEnvironment extends NodeEnvironment { + private readonly projectRoot: string; + private readonly testSuite: string; + private readonly ledgers: string[]; + + public global: HarnessGlobal; + + private logger: Logger; + private logDir: string; + + constructor(config: Config.ProjectConfig, context: EnvironmentContext) { + super(config); + + this.ledgers = TestEnvironment.extractLedgersToBeStarted( + context.docblockPragmas + ); + this.projectRoot = path.resolve(config.rootDir, ".."); + this.testSuite = path.parse(context.testPath).name; + } + + async setup() { + await super.setup(); + + // setup global variables + this.global.projectRoot = this.projectRoot; + this.global.ledgerConfigs = {}; + this.global.lndWallets = {}; + + this.logDir = path.join(this.projectRoot, "api_tests", "log"); + + const log4js = configure({ + appenders: { + multi: { + type: "multiFile", + base: this.logDir, + property: "categoryName", + extension: ".log", + layout: { + type: "pattern", + pattern: "%d %5.10p: %m", + }, + }, + }, + categories: { + default: { appenders: ["multi"], level: "debug" }, + }, + }); + + const testLogDir = path.join(this.logDir, "tests", this.testSuite); + await mkdirAsync(testLogDir, { recursive: true }); + + this.global.getLogFile = (pathElements) => + path.join(testLogDir, ...pathElements); + this.global.getLogger = (categories) => { + return log4js.getLogger( + path.join("tests", this.testSuite, ...categories) + ); + }; + this.logger = this.global.getLogger(["test_environment"]); + + this.global.getDataDir = async (program) => { + const dir = path.join(this.logDir, program); + await mkdirAsync(dir, { recursive: true }); + + return dir; + }; + this.global.parityLockDir = await this.getLockDirectory("parity"); + + this.logger.info("Starting up test environment"); + + await this.startLedgers(); + } + + async teardown() { + await super.teardown(); + + await this.cleanupAll(); + + loggerShutdown(); + } + + async cleanupAll() { + const tasks = []; + + for (const [, wallet] of Object.entries(this.global.lndWallets)) { + tasks.push(wallet.close()); + } + + await Promise.all(tasks); + } + + /** + * Initializes all required ledgers with as much parallelism as possible. + */ + private async startLedgers() { + const startEthereum = this.ledgers.includes("ethereum"); + const startBitcoin = this.ledgers.includes("bitcoin"); + const startLightning = this.ledgers.includes("lightning"); + + const tasks = []; + + if (startEthereum) { + tasks.push(this.startEthereum()); + } + + if (startBitcoin && !startLightning) { + tasks.push(this.startBitcoin()); + } + + if (startLightning) { + tasks.push(this.startBitcoinAndLightning()); + } + + await Promise.all(tasks); + } + + /** + * Start the Bitcoin Ledger + * + * Once this function returns, the necessary configuration values have been set inside the test environment. + */ + private async startBitcoin() { + const lockDir = await this.getLockDirectory("bitcoind"); + const release = await ledgerLock(lockDir); + + const bitcoind = await BitcoindInstance.new( + this.projectRoot, + await this.global.getDataDir("bitcoind"), + path.join(lockDir, "bitcoind.pid"), + this.logger + ); + const config = await this.startLedger( + lockDir, + bitcoind, + async (bitcoind) => bitcoind.config + ); + + const minerPidFile = path.join(lockDir, "miner.pid"); + + const minerAlreadyRunning = await existsAsync(minerPidFile); + + if (!minerAlreadyRunning) { + const tsNode = path.join( + this.projectRoot, + "api_tests", + "node_modules", + ".bin", + "ts-node" + ); + const minerProgram = path.join( + this.projectRoot, + "api_tests", + "src", + "bitcoin_miner.ts" + ); + + await BitcoinMinerInstance.start( + tsNode, + minerProgram, + path.join(lockDir, "config.json"), + minerPidFile, + this.logger + ); + } + + this.global.ledgerConfigs.bitcoin = config; + + await release(); + } + + /** + * Start the Ethereum Ledger + * + * Once this function returns, the necessary configuration values have been set inside the test environment. + */ + private async startEthereum() { + const lockDir = await this.getLockDirectory("parity"); + const release = await ledgerLock(lockDir); + + const parity = await ParityInstance.new( + this.projectRoot, + path.join(this.logDir, "parity.log"), + path.join(lockDir, "parity.pid"), + this.logger + ); + const config = await this.startLedger( + lockDir, + parity, + async (parity) => { + const rpcUrl = parity.rpcUrl; + + const erc20Wallet = new EthereumWallet( + rpcUrl, + this.logger, + lockDir + ); + const erc20TokenContract = await erc20Wallet.deployErc20TokenContract(); + + this.logger.info( + "ERC20 token contract deployed at", + erc20TokenContract + ); + + return { + rpc_url: rpcUrl, + tokenContract: erc20TokenContract, + }; + } + ); + + this.global.ledgerConfigs.ethereum = config; + this.global.tokenContract = config.tokenContract; + + await release(); + } + + /** + * First starts the Bitcoin and then the Lightning ledgers. + * + * The Lightning ledgers depend on Bitcoin to be up and running. + */ + private async startBitcoinAndLightning() { + await this.startBitcoin(); + + // Lightning nodes can be started in parallel + await Promise.all([ + this.startAliceLightning(), + this.startBobLightning(), + ]); + + await this.setupLightningChannels(); + } + + private async setupLightningChannels() { + const { alice, bob } = this.global.lndWallets; + + await alice.connectPeer(bob); + + await alice.mint({ + name: AssetKind.Bitcoin, + ledger: LedgerKind.Lightning, + quantity: "15000000", + }); + + await bob.mint({ + name: AssetKind.Bitcoin, + ledger: LedgerKind.Lightning, + quantity: "15000000", + }); + + await alice.openChannel(bob, 15000000); + await bob.openChannel(alice, 15000000); + } + + /** + * Start the Lightning Ledger for Alice + * + * This function assumes that the Bitcoin ledger is initialized. + * Once this function returns, the necessary configuration values have been set inside the test environment. + */ + private async startAliceLightning() { + const config = await this.initLightningLedger("lnd-alice"); + this.global.lndWallets.alice = await this.initLightningWallet(config); + } + + /** + * Start the Lightning Ledger for Bob + * + * This function assumes that the Bitcoin ledger is initialized. + * Once this function returns, the necessary configuration values have been set inside the test environment. + */ + private async startBobLightning() { + const config = await this.initLightningLedger("lnd-bob"); + this.global.lndWallets.bob = await this.initLightningWallet(config); + } + + private async initLightningWallet(config: LightningNodeConfig) { + return LightningWallet.newInstance( + await BitcoinWallet.newInstance( + this.global.ledgerConfigs.bitcoin, + this.logger + ), + this.logger, + config + ); + } + + private async initLightningLedger( + role: string + ): Promise { + const lockDir = await this.getLockDirectory(role); + const release = await ledgerLock(lockDir); + + const lnd = await LndInstance.new( + await this.global.getDataDir(role), + this.logger, + await this.global.getDataDir("bitcoind"), + path.join(lockDir, "lnd.pid") + ); + + const config = await this.startLedger( + lockDir, + lnd, + async (lnd) => lnd.config + ); + + await release(); + + return config; + } + + private async startLedger( + lockDir: string, + instance: S, + makeConfig: (instance: S) => Promise + ): Promise { + const configFile = path.join(lockDir, "config.json"); + + this.logger.info("Checking for config file ", configFile); + const configFileExists = await existsAsync(configFile); + + if (configFileExists) { + this.logger.info( + "Found config file, we'll be using that configuration instead of starting another instance" + ); + + const config = await readFileAsync(configFile, { + encoding: "utf-8", + }); + + return JSON.parse(config); + } else { + this.logger.info("No config file found, starting ledger"); + + await instance.start(); + + const config = await makeConfig(instance); + + await writeFileAsync(configFile, JSON.stringify(config), { + encoding: "utf-8", + }); + + this.logger.info("Config file written to", configFile); + + return config; + } + } + + private async getLockDirectory(process: string): Promise { + const dir = path.join(this.projectRoot, "api_tests", "locks", process); + + await mkdirAsync(dir, { + recursive: true, + }); + + return dir; + } + + private static extractLedgersToBeStarted( + docblockPragmas: Record + ): string[] { + const ledgersToStart = docblockPragmas.ledger; + + if (!ledgersToStart) { + return []; + } + + if (typeof ledgersToStart === "string") { + return [ledgersToStart]; + } + + return ledgersToStart; + } +} diff --git a/api_tests/src/utils.ts b/api_tests/src/utils.ts index 16d7b589c9..e2a2d46f12 100644 --- a/api_tests/src/utils.ts +++ b/api_tests/src/utils.ts @@ -5,13 +5,14 @@ import * as fs from "fs"; import { promisify } from "util"; import { Global } from "@jest/types"; import rimraf from "rimraf"; -import { Mutex } from "async-mutex"; import { exec } from "child_process"; import { LightningWallet } from "./wallets/lightning"; -import { BitcoinNodeConfig } from "./ledgers/bitcoin"; -import { EthereumNodeConfig } from "./ledgers/ethereum"; import { Logger } from "log4js"; -import { LightningNodeConfig } from "./ledgers/lightning"; +import { + BitcoinNodeConfig, + EthereumNodeConfig, + LightningNodeConfig, +} from "./ledgers"; export interface HarnessGlobal extends Global.Global { ledgerConfigs: LedgerConfig; @@ -21,11 +22,11 @@ export interface HarnessGlobal extends Global.Global { }; projectRoot: string; tokenContract: string; - parityAccountMutex: Mutex; + parityLockDir: string; getDataDir: (program: string) => Promise; getLogFile: (pathElements: string[]) => string; - getLogger: (category: string) => Logger; + getLogger: (categories: string[]) => Logger; } export interface LedgerConfig { @@ -40,6 +41,7 @@ export const existsAsync = promisify(fs.exists); export const openAsync = promisify(fs.open); export const mkdirAsync = promisify(fs.mkdir); export const writeFileAsync = promisify(fs.writeFile); +export const readFileAsync = promisify(fs.readFile); export const rimrafAsync = promisify(rimraf); export const execAsync = promisify(exec); diff --git a/api_tests/src/wait_for_log_message.ts b/api_tests/src/wait_for_log_message.ts index 521e2fcd6a..e08794231a 100644 --- a/api_tests/src/wait_for_log_message.ts +++ b/api_tests/src/wait_for_log_message.ts @@ -1,14 +1,15 @@ import { Tail } from "tail"; -import { timeout, waitUntilFileExists } from "./utils"; +import pTimeout from "p-timeout"; +import { waitUntilFileExists } from "./utils"; export default async function waitForLogMessage(logFile: string, line: string) { - await timeout(10000, waitUntilFileExists(logFile)); + await pTimeout(waitUntilFileExists(logFile), 10_000); // By default tail uses `fs.watch` that watches the inode // However, it looks like on Mac OS, the inode get changed at some point // To counter that then we use `fs.watchFile` which is actually considered // less efficient. Hence only using it on Mac. - const useWatchFile = process.platform === "darwin" ? true : false; + const useWatchFile = process.platform === "darwin"; const options = { fromBeginning: true, @@ -18,8 +19,7 @@ export default async function waitForLogMessage(logFile: string, line: string) { const tail = new Tail(logFile, options); - await timeout(60000, findTextInLog(tail, line)); - + await pTimeout(findTextInLog(tail, line), 60000); tail.unwatch(); } diff --git a/api_tests/src/wallets/bitcoin.ts b/api_tests/src/wallets/bitcoin.ts index d83aa8a0a6..4967a88d46 100644 --- a/api_tests/src/wallets/bitcoin.ts +++ b/api_tests/src/wallets/bitcoin.ts @@ -8,7 +8,7 @@ import { } from "comit-sdk"; import { toBitcoin, toSatoshi } from "satoshi-bitcoin"; import { pollUntilMinted, Wallet } from "./index"; -import { BitcoinNodeConfig } from "../ledgers/bitcoin"; +import { BitcoinNodeConfig } from "../ledgers"; export class BitcoinWallet implements Wallet { public static async newInstance(config: BitcoinNodeConfig, logger: Logger) { diff --git a/api_tests/src/wallets/ethereum.ts b/api_tests/src/wallets/ethereum.ts index 5fde0f590b..6701fa1956 100644 --- a/api_tests/src/wallets/ethereum.ts +++ b/api_tests/src/wallets/ethereum.ts @@ -4,10 +4,9 @@ import { ethers } from "ethers"; import { BigNumber as BigNumberEthers } from "ethers/utils"; import { Wallet } from "./index"; import { TransactionRequest } from "ethers/providers"; -import { HarnessGlobal, sleep } from "../utils"; +import { sleep } from "../utils"; import { Logger } from "log4js"; - -declare var global: HarnessGlobal; +import { lock } from "proper-lockfile"; export class EthereumWallet implements Wallet { public readonly inner: EthereumWalletSdk; @@ -16,7 +15,11 @@ export class EthereumWallet implements Wallet { private readonly parity: ethers.Wallet; private readonly jsonRpcProvider: ethers.providers.JsonRpcProvider; - constructor(rpcUrl: string, private readonly logger: Logger) { + constructor( + rpcUrl: string, + private readonly logger: Logger, + private readonly parityLockDir: string + ) { const provider = new ethers.providers.JsonRpcProvider(rpcUrl); this.parity = new ethers.Wallet( "0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7", @@ -79,12 +82,27 @@ export class EthereumWallet implements Wallet { } private async sendTransaction(tx: TransactionRequest) { - const release = await global.parityAccountMutex.acquire(); + const release = await lock(this.parityLockDir, { + retries: { + retries: 10, + minTimeout: 50, + maxTimeout: 2000, + }, + lockfilePath: "parity-account", + }); + + this.logger.debug( + "Acquired lock for parity account, sending transaction ", + tx + ); + try { return await this.parity.sendTransaction(tx); } finally { - release(); + await release(); } + + this.logger.debug("Lock for parity account released"); } private async mintEther(asset: Asset): Promise { diff --git a/api_tests/src/wallets/index.ts b/api_tests/src/wallets/index.ts index 6a189b90dd..9b65a73774 100644 --- a/api_tests/src/wallets/index.ts +++ b/api_tests/src/wallets/index.ts @@ -56,7 +56,8 @@ export class Wallets { case "ethereum": this.wallets.ethereum = new EthereumWallet( global.ledgerConfigs.ethereum.rpc_url, - logger + logger, + global.parityLockDir ); break; case "bitcoin": diff --git a/api_tests/src/wallets/lightning.ts b/api_tests/src/wallets/lightning.ts index 31d0bda308..0bfabdedb5 100644 --- a/api_tests/src/wallets/lightning.ts +++ b/api_tests/src/wallets/lightning.ts @@ -6,7 +6,7 @@ import { sleep } from "../utils"; import { LightningWallet as LightningWalletSdk, Outpoint } from "comit-sdk"; import { AddressType } from "@radar/lnrpc"; import { Logger } from "log4js"; -import { LightningNodeConfig } from "../ledgers/lightning"; +import { LightningNodeConfig } from "../ledgers"; export class LightningWallet implements Wallet { public static async newInstance( diff --git a/api_tests/tests/e2e/bitcoin_ethereum.ts b/api_tests/tests/bitcoin_ethereum.ts similarity index 62% rename from api_tests/tests/e2e/bitcoin_ethereum.ts rename to api_tests/tests/bitcoin_ethereum.ts index e228fa26d2..59e1636ca3 100644 --- a/api_tests/tests/e2e/bitcoin_ethereum.ts +++ b/api_tests/tests/bitcoin_ethereum.ts @@ -1,66 +1,11 @@ /** - * @ledgers ethereum,bitcoin,lightning - * @logDir e2e + * @ledger ethereum + * @ledger bitcoin */ -import { twoActorTest } from "../../src/actor_test"; -import { AssetKind } from "../../src/asset"; -import { sleep } from "../../src/utils"; -import { LedgerKind } from "../../src/ledgers/ledger"; - -// ******************************************** // -// Lightning Sanity Test // -// ******************************************** // -describe("E2E: Sanity - LND Alice pays Bob", () => { - it( - "sanity-lnd-alice-pays-bob", - twoActorTest(async ({ alice, bob }) => { - await alice.sendRequest( - { ledger: LedgerKind.Lightning, asset: AssetKind.Bitcoin }, - { ledger: LedgerKind.Bitcoin, asset: AssetKind.Bitcoin } - ); - const { rHash, paymentRequest } = await bob.lnCreateInvoice( - "20000" - ); - await alice.lnPayInvoiceWithRequest(paymentRequest); - await bob.lnAssertInvoiceSettled(rHash); - }) - ); - - it( - "sanity-lnd-alice-pays-bob-using-hold-invoice", - twoActorTest(async ({ alice, bob }) => { - await alice.sendRequest( - { ledger: LedgerKind.Lightning, asset: AssetKind.Bitcoin }, - { ledger: LedgerKind.Bitcoin, asset: AssetKind.Bitcoin } - ); - - const satAmount = "10000"; - const finalCltvDelta = 10; - - const { secret, secretHash } = bob.lnCreateSha256Secret(); - await bob.lnCreateHoldInvoice( - satAmount, - secretHash, - 3600, - finalCltvDelta - ); - const paymentPromise = alice.lnSendPayment( - bob, - satAmount, - secretHash, - finalCltvDelta - ); - - await bob.lnSettleInvoice(secret, secretHash); - - const pay = await paymentPromise; - expect(pay.paymentPreimage.toString("hex")).toEqual(secret); - - await bob.lnAssertInvoiceSettled(secretHash); - }) - ); -}); +import { twoActorTest } from "../src/actor_test"; +import { AssetKind } from "../src/asset"; +import { sleep } from "../src/utils"; // ******************************************** // // Bitcoin/bitcoin Alpha Ledger/Alpha Asset // @@ -345,88 +290,6 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { ); }); -// ******************************************** // -// Ethereum/ether Alpha Ledger/ Alpha Asset // -// Bitcoin/bitcoin Beta Ledger/Beta Asset // -// ******************************************** // -describe("E2E: Ethereum/ether - Bitcoin/bitcoin", () => { - it( - "rfc003-eth-btc-alice-redeems-bob-redeems", - twoActorTest(async ({ alice, bob }) => { - await alice.sendRequest(AssetKind.Ether, AssetKind.Bitcoin); - await bob.accept(); - - await alice.fund(); - await bob.fund(); - - await alice.redeem(); - await bob.redeem(); - - await alice.assertSwapped(); - await bob.assertSwapped(); - }) - ); - - // ************************ // - // Ignore Failed ETH TX // - // ************************ // - - it( - "rfc003-eth-btc-alpha-deploy-fails", - twoActorTest(async ({ alice, bob }) => { - await alice.sendRequest(AssetKind.Ether, AssetKind.Bitcoin); - await bob.accept(); - - await alice.fundLowGas("0x1b000"); - - await alice.assertAlphaNotDeployed(); - await bob.assertAlphaNotDeployed(); - await bob.assertBetaNotDeployed(); - await alice.assertBetaNotDeployed(); - }) - ); - - // ************************ // - // Refund tests // - // ************************ // - - it( - "rfc003-eth-btc-bob-refunds-alice-refunds", - twoActorTest(async ({ alice, bob }) => { - await alice.sendRequest(AssetKind.Ether, AssetKind.Bitcoin); - await bob.accept(); - - await alice.fund(); - await bob.fund(); - - await bob.refund(); - await alice.refund(); - - await bob.assertRefunded(); - await alice.assertRefunded(); - }) - ); - - // ************************ // - // Bitcoin High Fees // - // ************************ // - - it( - "rfc003-eth-btc-alice-redeems-with-high-fee", - twoActorTest(async ({ alice, bob }) => { - await alice.sendRequest(AssetKind.Ether, AssetKind.Bitcoin); - await bob.accept(); - - await alice.fund(); - await bob.fund(); - - const responsePromise = alice.redeemWithHighFee(); - - return expect(responsePromise).rejects.toThrow(); - }) - ); -}); - // ******************************************** // // Bitcoin/bitcoin Alpha Ledger/ Alpha Asset // // Ethereum/erc20 Beta Ledger/Beta Asset // @@ -468,45 +331,3 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/erc20", () => { }) ); }); - -// ******************************************** // -// Ethereum/erc20 Alpha Ledger/ Alpha Asset // -// Bitcoin/bitcoin Beta Ledger/Beta Asset // -// ******************************************** // -describe("E2E: Ethereum/erc20 - Bitcoin/bitcoin", () => { - it( - "rfc003-eth-erc20_btc-alice-redeems-bob-redeems", - twoActorTest(async ({ alice, bob }) => { - await alice.sendRequest(AssetKind.Erc20, AssetKind.Bitcoin); - await bob.accept(); - - await alice.deploy(); - await alice.fund(); - await bob.fund(); - - await alice.redeem(); - await bob.redeem(); - - await alice.assertSwapped(); - await bob.assertSwapped(); - }) - ); - - it( - "rfc003-eth-erc20_btc-bob-refunds-alice-refunds", - twoActorTest(async ({ alice, bob }) => { - await alice.sendRequest(AssetKind.Erc20, AssetKind.Bitcoin); - await bob.accept(); - - await alice.deploy(); - await alice.fund(); - await bob.fund(); - - await alice.refund(); - await bob.refund(); - - await alice.assertRefunded(); - await bob.assertRefunded(); - }) - ); -}); diff --git a/api_tests/tests/ethereum_bitcoin.ts b/api_tests/tests/ethereum_bitcoin.ts new file mode 100644 index 0000000000..abca9fd851 --- /dev/null +++ b/api_tests/tests/ethereum_bitcoin.ts @@ -0,0 +1,132 @@ +/** + * @ledger ethereum + * @ledger bitcoin + */ + +import { twoActorTest } from "../src/actor_test"; +import { AssetKind } from "../src/asset"; + +// ******************************************** // +// Ethereum/ether Alpha Ledger/ Alpha Asset // +// Bitcoin/bitcoin Beta Ledger/Beta Asset // +// ******************************************** // + +describe("E2E: Ethereum/ether - Bitcoin/bitcoin", () => { + it( + "rfc003-eth-btc-alice-redeems-bob-redeems", + twoActorTest(async ({ alice, bob }) => { + await alice.sendRequest(AssetKind.Ether, AssetKind.Bitcoin); + await bob.accept(); + + await alice.fund(); + await bob.fund(); + + await alice.redeem(); + await bob.redeem(); + + await alice.assertSwapped(); + await bob.assertSwapped(); + }) + ); + + // ************************ // + // Ignore Failed ETH TX // + // ************************ // + + it( + "rfc003-eth-btc-alpha-deploy-fails", + twoActorTest(async ({ alice, bob }) => { + await alice.sendRequest(AssetKind.Ether, AssetKind.Bitcoin); + await bob.accept(); + + await alice.fundLowGas("0x1b000"); + + await alice.assertAlphaNotDeployed(); + await bob.assertAlphaNotDeployed(); + await bob.assertBetaNotDeployed(); + await alice.assertBetaNotDeployed(); + }) + ); + + // ************************ // + // Refund tests // + // ************************ // + + it( + "rfc003-eth-btc-bob-refunds-alice-refunds", + twoActorTest(async ({ alice, bob }) => { + await alice.sendRequest(AssetKind.Ether, AssetKind.Bitcoin); + await bob.accept(); + + await alice.fund(); + await bob.fund(); + + await bob.refund(); + await alice.refund(); + + await bob.assertRefunded(); + await alice.assertRefunded(); + }) + ); + + // ************************ // + // Bitcoin High Fees // + // ************************ // + + it( + "rfc003-eth-btc-alice-redeems-with-high-fee", + twoActorTest(async ({ alice, bob }) => { + await alice.sendRequest(AssetKind.Ether, AssetKind.Bitcoin); + await bob.accept(); + + await alice.fund(); + await bob.fund(); + + const responsePromise = alice.redeemWithHighFee(); + + return expect(responsePromise).rejects.toThrowError(); + }) + ); +}); + +// ******************************************** // +// Ethereum/erc20 Alpha Ledger/ Alpha Asset // +// Bitcoin/bitcoin Beta Ledger/Beta Asset // +// ******************************************** // +describe("E2E: Ethereum/erc20 - Bitcoin/bitcoin", () => { + it( + "rfc003-eth-erc20_btc-alice-redeems-bob-redeems", + twoActorTest(async ({ alice, bob }) => { + await alice.sendRequest(AssetKind.Erc20, AssetKind.Bitcoin); + await bob.accept(); + + await alice.deploy(); + await alice.fund(); + await bob.fund(); + + await alice.redeem(); + await bob.redeem(); + + await alice.assertSwapped(); + await bob.assertSwapped(); + }) + ); + + it( + "rfc003-eth-erc20_btc-bob-refunds-alice-refunds", + twoActorTest(async ({ alice, bob }) => { + await alice.sendRequest(AssetKind.Erc20, AssetKind.Bitcoin); + await bob.accept(); + + await alice.deploy(); + await alice.fund(); + await bob.fund(); + + await alice.refund(); + await bob.refund(); + + await alice.assertRefunded(); + await bob.assertRefunded(); + }) + ); +}); diff --git a/api_tests/tests/dry/lightning_routes.ts b/api_tests/tests/lightning_routes.ts similarity index 94% rename from api_tests/tests/dry/lightning_routes.ts rename to api_tests/tests/lightning_routes.ts index 21ff118bb6..33724a5639 100644 --- a/api_tests/tests/dry/lightning_routes.ts +++ b/api_tests/tests/lightning_routes.ts @@ -1,14 +1,10 @@ -/** - * @logDir lightning_routes - */ - -import { oneActorTest } from "../../src/actor_test"; +import { oneActorTest } from "../src/actor_test"; import { defaultHalightLightningBitcoinHanEthereumEther, defaultHalightLightningBitcoinHerc20EthereumErc20, defaultHanEthereumEtherHalightLightningBitcoin, defaultHerc20EthereumErc20HalightLightningBitcoin, -} from "../../src/actors/defaults"; +} from "../src/actors/defaults"; // ******************************************** // // Lightning routes // diff --git a/api_tests/tests/lnd_sanity.ts b/api_tests/tests/lnd_sanity.ts new file mode 100644 index 0000000000..f015abffc7 --- /dev/null +++ b/api_tests/tests/lnd_sanity.ts @@ -0,0 +1,62 @@ +/** + * @ledger lightning + */ + +// ******************************************** // +// Lightning Sanity Test // +// ******************************************** // +import { twoActorTest } from "../src/actor_test"; +import { LedgerKind } from "../src/ledgers/ledger"; +import { AssetKind } from "../src/asset"; +import { expect } from "chai"; + +describe("E2E: Sanity - LND Alice pays Bob", () => { + it( + "sanity-lnd-alice-pays-bob", + twoActorTest(async ({ alice, bob }) => { + await alice.sendRequest( + { ledger: LedgerKind.Lightning, asset: AssetKind.Bitcoin }, + { ledger: LedgerKind.Bitcoin, asset: AssetKind.Bitcoin } + ); + const { rHash, paymentRequest } = await bob.lnCreateInvoice( + "20000" + ); + await alice.lnPayInvoiceWithRequest(paymentRequest); + await bob.lnAssertInvoiceSettled(rHash); + }) + ); + + it( + "sanity-lnd-alice-pays-bob-using-hold-invoice", + twoActorTest(async ({ alice, bob }) => { + await alice.sendRequest( + { ledger: LedgerKind.Lightning, asset: AssetKind.Bitcoin }, + { ledger: LedgerKind.Bitcoin, asset: AssetKind.Bitcoin } + ); + + const satAmount = "10000"; + const finalCltvDelta = 10; + + const { secret, secretHash } = bob.lnCreateSha256Secret(); + await bob.lnCreateHoldInvoice( + satAmount, + secretHash, + 3600, + finalCltvDelta + ); + const paymentPromise = alice.lnSendPayment( + bob, + satAmount, + secretHash, + finalCltvDelta + ); + + await bob.lnSettleInvoice(secret, secretHash); + + const pay = await paymentPromise; + expect(pay.paymentPreimage.toString("hex")).equals(secret); + + await bob.lnAssertInvoiceSettled(secretHash); + }) + ); +}); diff --git a/api_tests/tests/dry/multiple_peers.ts b/api_tests/tests/multiple_peers.ts similarity index 94% rename from api_tests/tests/dry/multiple_peers.ts rename to api_tests/tests/multiple_peers.ts index 8ef7101729..982c89c339 100644 --- a/api_tests/tests/dry/multiple_peers.ts +++ b/api_tests/tests/multiple_peers.ts @@ -1,9 +1,5 @@ -/** - * @logDir multiple_peers - */ - -import { threeActorTest } from "../../src/actor_test"; -import { createDefaultSwapRequest } from "../../src/utils"; +import { threeActorTest } from "../src/actor_test"; +import { createDefaultSwapRequest } from "../src/utils"; import { expect } from "chai"; import { SwapDetails } from "comit-sdk"; diff --git a/api_tests/tests/dry/peers_using_ip.ts b/api_tests/tests/peers_using_ip.ts similarity index 94% rename from api_tests/tests/dry/peers_using_ip.ts rename to api_tests/tests/peers_using_ip.ts index 330259997e..a40d73337d 100644 --- a/api_tests/tests/dry/peers_using_ip.ts +++ b/api_tests/tests/peers_using_ip.ts @@ -1,11 +1,7 @@ -/** - * @logDir peers_ip - */ - -import { threeActorTest, twoActorTest } from "../../src/actor_test"; -import { createDefaultSwapRequest, sleep } from "../../src/utils"; +import { threeActorTest, twoActorTest } from "../src/actor_test"; +import { createDefaultSwapRequest, sleep } from "../src/utils"; import { expect, request } from "chai"; -import { Actor } from "../../src/actors/actor"; +import { Actor } from "../src/actors/actor"; // ******************************************** // // Peers using ips // diff --git a/api_tests/tests/dry/rfc003_schema.ts b/api_tests/tests/rfc003_schema.ts similarity index 92% rename from api_tests/tests/dry/rfc003_schema.ts rename to api_tests/tests/rfc003_schema.ts index 62ed3b07aa..9d599df8dd 100644 --- a/api_tests/tests/dry/rfc003_schema.ts +++ b/api_tests/tests/rfc003_schema.ts @@ -1,15 +1,11 @@ -/** - * @logDir rfc003 - */ - -import { Actor } from "../../src/actors/actor"; +import { Actor } from "../src/actors/actor"; import { expect, request } from "chai"; import "chai/register-should"; -import "../../src/setup_chai"; -import * as sirenJsonSchema from "../../siren.schema.json"; -import * as swapPropertiesJsonSchema from "../../swap.schema.json"; -import { twoActorTest } from "../../src/actor_test"; -import { createDefaultSwapRequest, DEFAULT_ALPHA } from "../../src/utils"; +import "../src/setup_chai"; +import * as sirenJsonSchema from "../siren.schema.json"; +import * as swapPropertiesJsonSchema from "../swap.schema.json"; +import { twoActorTest } from "../src/actor_test"; +import { createDefaultSwapRequest, DEFAULT_ALPHA } from "../src/utils"; import { Action, EmbeddedRepresentationSubEntity, @@ -220,14 +216,16 @@ describe("Rfc003 schema swap reject tests", () => { const aliceReasonableSwapDetails = await alice.pollSwapDetails( aliceReasonableSwap ); - const aliceStingySwapDetails = await alice.pollSwapDetails( - aliceStingySwap - ); expect( - aliceStingySwapDetails.properties.state.communication.status, + await alice.pollCndUntil( + aliceStingySwap, + (entity) => + entity.properties.state.communication.status === + "DECLINED" + ), "[Alice] Should be in the Declined State after Bob declines a swap" - ).to.eq("DECLINED"); + ).to.exist; expect( aliceReasonableSwapDetails.properties.state.communication diff --git a/api_tests/tests/dry/sanity.ts b/api_tests/tests/sanity.ts similarity index 97% rename from api_tests/tests/dry/sanity.ts rename to api_tests/tests/sanity.ts index 059ea9c905..7489989ac8 100644 --- a/api_tests/tests/dry/sanity.ts +++ b/api_tests/tests/sanity.ts @@ -1,10 +1,6 @@ -/** - * @logDir sanity - */ - -import { oneActorTest } from "../../src/actor_test"; +import { oneActorTest } from "../src/actor_test"; import { expect, request } from "chai"; -import * as sirenJsonSchema from "../../siren.schema.json"; +import * as sirenJsonSchema from "../siren.schema.json"; import { Entity, Link } from "comit-sdk"; // ******************************************** // diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index c2b2a8d094..ba09bf1a5f 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -499,7 +499,7 @@ resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== -"@types/glob@*": +"@types/glob@*", "@types/glob@^7.1.1": version "7.1.1" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== @@ -578,6 +578,18 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.19.1.tgz#33509849f8e679e4add158959fdb086440e9553f" integrity sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ== +"@types/proper-lockfile@^4.1.1": + version "4.1.1" + resolved "https://registry.yarnpkg.com/@types/proper-lockfile/-/proper-lockfile-4.1.1.tgz#99f026cbfdbe6305bdd454ffd5fefc1bd064beb1" + integrity sha512-HAjVfDa73pFgivViHyDu8HHHcds+W4MgOuZZAdyFJrHS8ngtCXmhl4hc2YXqSOwO6Bsa+iF2Sgxb2+gv874VOQ== + dependencies: + "@types/retry" "*" + +"@types/retry@*": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" + integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== + "@types/rimraf@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-3.0.0.tgz#b9d03f090ece263671898d57bb7bb007023ac19f" @@ -842,13 +854,6 @@ astral-regex@^1.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== -async-mutex@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.2.1.tgz#ffa0bc669f54f7692812b0ce83de487564677c08" - integrity sha512-8GAyGD9/Fr4TgMigfCAXsyjvPturIqHDDw7Mim6DtNRbwxY2ul/D4b4CF1qjaMvomd/SJs/8EM23M+RGDEpaKA== - dependencies: - tslib "^1.11.1" - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -2302,7 +2307,7 @@ glob@^6.0.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: +glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -2324,16 +2329,16 @@ google-protobuf@^3.6.1: resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.11.4.tgz#598ca405a3cfa917a2132994d008b5932ef42014" integrity sha512-lL6b04rDirurUBOgsY2+LalI6Evq8eH5TcNzi7TYQ3BsIWelT0KSOQSBsXuavEkNf+odQU6c0lgz3UsZXeNX9Q== +graceful-fs@^4.1.11, graceful-fs@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" + integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== + graceful-fs@^4.1.15, graceful-fs@^4.1.6, graceful-fs@^4.2.0: version "4.2.2" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02" integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q== -graceful-fs@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" - integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== - growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" @@ -4041,6 +4046,13 @@ pretty-format@^25.2.1, pretty-format@^25.2.6: ansi-styles "^4.0.0" react-is "^16.12.0" +process-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/process-exists/-/process-exists-4.0.0.tgz#dc12d87798c17b3f129f716631e2ccdaf240b4ab" + integrity sha512-BnlcYPiZjSW+fye12g9B7UeCzMAOdMkxuTz3zcytJ2BHwYZf2RoKvuuwUcJLeXlGj58x9YQrvhT21PmKhUc4UQ== + dependencies: + ps-list "^6.3.0" + process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" @@ -4054,6 +4066,15 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.4" +proper-lockfile@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-4.1.1.tgz#284cf9db9e30a90e647afad69deb7cb06881262c" + integrity sha512-1w6rxXodisVpn7QYvLk706mzprPTAPCYAqxMvctmPN3ekuRk/kuGkGc82pangZiAt4R3lwSuUzheTTn0/Yb7Zg== + dependencies: + graceful-fs "^4.1.11" + retry "^0.12.0" + signal-exit "^3.0.2" + protobufjs@^5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-5.0.3.tgz#e4dfe9fb67c90b2630d15868249bcc4961467a17" @@ -4091,6 +4112,11 @@ proxy-addr@~2.0.5: forwarded "~0.1.2" ipaddr.js "1.9.0" +ps-list@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/ps-list/-/ps-list-6.3.0.tgz#a2b775c2db7d547a28fbaa3a05e4c281771259be" + integrity sha512-qau0czUSB0fzSlBOQt0bo+I2v6R+xiQdj78e1BR/Qjfl5OHWJ/urXi8+ilw1eHe+5hSeDI1wrwVTgDp2wst4oA== + psl@^1.1.24: version "1.1.32" resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.32.tgz#3f132717cf2f9c169724b2b6caf373cf694198db" @@ -4325,6 +4351,11 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + rfdc@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.1.4.tgz#ba72cc1367a0ccd9cf81a870b3b58bd3ad07f8c2" @@ -4967,7 +4998,7 @@ ts-protoc-gen@^0.8.0: dependencies: google-protobuf "^3.6.1" -tslib@^1.10.0, tslib@^1.11.1, tslib@^1.8.1: +tslib@^1.10.0, tslib@^1.8.1: version "1.11.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== From 599aee7fac9a18068efb1827c18120d655e0d252 Mon Sep 17 00:00:00 2001 From: Philipp Hoenisch Date: Tue, 31 Mar 2020 14:43:48 +1100 Subject: [PATCH 64/88] Split up tests to get more feedback and more parallelization --- api_tests/src/test_environment.ts | 1 + api_tests/src/wallets/ethereum.ts | 13 +- api_tests/tests/bitcoin_erc20.ts | 45 +++++ api_tests/tests/bitcoin_ethereum.ts | 181 ------------------ .../tests/bitcoin_ethereum_restart_cnds.ts | 115 +++++++++++ api_tests/tests/erc20_bitcoin.ts | 45 +++++ api_tests/tests/ethereum_bitcoin.ts | 47 ----- 7 files changed, 216 insertions(+), 231 deletions(-) create mode 100644 api_tests/tests/bitcoin_erc20.ts create mode 100644 api_tests/tests/bitcoin_ethereum_restart_cnds.ts create mode 100644 api_tests/tests/erc20_bitcoin.ts diff --git a/api_tests/src/test_environment.ts b/api_tests/src/test_environment.ts index 223abbb896..2fcfbc5023 100644 --- a/api_tests/src/test_environment.ts +++ b/api_tests/src/test_environment.ts @@ -63,6 +63,7 @@ export default class TestEnvironment extends NodeEnvironment { type: "pattern", pattern: "%d %5.10p: %m", }, + timeout: 2000, }, }, categories: { diff --git a/api_tests/src/wallets/ethereum.ts b/api_tests/src/wallets/ethereum.ts index 6701fa1956..d414dd8590 100644 --- a/api_tests/src/wallets/ethereum.ts +++ b/api_tests/src/wallets/ethereum.ts @@ -63,7 +63,11 @@ export class EthereumWallet implements Wallet { data, }; const transactionResponse = await this.sendTransaction(tx); - const transactionReceipt = await transactionResponse.wait(1); + const transactionReceipt = await this.parity.provider.waitForTransaction( + transactionResponse.hash, + 1 + ); + // const transactionReceipt = await transactionResponse.wait(1); if (!transactionReceipt.status) { throw new Error( @@ -116,7 +120,7 @@ export class EthereumWallet implements Wallet { gasLimit: 21000, }); - await response.wait(1); + await this.parity.provider.waitForTransaction(response.hash, 1); const balance = await this.getBalanceByAsset(asset); @@ -140,7 +144,10 @@ export class EthereumWallet implements Wallet { data, }; const transactionResponse = await this.parity.sendTransaction(tx); - const transactionReceipt = await transactionResponse.wait(1); + const transactionReceipt = await this.parity.provider.waitForTransaction( + transactionResponse.hash, + 1 + ); return transactionReceipt.contractAddress; } diff --git a/api_tests/tests/bitcoin_erc20.ts b/api_tests/tests/bitcoin_erc20.ts new file mode 100644 index 0000000000..ad7f1ec500 --- /dev/null +++ b/api_tests/tests/bitcoin_erc20.ts @@ -0,0 +1,45 @@ +/** + * @ledger ethereum + * @ledger bitcoin + */ + +import { twoActorTest } from "../src/actor_test"; +import { AssetKind } from "../src/asset"; + +describe("E2E: Bitcoin/bitcoin - Ethereum/erc20", () => { + it( + "rfc003-btc-eth-erc20-alice-redeems-bob-redeems", + twoActorTest(async ({ alice, bob }) => { + await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Erc20); + await bob.accept(); + + await alice.fund(); + await bob.deploy(); + await bob.fund(); + + await alice.redeem(); + await bob.redeem(); + + await alice.assertSwapped(); + await bob.assertSwapped(); + }) + ); + + it( + "rfc003-btc-eth-erc20-bob-refunds-alice-refunds", + twoActorTest(async ({ alice, bob }) => { + await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Erc20); + await bob.accept(); + + await alice.fund(); + await bob.deploy(); + await bob.fund(); + + await alice.refund(); + await bob.refund(); + + await alice.assertRefunded(); + await bob.assertRefunded(); + }) + ); +}); diff --git a/api_tests/tests/bitcoin_ethereum.ts b/api_tests/tests/bitcoin_ethereum.ts index 59e1636ca3..0a09230fb7 100644 --- a/api_tests/tests/bitcoin_ethereum.ts +++ b/api_tests/tests/bitcoin_ethereum.ts @@ -5,12 +5,7 @@ import { twoActorTest } from "../src/actor_test"; import { AssetKind } from "../src/asset"; -import { sleep } from "../src/utils"; -// ******************************************** // -// Bitcoin/bitcoin Alpha Ledger/Alpha Asset // -// Ethereum/ether Beta Ledger/Beta Asset // -// ******************************************** // describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { it( "rfc003-btc-eth-alice-redeems-bob-redeems", @@ -29,10 +24,6 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { }) ); - // ************************ // - // Refund test // - // ************************ // - it( "rfc003-btc-eth-bob-refunds-alice-refunds", twoActorTest(async ({ alice, bob }) => { @@ -67,136 +58,6 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { }) ); - // ************************ // - // Restart cnd test // - // ************************ // - - it( - "rfc003-btc-eth-cnd-can-be-restarted", - twoActorTest(async ({ alice, bob }) => { - await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); - await bob.accept(); - - await alice.currentSwapIsAccepted(); - await bob.currentSwapIsAccepted(); - - await alice.restart(); - await bob.restart(); - - await alice.currentSwapIsAccepted(); - await bob.currentSwapIsAccepted(); - }) - ); - - // ************************ // - // Resume cnd test // - // ************************ // - - it( - "rfc003-btc-eth-resume-alice-down-bob-funds", - twoActorTest(async ({ alice, bob }) => { - await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); - await bob.accept(); - - await alice.fund(); - await alice.stop(); - - // Action happens while alice is down. - await bob.fund(); - - // Blocks are geneated every second here, wait to ensure - // we look into the past for the transaction. - await sleep(2000); - await alice.start(); - - await alice.redeem(); - await bob.redeem(); - - await alice.assertSwapped(); - await bob.assertSwapped(); - }) - ); - - it( - "rfc003-btc-eth-resume-alice-down-bob-redeems", - twoActorTest(async ({ alice, bob }) => { - await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); - await bob.accept(); - - await alice.fund(); - await bob.fund(); - - await alice.redeem(); - await alice.stop(); - - // Action happens while alice is down. - await bob.redeem(); - - // Blocks are geneated every second here, wait to ensure - // we look into the past for the transaction. - await sleep(2000); - await alice.start(); - - await alice.assertSwapped(); - await bob.assertSwapped(); - }) - ); - - it( - "rfc003-btc-eth-resume-bob-down-alice-funds", - twoActorTest(async ({ alice, bob }) => { - await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); - await bob.accept(); - - // Wait for Alice to receive the accept message before stopping Bob's cnd. - await alice.currentSwapIsAccepted(); - - await bob.stop(); - - // Action happens while bob is down. - await alice.fund(); - - // Blocks are geneated every second here, wait to ensure - // we look into the past for the transaction. - await sleep(2000); - await bob.start(); - - await bob.fund(); - - await alice.redeem(); - await bob.redeem(); - - await alice.assertSwapped(); - await bob.assertSwapped(); - }) - ); - - it( - "rfc003-btc-eth-resume-bob-down-alice-redeems", - twoActorTest(async ({ alice, bob }) => { - await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); - await bob.accept(); - - await alice.fund(); - await bob.fund(); - - await bob.stop(); - - // Action happens while bob is down. - await alice.redeem(); - - // Blocks are geneated every second here, wait to ensure - // we look into the past for the transaction. - await sleep(2000); - await bob.start(); - - await bob.redeem(); - - await alice.assertSwapped(); - await bob.assertSwapped(); - }) - ); - // ************************ // // Underfunding test // // ************************ // @@ -289,45 +150,3 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { }) ); }); - -// ******************************************** // -// Bitcoin/bitcoin Alpha Ledger/ Alpha Asset // -// Ethereum/erc20 Beta Ledger/Beta Asset // -// ******************************************** // -describe("E2E: Bitcoin/bitcoin - Ethereum/erc20", () => { - it( - "rfc003-btc-eth-erc20-alice-redeems-bob-redeems", - twoActorTest(async ({ alice, bob }) => { - await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Erc20); - await bob.accept(); - - await alice.fund(); - await bob.deploy(); - await bob.fund(); - - await alice.redeem(); - await bob.redeem(); - - await alice.assertSwapped(); - await bob.assertSwapped(); - }) - ); - - it( - "rfc003-btc-eth-erc20-bob-refunds-alice-refunds", - twoActorTest(async ({ alice, bob }) => { - await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Erc20); - await bob.accept(); - - await alice.fund(); - await bob.deploy(); - await bob.fund(); - - await alice.refund(); - await bob.refund(); - - await alice.assertRefunded(); - await bob.assertRefunded(); - }) - ); -}); diff --git a/api_tests/tests/bitcoin_ethereum_restart_cnds.ts b/api_tests/tests/bitcoin_ethereum_restart_cnds.ts new file mode 100644 index 0000000000..e3e26aee0e --- /dev/null +++ b/api_tests/tests/bitcoin_ethereum_restart_cnds.ts @@ -0,0 +1,115 @@ +/** + * @ledger ethereum + * @ledger bitcoin + */ + +import { twoActorTest } from "../src/actor_test"; +import { AssetKind } from "../src/asset"; +import { sleep } from "../src/utils"; + +describe("E2E: Bitcoin/bitcoin - Ethereum/ether (restart cnd nodes)", () => { + it( + "rfc003-btc-eth-resume-alice-down-bob-funds", + twoActorTest(async ({ alice, bob }) => { + await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); + await bob.accept(); + + await alice.fund(); + await alice.stop(); + + // Action happens while alice is down. + await bob.fund(); + + // Blocks are geneated every second here, wait to ensure + // we look into the past for the transaction. + await sleep(2000); + await alice.start(); + + await alice.redeem(); + await bob.redeem(); + + await alice.assertSwapped(); + await bob.assertSwapped(); + }) + ); + + it( + "rfc003-btc-eth-resume-alice-down-bob-redeems", + twoActorTest(async ({ alice, bob }) => { + await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); + await bob.accept(); + + await alice.fund(); + await bob.fund(); + + await alice.redeem(); + await alice.stop(); + + // Action happens while alice is down. + await bob.redeem(); + + // Blocks are geneated every second here, wait to ensure + // we look into the past for the transaction. + await sleep(2000); + await alice.start(); + + await alice.assertSwapped(); + await bob.assertSwapped(); + }) + ); + + it( + "rfc003-btc-eth-resume-bob-down-alice-funds", + twoActorTest(async ({ alice, bob }) => { + await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); + await bob.accept(); + + // Wait for Alice to receive the accept message before stopping Bob's cnd. + await alice.currentSwapIsAccepted(); + + await bob.stop(); + + // Action happens while bob is down. + await alice.fund(); + + // Blocks are geneated every second here, wait to ensure + // we look into the past for the transaction. + await sleep(2000); + await bob.start(); + + await bob.fund(); + + await alice.redeem(); + await bob.redeem(); + + await alice.assertSwapped(); + await bob.assertSwapped(); + }) + ); + + it( + "rfc003-btc-eth-resume-bob-down-alice-redeems", + twoActorTest(async ({ alice, bob }) => { + await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); + await bob.accept(); + + await alice.fund(); + await bob.fund(); + + await bob.stop(); + + // Action happens while bob is down. + await alice.redeem(); + + // Blocks are geneated every second here, wait to ensure + // we look into the past for the transaction. + await sleep(2000); + await bob.start(); + + await bob.redeem(); + + await alice.assertSwapped(); + await bob.assertSwapped(); + }) + ); +}); diff --git a/api_tests/tests/erc20_bitcoin.ts b/api_tests/tests/erc20_bitcoin.ts new file mode 100644 index 0000000000..36b8b6be76 --- /dev/null +++ b/api_tests/tests/erc20_bitcoin.ts @@ -0,0 +1,45 @@ +/** + * @ledger ethereum + * @ledger bitcoin + */ + +import { twoActorTest } from "../src/actor_test"; +import { AssetKind } from "../src/asset"; + +describe("E2E: Ethereum/erc20 - Bitcoin/bitcoin", () => { + it( + "rfc003-eth-erc20_btc-alice-redeems-bob-redeems", + twoActorTest(async ({ alice, bob }) => { + await alice.sendRequest(AssetKind.Erc20, AssetKind.Bitcoin); + await bob.accept(); + + await alice.deploy(); + await alice.fund(); + await bob.fund(); + + await alice.redeem(); + await bob.redeem(); + + await alice.assertSwapped(); + await bob.assertSwapped(); + }) + ); + + it( + "rfc003-eth-erc20_btc-bob-refunds-alice-refunds", + twoActorTest(async ({ alice, bob }) => { + await alice.sendRequest(AssetKind.Erc20, AssetKind.Bitcoin); + await bob.accept(); + + await alice.deploy(); + await alice.fund(); + await bob.fund(); + + await alice.refund(); + await bob.refund(); + + await alice.assertRefunded(); + await bob.assertRefunded(); + }) + ); +}); diff --git a/api_tests/tests/ethereum_bitcoin.ts b/api_tests/tests/ethereum_bitcoin.ts index abca9fd851..e3312416c9 100644 --- a/api_tests/tests/ethereum_bitcoin.ts +++ b/api_tests/tests/ethereum_bitcoin.ts @@ -6,11 +6,6 @@ import { twoActorTest } from "../src/actor_test"; import { AssetKind } from "../src/asset"; -// ******************************************** // -// Ethereum/ether Alpha Ledger/ Alpha Asset // -// Bitcoin/bitcoin Beta Ledger/Beta Asset // -// ******************************************** // - describe("E2E: Ethereum/ether - Bitcoin/bitcoin", () => { it( "rfc003-eth-btc-alice-redeems-bob-redeems", @@ -88,45 +83,3 @@ describe("E2E: Ethereum/ether - Bitcoin/bitcoin", () => { }) ); }); - -// ******************************************** // -// Ethereum/erc20 Alpha Ledger/ Alpha Asset // -// Bitcoin/bitcoin Beta Ledger/Beta Asset // -// ******************************************** // -describe("E2E: Ethereum/erc20 - Bitcoin/bitcoin", () => { - it( - "rfc003-eth-erc20_btc-alice-redeems-bob-redeems", - twoActorTest(async ({ alice, bob }) => { - await alice.sendRequest(AssetKind.Erc20, AssetKind.Bitcoin); - await bob.accept(); - - await alice.deploy(); - await alice.fund(); - await bob.fund(); - - await alice.redeem(); - await bob.redeem(); - - await alice.assertSwapped(); - await bob.assertSwapped(); - }) - ); - - it( - "rfc003-eth-erc20_btc-bob-refunds-alice-refunds", - twoActorTest(async ({ alice, bob }) => { - await alice.sendRequest(AssetKind.Erc20, AssetKind.Bitcoin); - await bob.accept(); - - await alice.deploy(); - await alice.fund(); - await bob.fund(); - - await alice.refund(); - await bob.refund(); - - await alice.assertRefunded(); - await bob.assertRefunded(); - }) - ); -}); From d46bf9caaf1b381128415fc3fba2cc315f4abf52 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 8 Apr 2020 18:15:20 +1000 Subject: [PATCH 65/88] Delete e2e_test_environment.ts --- api_tests/src/e2e_test_environment.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 api_tests/src/e2e_test_environment.ts diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts deleted file mode 100644 index e69de29bb2..0000000000 From ae44bc79b386c68e0157420acea4d55ec24ba232 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2020 15:54:34 +0000 Subject: [PATCH 66/88] Bump jest from 25.2.7 to 25.3.0 in /api_tests Bumps [jest](https://github.com/facebook/jest) from 25.2.7 to 25.3.0. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/compare/v25.2.7...v25.3.0) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 679 +++++++++++++++++++++++------------------ 2 files changed, 391 insertions(+), 290 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 7147d37259..33632a9e32 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -48,7 +48,7 @@ "get-port": "^5.1.1", "glob": "^7.1.6", "jasmine": "^3.5.0", - "jest": "^25.2.7", + "jest": "^25.3.0", "js-sha256": "^0.9.0", "log4js": "^6.1.2", "p-timeout": "^3.2.0", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index ba09bf1a5f..ca21107fdb 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -56,7 +56,7 @@ dependencies: "@babel/types" "^7.8.3" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.8.0": +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz#9ea293be19babc0f52ff8ca88b34c3611b208670" integrity sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ== @@ -91,20 +91,76 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.6.tgz#ba5c9910cddb77685a008e3c587af8d27b67962c" integrity sha512-trGNYSfwq5s0SgM1BMEB8hX3NDmO7EP2wsDGDexiaKMB92BaRpS+qZfpkMqUBhcsOTBwNy9B/jieo4ad/t/z2g== -"@babel/plugin-syntax-bigint@^7.0.0": +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-object-rest-spread@^7.0.0": +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.8.3.tgz#6cb933a8872c8d359bfde69bbeaae5162fd1e8f7" + integrity sha512-UcAyQWg2bAN647Q+O811tG9MrJ38Z10jjhQdKNAL8fsyPzE3cCN/uT+f55cFVY4aGO4jqJAvmqsuY3GQDwAoXg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.8.3.tgz#3995d7d7ffff432f6ddc742b47e730c054599897" + integrity sha512-Zpg2Sgc++37kuFl6ppq2Q7Awc6E6AIW671x5PY8E/f7MCIyPPGK/EoeZXvvY3P42exZ3Q4/t3YOzP/HiN79jDg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz#0e3fb63e09bea1b11e96467271c8308007e7c41f" + integrity sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + "@babel/template@^7.7.4", "@babel/template@^7.8.3", "@babel/template@^7.8.6": version "7.8.6" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" @@ -179,43 +235,43 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== -"@jest/console@^25.2.6": - version "25.2.6" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-25.2.6.tgz#f594847ec8aef3cf27f448abe97e76e491212e97" - integrity sha512-bGp+0PicZVCEhb+ifnW9wpKWONNdkhtJsRE7ap729hiAfTvCN6VhGx0s/l/V/skA2pnyqq+N/7xl9ZWfykDpsg== +"@jest/console@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-25.3.0.tgz#33b56b81238427bf3ebe3f7b3378d2f79cdbd409" + integrity sha512-LvSDNqpmZIZyweFaEQ6wKY7CbexPitlsLHGJtcooNECo0An/w49rFhjCJzu6efeb6+a3ee946xss1Jcd9r03UQ== dependencies: "@jest/source-map" "^25.2.6" chalk "^3.0.0" - jest-util "^25.2.6" + jest-util "^25.3.0" slash "^3.0.0" -"@jest/core@^25.2.7": - version "25.2.7" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-25.2.7.tgz#58d697687e94ee644273d15e4eed6a20e27187cd" - integrity sha512-Nd6ELJyR+j0zlwhzkfzY70m04hAur0VnMwJXVe4VmmD/SaQ6DEyal++ERQ1sgyKIKKEqRuui6k/R0wHLez4P+g== +"@jest/core@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-25.3.0.tgz#80f97a7a8b59dde741a24f30871cc26d0197d426" + integrity sha512-+D5a/tFf6pA/Gqft2DLBp/yeSRgXhlJ+Wpst0X/ZkfTRP54qDR3C61VfHwaex+GzZBiTcE9vQeoZ2v5T10+Mqw== dependencies: - "@jest/console" "^25.2.6" - "@jest/reporters" "^25.2.6" - "@jest/test-result" "^25.2.6" - "@jest/transform" "^25.2.6" - "@jest/types" "^25.2.6" + "@jest/console" "^25.3.0" + "@jest/reporters" "^25.3.0" + "@jest/test-result" "^25.3.0" + "@jest/transform" "^25.3.0" + "@jest/types" "^25.3.0" ansi-escapes "^4.2.1" chalk "^3.0.0" exit "^0.1.2" graceful-fs "^4.2.3" - jest-changed-files "^25.2.6" - jest-config "^25.2.7" - jest-haste-map "^25.2.6" - jest-message-util "^25.2.6" + jest-changed-files "^25.3.0" + jest-config "^25.3.0" + jest-haste-map "^25.3.0" + jest-message-util "^25.3.0" jest-regex-util "^25.2.6" - jest-resolve "^25.2.6" - jest-resolve-dependencies "^25.2.7" - jest-runner "^25.2.7" - jest-runtime "^25.2.7" - jest-snapshot "^25.2.7" - jest-util "^25.2.6" - jest-validate "^25.2.6" - jest-watcher "^25.2.7" + jest-resolve "^25.3.0" + jest-resolve-dependencies "^25.3.0" + jest-runner "^25.3.0" + jest-runtime "^25.3.0" + jest-snapshot "^25.3.0" + jest-util "^25.3.0" + jest-validate "^25.3.0" + jest-watcher "^25.3.0" micromatch "^4.0.2" p-each-series "^2.1.0" realpath-native "^2.0.0" @@ -223,36 +279,36 @@ slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^25.2.6": - version "25.2.6" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-25.2.6.tgz#8f7931e79abd81893ce88b7306f0cc4744835000" - integrity sha512-17WIw+wCb9drRNFw1hi8CHah38dXVdOk7ga9exThhGtXlZ9mK8xH4DjSB9uGDGXIWYSHmrxoyS6KJ7ywGr7bzg== +"@jest/environment@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-25.3.0.tgz#587f28ddb4b0dfe97404d3d4a4c9dbfa0245fb2e" + integrity sha512-vgooqwJTHLLak4fE+TaCGeYP7Tz1Y3CKOsNxR1sE0V3nx3KRUHn3NUnt+wbcfd5yQWKZQKAfW6wqbuwQLrXo3g== dependencies: - "@jest/fake-timers" "^25.2.6" - "@jest/types" "^25.2.6" - jest-mock "^25.2.6" + "@jest/fake-timers" "^25.3.0" + "@jest/types" "^25.3.0" + jest-mock "^25.3.0" -"@jest/fake-timers@^25.2.6": - version "25.2.6" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.2.6.tgz#239dbde3f56badf7d05bcf888f5d669296077cad" - integrity sha512-A6qtDIA2zg/hVgUJJYzQSHFBIp25vHdSxW/s4XmTJAYxER6eL0NQdQhe4+232uUSviKitubHGXXirt5M7blPiA== +"@jest/fake-timers@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.3.0.tgz#995aad36d5c8984165ca5db12e740ab8dbf7042a" + integrity sha512-NHAj7WbsyR3qBJPpBwSwqaq2WluIvUQsyzpJTN7XDVk7VnlC/y1BAnaYZL3vbPIP8Nhm0Ae5DJe0KExr/SdMJQ== dependencies: - "@jest/types" "^25.2.6" - jest-message-util "^25.2.6" - jest-mock "^25.2.6" - jest-util "^25.2.6" + "@jest/types" "^25.3.0" + jest-message-util "^25.3.0" + jest-mock "^25.3.0" + jest-util "^25.3.0" lolex "^5.0.0" -"@jest/reporters@^25.2.6": - version "25.2.6" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-25.2.6.tgz#6d87e40fb15adb69e22bb83aa02a4d88b2253b5f" - integrity sha512-DRMyjaxcd6ZKctiXNcuVObnPwB1eUs7xrUVu0J2V0p5/aZJei5UM9GL3s/bmN4hRV8Mt3zXh+/9X2o0Q4ClZIA== +"@jest/reporters@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-25.3.0.tgz#7f39f0e6911561cc5112a1b54656de18faee269b" + integrity sha512-1u0ZBygs0C9DhdYgLCrRfZfNKQa+9+J7Uo+Z9z0RWLHzgsxhoG32lrmMOtUw48yR6bLNELdvzormwUqSk4H4Vg== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^25.2.6" - "@jest/test-result" "^25.2.6" - "@jest/transform" "^25.2.6" - "@jest/types" "^25.2.6" + "@jest/console" "^25.3.0" + "@jest/test-result" "^25.3.0" + "@jest/transform" "^25.3.0" + "@jest/types" "^25.3.0" chalk "^3.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" @@ -261,10 +317,10 @@ istanbul-lib-instrument "^4.0.0" istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.0.0" - jest-haste-map "^25.2.6" - jest-resolve "^25.2.6" - jest-util "^25.2.6" + istanbul-reports "^3.0.2" + jest-haste-map "^25.3.0" + jest-resolve "^25.3.0" + jest-util "^25.3.0" jest-worker "^25.2.6" slash "^3.0.0" source-map "^0.6.0" @@ -283,41 +339,41 @@ graceful-fs "^4.2.3" source-map "^0.6.0" -"@jest/test-result@^25.2.6": - version "25.2.6" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.2.6.tgz#f6082954955313eb96f6cabf9fb14f8017826916" - integrity sha512-gmGgcF4qz/pkBzyfJuVHo2DA24kIgVQ5Pf/VpW4QbyMLSegi8z+9foSZABfIt5se6k0fFj/3p/vrQXdaOgit0w== +"@jest/test-result@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.3.0.tgz#137fab5e5c6fed36e5d40735d1eb029325e3bf06" + integrity sha512-mqrGuiiPXl1ap09Mydg4O782F3ouDQfsKqtQzIjitpwv3t1cHDwCto21jThw6WRRE+dKcWQvLG70GpyLJICfGw== dependencies: - "@jest/console" "^25.2.6" - "@jest/types" "^25.2.6" + "@jest/console" "^25.3.0" + "@jest/types" "^25.3.0" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^25.2.7": - version "25.2.7" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-25.2.7.tgz#e4331f7b4850e34289b9a5c8ec8a2c03b400da8f" - integrity sha512-s2uYGOXONDSTJQcZJ9A3Zkg3hwe53RlX1HjUNqjUy3HIqwgwCKJbnAKYsORPbhxXi3ARMKA7JNBi9arsTxXoYw== +"@jest/test-sequencer@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-25.3.0.tgz#271ad5f2b8f8137d092ccedc87e16a50f8676209" + integrity sha512-Xvns3xbji7JCvVcDGvqJ/pf4IpmohPODumoPEZJ0/VgC5gI4XaNVIBET2Dq5Czu6Gk3xFcmhtthh/MBOTljdNg== dependencies: - "@jest/test-result" "^25.2.6" - jest-haste-map "^25.2.6" - jest-runner "^25.2.7" - jest-runtime "^25.2.7" + "@jest/test-result" "^25.3.0" + jest-haste-map "^25.3.0" + jest-runner "^25.3.0" + jest-runtime "^25.3.0" -"@jest/transform@^25.2.6": - version "25.2.6" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-25.2.6.tgz#007fd946dedf12d2a9eb5d4154faf1991d5f61ff" - integrity sha512-rZnjCjZf9avPOf9q/w9RUZ9Uc29JmB53uIXNJmNz04QbDMD5cR/VjfikiMKajBsXe2vnFl5sJ4RTt+9HPicauQ== +"@jest/transform@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-25.3.0.tgz#083c5447d5307d9b9494d6968115b647460e71f1" + integrity sha512-W01p8kTDvvEX6kd0tJc7Y5VdYyFaKwNWy1HQz6Jqlhu48z/8Gxp+yFCDVj+H8Rc7ezl3Mg0hDaGuFVkmHOqirg== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^25.2.6" + "@jest/types" "^25.3.0" babel-plugin-istanbul "^6.0.0" chalk "^3.0.0" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" graceful-fs "^4.2.3" - jest-haste-map "^25.2.6" + jest-haste-map "^25.3.0" jest-regex-util "^25.2.6" - jest-util "^25.2.6" + jest-util "^25.3.0" micromatch "^4.0.2" pirates "^4.0.1" realpath-native "^2.0.0" @@ -335,6 +391,16 @@ "@types/yargs" "^15.0.0" chalk "^3.0.0" +"@jest/types@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.3.0.tgz#88f94b277a1d028fd7117bc1f74451e0fc2131e7" + integrity sha512-UkaDNewdqXAmCDbN2GlUM6amDKS78eCqiw/UmF5nE0mmLTd6moJkiZJML/X52Ke3LH7Swhw883IRXq8o9nWjVw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^15.0.0" + chalk "^3.0.0" + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -417,10 +483,10 @@ dependencies: type-detect "4.0.8" -"@types/babel__core@^7.1.0": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.6.tgz#16ff42a5ae203c9af1c6e190ed1f30f83207b610" - integrity sha512-tTnhWszAqvXnhW7m5jQU9PomXSiKXk2sFxpahXvI20SZKu9ylPi8WtIxueZ6ehDWikPT0jeFujMj3X4ZHuf3Tg== +"@types/babel__core@^7.1.7": + version "7.1.7" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.7.tgz#1dacad8840364a57c98d0dd4855c6dd3752c6b89" + integrity sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -882,16 +948,16 @@ axios@^0.19.0: follow-redirects "1.5.10" is-buffer "^2.0.2" -babel-jest@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.2.6.tgz#fe67ff4d0db3626ca8082da8881dd5e84e07ae75" - integrity sha512-MDJOAlwtIeIQiGshyX0d2PxTbV73xZMpNji40ivVTPQOm59OdRR9nYCkffqI7ugtsK4JR98HgNKbDbuVf4k5QQ== +babel-jest@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.3.0.tgz#999d0c19e8427f66b796bf9ea233eedf087b957c" + integrity sha512-qiXeX1Cmw4JZ5yQ4H57WpkO0MZ61Qj+YnsVUwAMnDV5ls+yHon11XjarDdgP7H8lTmiEi6biiZA8y3Tmvx6pCg== dependencies: - "@jest/transform" "^25.2.6" - "@jest/types" "^25.2.6" - "@types/babel__core" "^7.1.0" + "@jest/transform" "^25.3.0" + "@jest/types" "^25.3.0" + "@types/babel__core" "^7.1.7" babel-plugin-istanbul "^6.0.0" - babel-preset-jest "^25.2.6" + babel-preset-jest "^25.3.0" chalk "^3.0.0" slash "^3.0.0" @@ -913,14 +979,29 @@ babel-plugin-jest-hoist@^25.2.6: dependencies: "@types/babel__traverse" "^7.0.6" -babel-preset-jest@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-25.2.6.tgz#5d3f7c99e2a8508d61775c9d68506d143b7f71b5" - integrity sha512-Xh2eEAwaLY9+SyMt/xmGZDnXTW/7pSaBPG0EMo7EuhvosFKVWYB6CqwYD31DaEQuoTL090oDZ0FEqygffGRaSQ== +babel-preset-current-node-syntax@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.2.tgz#fb4a4c51fe38ca60fede1dc74ab35eb843cb41d6" + integrity sha512-u/8cS+dEiK1SFILbOC8/rUI3ml9lboKuuMvZ/4aQnQmhecQAgPw5ew066C1ObnEAUmlx7dv/s2z52psWEtLNiw== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +babel-preset-jest@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-25.3.0.tgz#9ab40aee52a19bdc52b8b1ec2403d5914ac3d86b" + integrity sha512-tjdvLKNMwDI9r+QWz9sZUQGTq1dpoxjUqFUpEasAc7MOtHg9XuLT2fx0udFG+k1nvMV0WvHHVAN7VmCZ+1Zxbw== dependencies: - "@babel/plugin-syntax-bigint" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" babel-plugin-jest-hoist "^25.2.6" + babel-preset-current-node-syntax "^0.1.2" balanced-match@^1.0.0: version "1.0.0" @@ -1998,16 +2079,16 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^25.2.7: - version "25.2.7" - resolved "https://registry.yarnpkg.com/expect/-/expect-25.2.7.tgz#509b79f47502835f4071ff3ecc401f2eaecca709" - integrity sha512-yA+U2Ph0MkMsJ9N8q5hs9WgWI6oJYfecdXta6LkP/alY/jZZL1MHlJ2wbLh60Ucqf3G+51ytbqV3mlGfmxkpNw== +expect@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-25.3.0.tgz#5fd36e51befd05afb7184bc954f8a4792d184c71" + integrity sha512-buboTXML2h/L0Kh44Ys2Cx49mX20ISc5KDirkxIs3Q9AJv0kazweUAbukegr+nHDOvFRKmxdojjIHCjqAceYfg== dependencies: - "@jest/types" "^25.2.6" + "@jest/types" "^25.3.0" ansi-styles "^4.0.0" jest-get-type "^25.2.6" - jest-matcher-utils "^25.2.7" - jest-message-util "^25.2.6" + jest-matcher-utils "^25.3.0" + jest-message-util "^25.3.0" jest-regex-util "^25.2.6" express@^4.17.1: @@ -2764,10 +2845,10 @@ istanbul-lib-source-maps@^4.0.0: istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.0.tgz#d4d16d035db99581b6194e119bbf36c963c5eb70" - integrity sha512-2osTcC8zcOSUkImzN2EWQta3Vdi4WjjKw99P2yWx5mLnigAM0Rd5uYFn1cf2i/Ois45GkNjaoTqc5CxgMSX80A== +istanbul-reports@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.2.tgz#d593210e5000683750cb09fc0644e4b6e27fd53b" + integrity sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" @@ -2785,59 +2866,59 @@ jasmine@^3.5.0: glob "^7.1.4" jasmine-core "~3.5.0" -jest-changed-files@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-25.2.6.tgz#7d569cd6b265b1a84db3914db345d9c452f26b71" - integrity sha512-F7l2m5n55jFnJj4ItB9XbAlgO+6umgvz/mdK76BfTd2NGkvGf9x96hUXP/15a1K0k14QtVOoutwpRKl360msvg== +jest-changed-files@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-25.3.0.tgz#85d8de6f4bd13dafda9d7f1e3f2565fc0e183c78" + integrity sha512-eqd5hyLbUjIVvLlJ3vQ/MoPxsxfESVXG9gvU19XXjKzxr+dXmZIqCXiY0OiYaibwlHZBJl2Vebkc0ADEMzCXew== dependencies: - "@jest/types" "^25.2.6" + "@jest/types" "^25.3.0" execa "^3.2.0" throat "^5.0.0" -jest-cli@^25.2.7: - version "25.2.7" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-25.2.7.tgz#515b61fee402c397ffa8d570532f7b039c3159f4" - integrity sha512-OOAZwY4Jkd3r5WhVM5L3JeLNFaylvHUczMLxQDVLrrVyb1Cy+DNJ6MVsb5TLh6iBklB42m5TOP+IbOgKGGOtMw== +jest-cli@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-25.3.0.tgz#d9e11f5700cc5946583cf0d01a9bdebceed448d2" + integrity sha512-XpNQPlW1tzpP7RGG8dxpkRegYDuLjzSiENu92+CYM87nEbmEPb3b4+yo8xcsHOnj0AG7DUt9b3uG8LuHI3MDzw== dependencies: - "@jest/core" "^25.2.7" - "@jest/test-result" "^25.2.6" - "@jest/types" "^25.2.6" + "@jest/core" "^25.3.0" + "@jest/test-result" "^25.3.0" + "@jest/types" "^25.3.0" chalk "^3.0.0" exit "^0.1.2" import-local "^3.0.2" is-ci "^2.0.0" - jest-config "^25.2.7" - jest-util "^25.2.6" - jest-validate "^25.2.6" + jest-config "^25.3.0" + jest-util "^25.3.0" + jest-validate "^25.3.0" prompts "^2.0.1" realpath-native "^2.0.0" yargs "^15.3.1" -jest-config@^25.2.7: - version "25.2.7" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-25.2.7.tgz#a14e5b96575987ce913dd9fc20ac8cd4b35a8c29" - integrity sha512-rIdPPXR6XUxi+7xO4CbmXXkE6YWprvlKc4kg1SrkCL2YV5m/8MkHstq9gBZJ19Qoa3iz/GP+0sTG/PcIwkFojg== +jest-config@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-25.3.0.tgz#112b5e2f2e57dec4501dd2fe979044c06fb1317e" + integrity sha512-CmF1JnNWFmoCSPC4tnU52wnVBpuxHjilA40qH/03IHxIevkjUInSMwaDeE6ACfxMPTLidBGBCO3EbxvzPbo8wA== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^25.2.7" - "@jest/types" "^25.2.6" - babel-jest "^25.2.6" + "@jest/test-sequencer" "^25.3.0" + "@jest/types" "^25.3.0" + babel-jest "^25.3.0" chalk "^3.0.0" deepmerge "^4.2.2" glob "^7.1.1" - jest-environment-jsdom "^25.2.6" - jest-environment-node "^25.2.6" + jest-environment-jsdom "^25.3.0" + jest-environment-node "^25.3.0" jest-get-type "^25.2.6" - jest-jasmine2 "^25.2.7" + jest-jasmine2 "^25.3.0" jest-regex-util "^25.2.6" - jest-resolve "^25.2.6" - jest-util "^25.2.6" - jest-validate "^25.2.6" + jest-resolve "^25.3.0" + jest-util "^25.3.0" + jest-validate "^25.3.0" micromatch "^4.0.2" - pretty-format "^25.2.6" + pretty-format "^25.3.0" realpath-native "^2.0.0" -jest-diff@^25.2.1, jest-diff@^25.2.6: +jest-diff@^25.2.1: version "25.2.6" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.2.6.tgz#a6d70a9ab74507715ea1092ac513d1ab81c1b5e7" integrity sha512-KuadXImtRghTFga+/adnNrv9s61HudRMR7gVSbP35UKZdn4IK2/0N0PpGZIqtmllK9aUyye54I3nu28OYSnqOg== @@ -2847,46 +2928,56 @@ jest-diff@^25.2.1, jest-diff@^25.2.6: jest-get-type "^25.2.6" pretty-format "^25.2.6" -jest-docblock@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-25.2.6.tgz#4b09f1e7b7d6b3f39242ef3647ac7106770f722b" - integrity sha512-VAYrljEq0upq0oERfIaaNf28gC6p9gORndhHstCYF8NWGNQJnzoaU//S475IxfWMk4UjjVmS9rJKLe5Jjjbixw== +jest-diff@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.3.0.tgz#0d7d6f5d6171e5dacde9e05be47b3615e147c26f" + integrity sha512-vyvs6RPoVdiwARwY4kqFWd4PirPLm2dmmkNzKqo38uZOzJvLee87yzDjIZLmY1SjM3XR5DwsUH+cdQ12vgqi1w== + dependencies: + chalk "^3.0.0" + diff-sequences "^25.2.6" + jest-get-type "^25.2.6" + pretty-format "^25.3.0" + +jest-docblock@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-25.3.0.tgz#8b777a27e3477cd77a168c05290c471a575623ef" + integrity sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg== dependencies: detect-newline "^3.0.0" -jest-each@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-25.2.6.tgz#026f6dea2ccc443c35cea793265620aab1b278b6" - integrity sha512-OgQ01VINaRD6idWJOhCYwUc5EcgHBiFlJuw+ON2VgYr7HLtMFyCcuo+3mmBvuLUH4QudREZN7cDCZviknzsaJQ== +jest-each@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-25.3.0.tgz#a319eecf1f6076164ab86f99ca166a55b96c0bd4" + integrity sha512-aBfS4VOf/Qs95yUlX6d6WBv0szvOcTkTTyCIaLuQGj4bSHsT+Wd9dDngVHrCe5uytxpN8VM+NAloI6nbPjXfXw== dependencies: - "@jest/types" "^25.2.6" + "@jest/types" "^25.3.0" chalk "^3.0.0" jest-get-type "^25.2.6" - jest-util "^25.2.6" - pretty-format "^25.2.6" - -jest-environment-jsdom@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-25.2.6.tgz#b7ae41c6035905b8e58d63a8f63cf8eaa00af279" - integrity sha512-/o7MZIhGmLGIEG5j7r5B5Az0umWLCHU+F5crwfbm0BzC4ybHTJZOQTFQWhohBg+kbTCNOuftMcqHlVkVduJCQQ== - dependencies: - "@jest/environment" "^25.2.6" - "@jest/fake-timers" "^25.2.6" - "@jest/types" "^25.2.6" - jest-mock "^25.2.6" - jest-util "^25.2.6" + jest-util "^25.3.0" + pretty-format "^25.3.0" + +jest-environment-jsdom@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-25.3.0.tgz#c493ab8c41f28001520c70ef67dd88b88be6af05" + integrity sha512-jdE4bQN+k2QEZ9sWOxsqDJvMzbdFSCN/4tw8X0TQaCqyzKz58PyEf41oIr4WO7ERdp7WaJGBSUKF7imR3UW1lg== + dependencies: + "@jest/environment" "^25.3.0" + "@jest/fake-timers" "^25.3.0" + "@jest/types" "^25.3.0" + jest-mock "^25.3.0" + jest-util "^25.3.0" jsdom "^15.2.1" -jest-environment-node@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-25.2.6.tgz#ad4398432867113f474d94fe37b071ed04b30f3d" - integrity sha512-D1Ihj14fxZiMHGeTtU/LunhzSI+UeBvlr/rcXMTNyRMUMSz2PEhuqGbB78brBY6Dk3FhJDk7Ta+8reVaGjLWhA== +jest-environment-node@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-25.3.0.tgz#9845f0e63991e8498448cb0ae804935689533db9" + integrity sha512-XO09S29Nx1NU7TiMPHMoDIkxoGBuKSTbE+sHp0gXbeLDXhIdhysUI25kOqFFSD9AuDgvPvxWCXrvNqiFsOH33g== dependencies: - "@jest/environment" "^25.2.6" - "@jest/fake-timers" "^25.2.6" - "@jest/types" "^25.2.6" - jest-mock "^25.2.6" - jest-util "^25.2.6" + "@jest/environment" "^25.3.0" + "@jest/fake-timers" "^25.3.0" + "@jest/types" "^25.3.0" + jest-mock "^25.3.0" + jest-util "^25.3.0" semver "^6.3.0" jest-get-type@^25.2.6: @@ -2894,17 +2985,17 @@ jest-get-type@^25.2.6: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877" integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig== -jest-haste-map@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-25.2.6.tgz#4aa6bcfa15310afccdb9ca77af58a98add8cedb8" - integrity sha512-nom0+fnY8jwzelSDQnrqaKAcDZczYQvMEwcBjeL3PQ4MlcsqeB7dmrsAniUw/9eLkngT5DE6FhnenypilQFsgA== +jest-haste-map@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-25.3.0.tgz#b7683031c9c9ddc0521d311564108b244b11e4c6" + integrity sha512-LjXaRa+F8wwtSxo9G+hHD/Cp63PPQzvaBL9XCVoJD2rrcJO0Zr2+YYzAFWWYJ5GlPUkoaJFJtOuk0sL6MJY80A== dependencies: - "@jest/types" "^25.2.6" + "@jest/types" "^25.3.0" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.3" jest-serializer "^25.2.6" - jest-util "^25.2.6" + jest-util "^25.3.0" jest-worker "^25.2.6" micromatch "^4.0.2" sane "^4.0.3" @@ -2913,66 +3004,66 @@ jest-haste-map@^25.2.6: optionalDependencies: fsevents "^2.1.2" -jest-jasmine2@^25.2.7: - version "25.2.7" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-25.2.7.tgz#55ff87f8f462ef0e2f16fd19430b8be8bcebef0e" - integrity sha512-HeQxEbonp8fUvik9jF0lkU9ab1u5TQdIb7YSU9Fj7SxWtqHNDGyCpF6ZZ3r/5yuertxi+R95Ba9eA91GMQ38eA== +jest-jasmine2@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-25.3.0.tgz#16ae4f68adef65fb45001b26c864bcbcbf972830" + integrity sha512-NCYOGE6+HNzYFSui52SefgpsnIzvxjn6KAgqw66BdRp37xpMD/4kujDHLNW5bS5i53os5TcMn6jYrzQRO8VPrQ== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^25.2.6" + "@jest/environment" "^25.3.0" "@jest/source-map" "^25.2.6" - "@jest/test-result" "^25.2.6" - "@jest/types" "^25.2.6" + "@jest/test-result" "^25.3.0" + "@jest/types" "^25.3.0" chalk "^3.0.0" co "^4.6.0" - expect "^25.2.7" + expect "^25.3.0" is-generator-fn "^2.0.0" - jest-each "^25.2.6" - jest-matcher-utils "^25.2.7" - jest-message-util "^25.2.6" - jest-runtime "^25.2.7" - jest-snapshot "^25.2.7" - jest-util "^25.2.6" - pretty-format "^25.2.6" + jest-each "^25.3.0" + jest-matcher-utils "^25.3.0" + jest-message-util "^25.3.0" + jest-runtime "^25.3.0" + jest-snapshot "^25.3.0" + jest-util "^25.3.0" + pretty-format "^25.3.0" throat "^5.0.0" -jest-leak-detector@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-25.2.6.tgz#68fbaf651142292b03e30641f33e15af9b8c62b1" - integrity sha512-n+aJUM+j/x1kIaPVxzerMqhAUuqTU1PL5kup46rXh+l9SP8H6LqECT/qD1GrnylE1L463/0StSPkH4fUpkuEjA== +jest-leak-detector@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-25.3.0.tgz#5b6bf04903b35be56038915a55f47291771f769f" + integrity sha512-jk7k24dMIfk8LUSQQGN8PyOy9+J0NAfHZWiDmUDYVMctY8FLJQ1eQ8+PjMoN8PgwhLIggUqgYJnyRFvUz3jLRw== dependencies: jest-get-type "^25.2.6" - pretty-format "^25.2.6" + pretty-format "^25.3.0" -jest-matcher-utils@^25.2.7: - version "25.2.7" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.2.7.tgz#53fad3c11fc42e92e374306df543026712c957a3" - integrity sha512-jNYmKQPRyPO3ny0KY1I4f0XW4XnpJ3Nx5ovT4ik0TYDOYzuXJW40axqOyS61l/voWbVT9y9nZ1THL1DlpaBVpA== +jest-matcher-utils@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.3.0.tgz#76765788a26edaa8bc5f0100aea52ae383559648" + integrity sha512-ZBUJ2fchNIZt+fyzkuCFBb8SKaU//Rln45augfUtbHaGyVxCO++ANARdBK9oPGXU3hEDgyy7UHnOP/qNOJXFUg== dependencies: chalk "^3.0.0" - jest-diff "^25.2.6" + jest-diff "^25.3.0" jest-get-type "^25.2.6" - pretty-format "^25.2.6" + pretty-format "^25.3.0" -jest-message-util@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.2.6.tgz#9d5523bebec8cd9cdef75f0f3069d6ec9a2252df" - integrity sha512-Hgg5HbOssSqOuj+xU1mi7m3Ti2nwSQJQf/kxEkrz2r2rp2ZLO1pMeKkz2WiDUWgSR+APstqz0uMFcE5yc0qdcg== +jest-message-util@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.3.0.tgz#e3836826fe5ca538a337b87d9bd2648190867f85" + integrity sha512-5QNy9Id4WxJbRITEbA1T1kem9bk7y2fD0updZMSTNHtbEDnYOGLDPAuFBhFgVmOZpv0n6OMdVkK+WhyXEPCcOw== dependencies: "@babel/code-frame" "^7.0.0" - "@jest/types" "^25.2.6" + "@jest/types" "^25.3.0" "@types/stack-utils" "^1.0.1" chalk "^3.0.0" micromatch "^4.0.2" slash "^3.0.0" stack-utils "^1.0.1" -jest-mock@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-25.2.6.tgz#8df66eaa55a713d0f2a7dfb4f14507289d24dfa3" - integrity sha512-vc4nibavi2RGPdj/MyZy/azuDjZhpYZLvpfgq1fxkhbyTpKVdG7CgmRVKJ7zgLpY5kuMjTzDYA6QnRwhsCU+tA== +jest-mock@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-25.3.0.tgz#d72644509e40987a732a9a2534a1054f4649402c" + integrity sha512-yRn6GbuqB4j3aYu+Z1ezwRiZfp0o9om5uOcBovVtkcRLeBCNP5mT0ysdenUsxAHnQUgGwPOE1wwhtQYe6NKirQ== dependencies: - "@jest/types" "^25.2.6" + "@jest/types" "^25.3.0" jest-pnp-resolver@^1.2.1: version "1.2.1" @@ -2984,78 +3075,78 @@ jest-regex-util@^25.2.6: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.2.6.tgz#d847d38ba15d2118d3b06390056028d0f2fd3964" integrity sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw== -jest-resolve-dependencies@^25.2.7: - version "25.2.7" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-25.2.7.tgz#9ca4c62d67cce031a27fa5d5705b4b5b5c029d23" - integrity sha512-IrnMzCAh11Xd2gAOJL+ThEW6QO8DyqNdvNkQcaCticDrOAr9wtKT7yT6QBFFjqKFgjjvaVKDs59WdgUhgYnHnQ== +jest-resolve-dependencies@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-25.3.0.tgz#b0e4ae053dd44ddacc18c6ee12b5b7c28e445a90" + integrity sha512-bDUlLYmHW+f7J7KgcY2lkq8EMRqKonRl0XoD4Wp5SJkgAxKJnsaIOlrrVNTfXYf+YOu3VCjm/Ac2hPF2nfsCIA== dependencies: - "@jest/types" "^25.2.6" + "@jest/types" "^25.3.0" jest-regex-util "^25.2.6" - jest-snapshot "^25.2.7" + jest-snapshot "^25.3.0" -jest-resolve@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-25.2.6.tgz#84694ead5da13c2890ac04d4a78699ba937f3896" - integrity sha512-7O61GVdcAXkLz/vNGKdF+00A80/fKEAA47AEXVNcZwj75vEjPfZbXDaWFmAQCyXj4oo9y9dC9D+CLA11t8ieGw== +jest-resolve@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-25.3.0.tgz#cb90a5bbea54a02eccdbbf4126a819595dcf91d6" + integrity sha512-IHoQAAybulsJ+ZgWis+ekYKDAoFkVH5Nx/znpb41zRtpxj4fr2WNV9iDqavdSm8GIpMlsfZxbC/fV9DhW0q9VQ== dependencies: - "@jest/types" "^25.2.6" + "@jest/types" "^25.3.0" browser-resolve "^1.11.3" chalk "^3.0.0" jest-pnp-resolver "^1.2.1" realpath-native "^2.0.0" resolve "^1.15.1" -jest-runner@^25.2.7: - version "25.2.7" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-25.2.7.tgz#3676c01dc0104caa8a0ebb8507df382c88f2a1e2" - integrity sha512-RFEr71nMrtNwcpoHzie5+fe1w3JQCGMyT2xzNwKe3f88+bK+frM2o1v24gEcPxQ2QqB3COMCe2+1EkElP+qqqQ== +jest-runner@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-25.3.0.tgz#673ef2ac79d2810eb6b2c1a3f82398375a3d1174" + integrity sha512-csDqSC9qGHYWDrzrElzEgFbteztFeZJmKhSgY5jlCIcN0+PhActzRNku0DA1Xa1HxGOb0/AfbP1EGJlP4fGPtA== dependencies: - "@jest/console" "^25.2.6" - "@jest/environment" "^25.2.6" - "@jest/test-result" "^25.2.6" - "@jest/types" "^25.2.6" + "@jest/console" "^25.3.0" + "@jest/environment" "^25.3.0" + "@jest/test-result" "^25.3.0" + "@jest/types" "^25.3.0" chalk "^3.0.0" exit "^0.1.2" graceful-fs "^4.2.3" - jest-config "^25.2.7" - jest-docblock "^25.2.6" - jest-haste-map "^25.2.6" - jest-jasmine2 "^25.2.7" - jest-leak-detector "^25.2.6" - jest-message-util "^25.2.6" - jest-resolve "^25.2.6" - jest-runtime "^25.2.7" - jest-util "^25.2.6" + jest-config "^25.3.0" + jest-docblock "^25.3.0" + jest-haste-map "^25.3.0" + jest-jasmine2 "^25.3.0" + jest-leak-detector "^25.3.0" + jest-message-util "^25.3.0" + jest-resolve "^25.3.0" + jest-runtime "^25.3.0" + jest-util "^25.3.0" jest-worker "^25.2.6" source-map-support "^0.5.6" throat "^5.0.0" -jest-runtime@^25.2.7: - version "25.2.7" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-25.2.7.tgz#cb10e695d036671a83aec3a3803163c354043ac9" - integrity sha512-Gw3X8KxTTFylu2T/iDSNKRUQXQiPIYUY0b66GwVYa7W8wySkUljKhibQHSq0VhmCAN7vRBEQjlVQ+NFGNmQeBw== +jest-runtime@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-25.3.0.tgz#af4d40dbcc590fa5de9910cb6a120a13d131050b" + integrity sha512-gn5KYB1wxXRM3nfw8fVpthFu60vxQUCr+ShGq41+ZBFF3DRHZRKj3HDWVAVB4iTNBj2y04QeAo5cZ/boYaPg0w== dependencies: - "@jest/console" "^25.2.6" - "@jest/environment" "^25.2.6" + "@jest/console" "^25.3.0" + "@jest/environment" "^25.3.0" "@jest/source-map" "^25.2.6" - "@jest/test-result" "^25.2.6" - "@jest/transform" "^25.2.6" - "@jest/types" "^25.2.6" + "@jest/test-result" "^25.3.0" + "@jest/transform" "^25.3.0" + "@jest/types" "^25.3.0" "@types/yargs" "^15.0.0" chalk "^3.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.2.3" - jest-config "^25.2.7" - jest-haste-map "^25.2.6" - jest-message-util "^25.2.6" - jest-mock "^25.2.6" + jest-config "^25.3.0" + jest-haste-map "^25.3.0" + jest-message-util "^25.3.0" + jest-mock "^25.3.0" jest-regex-util "^25.2.6" - jest-resolve "^25.2.6" - jest-snapshot "^25.2.7" - jest-util "^25.2.6" - jest-validate "^25.2.6" + jest-resolve "^25.3.0" + jest-snapshot "^25.3.0" + jest-util "^25.3.0" + jest-validate "^25.3.0" realpath-native "^2.0.0" slash "^3.0.0" strip-bom "^4.0.0" @@ -3066,58 +3157,58 @@ jest-serializer@^25.2.6: resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-25.2.6.tgz#3bb4cc14fe0d8358489dbbefbb8a4e708ce039b7" integrity sha512-RMVCfZsezQS2Ww4kB5HJTMaMJ0asmC0BHlnobQC6yEtxiFKIxohFA4QSXSabKwSggaNkqxn6Z2VwdFCjhUWuiQ== -jest-snapshot@^25.2.7: - version "25.2.7" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-25.2.7.tgz#7eeafeef4dcbda1c47c8503d2bf5212b6430aac6" - integrity sha512-Rm8k7xpGM4tzmYhB6IeRjsOMkXaU8/FOz5XlU6oYwhy53mq6txVNqIKqN1VSiexzpC80oWVxVDfUDt71M6XPOA== +jest-snapshot@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-25.3.0.tgz#d4feb457494f4aaedcc83fbbf1ca21808fc3df71" + integrity sha512-GGpR6Oro2htJPKh5RX4PR1xwo5jCEjtvSPLW1IS7N85y+2bWKbiknHpJJRKSdGXghElb5hWaeQASJI4IiRayGg== dependencies: "@babel/types" "^7.0.0" - "@jest/types" "^25.2.6" + "@jest/types" "^25.3.0" "@types/prettier" "^1.19.0" chalk "^3.0.0" - expect "^25.2.7" - jest-diff "^25.2.6" + expect "^25.3.0" + jest-diff "^25.3.0" jest-get-type "^25.2.6" - jest-matcher-utils "^25.2.7" - jest-message-util "^25.2.6" - jest-resolve "^25.2.6" + jest-matcher-utils "^25.3.0" + jest-message-util "^25.3.0" + jest-resolve "^25.3.0" make-dir "^3.0.0" natural-compare "^1.4.0" - pretty-format "^25.2.6" + pretty-format "^25.3.0" semver "^6.3.0" -jest-util@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.2.6.tgz#3c1c95cdfd653126728b0ed861a86610e30d569c" - integrity sha512-gpXy0H5ymuQ0x2qgl1zzHg7LYHZYUmDEq6F7lhHA8M0eIwDB2WteOcCnQsohl9c/vBKZ3JF2r4EseipCZz3s4Q== +jest-util@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.3.0.tgz#e3b0064165818f10d78514696fd25efba82cf049" + integrity sha512-dc625P/KS/CpWTJJJxKc4bA3A6c+PJGBAqS8JTJqx4HqPoKNqXg/Ec8biL2Z1TabwK7E7Ilf0/ukSEXM1VwzNA== dependencies: - "@jest/types" "^25.2.6" + "@jest/types" "^25.3.0" chalk "^3.0.0" is-ci "^2.0.0" make-dir "^3.0.0" -jest-validate@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-25.2.6.tgz#ab3631fb97e242c42b09ca53127abe0b12e9125e" - integrity sha512-a4GN7hYbqQ3Rt9iHsNLFqQz7HDV7KiRPCwPgo5nqtTIWNZw7gnT8KchG+Riwh+UTSn8REjFCodGp50KX/fRNgQ== +jest-validate@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-25.3.0.tgz#eb95fdee0039647bcd5d4be641b21e4a142a880c" + integrity sha512-3WuXgIZ4HXUvW6gk9twFFkT9j6zUorKnF2oEY8VEsHb7x5LGvVlN3WUsbqazVKuyXwvikO2zFJ/YTySMsMje2w== dependencies: - "@jest/types" "^25.2.6" + "@jest/types" "^25.3.0" camelcase "^5.3.1" chalk "^3.0.0" jest-get-type "^25.2.6" leven "^3.1.0" - pretty-format "^25.2.6" + pretty-format "^25.3.0" -jest-watcher@^25.2.7: - version "25.2.7" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-25.2.7.tgz#01db4332d34d14c03c9ef22255125a3b07f997bc" - integrity sha512-RdHuW+f49tahWtluTnUdZ2iPliebleROI2L/J5phYrUS6DPC9RB3SuUtqYyYhGZJsbvRSuLMIlY/cICJ+PIecw== +jest-watcher@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-25.3.0.tgz#fd03fd5ca52f02bd3161ab177466bf1bfdd34e5c" + integrity sha512-dtFkfidFCS9Ucv8azOg2hkiY3sgJEHeTLtGFHS+jfBEE7eRtrO6+2r1BokyDkaG2FOD7485r/SgpC1MFAENfeA== dependencies: - "@jest/test-result" "^25.2.6" - "@jest/types" "^25.2.6" + "@jest/test-result" "^25.3.0" + "@jest/types" "^25.3.0" ansi-escapes "^4.2.1" chalk "^3.0.0" - jest-util "^25.2.6" + jest-util "^25.3.0" string-length "^3.1.0" jest-worker@^25.2.6: @@ -3128,14 +3219,14 @@ jest-worker@^25.2.6: merge-stream "^2.0.0" supports-color "^7.0.0" -jest@^25.2.7: - version "25.2.7" - resolved "https://registry.yarnpkg.com/jest/-/jest-25.2.7.tgz#3929a5f35cdd496f7756876a206b99a94e1e09ae" - integrity sha512-XV1n/CE2McCikl4tfpCY950RytHYvxdo/wvtgmn/qwA8z1s16fuvgFL/KoPrrmkqJTaPMUlLVE58pwiaTX5TdA== +jest@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-25.3.0.tgz#7a5e59741d94b8662664c77a9f346246d6bf228b" + integrity sha512-iKd5ShQSHzFT5IL/6h5RZJhApgqXSoPxhp5HEi94v6OAw9QkF8T7X+liEU2eEHJ1eMFYTHmeWLrpBWulsDpaUg== dependencies: - "@jest/core" "^25.2.7" + "@jest/core" "^25.3.0" import-local "^3.0.2" - jest-cli "^25.2.7" + jest-cli "^25.3.0" js-sha256@^0.9.0: version "0.9.0" @@ -4046,6 +4137,16 @@ pretty-format@^25.2.1, pretty-format@^25.2.6: ansi-styles "^4.0.0" react-is "^16.12.0" +pretty-format@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.3.0.tgz#d0a4f988ff4a6cd350342fdabbb809aeb4d49ad5" + integrity sha512-wToHwF8bkQknIcFkBqNfKu4+UZqnrLn/Vr+wwKQwwvPzkBfDDKp/qIabFqdgtoi5PEnM8LFByVsOrHoa3SpTVA== + dependencies: + "@jest/types" "^25.3.0" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^16.12.0" + process-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/process-exists/-/process-exists-4.0.0.tgz#dc12d87798c17b3f129f716631e2ccdaf240b4ab" From dc2462a516a01905780552cb935b20496d6ec5ae Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Mon, 6 Apr 2020 14:33:58 +1000 Subject: [PATCH 67/88] Improve communication protocols This is the changes that came out of the LN squad. Improvements include: - Add address book to the oneshot behaviour - Minor improvements to the swap digest code (implement Display, Serialize, Deserialize). - Rename `BehaviourEvent` to `BehaviourOutEvent` - Rename `AwaitingConfirmation` to `ReceivedAnnouncement` - Make `Message` fields public --- Cargo.lock | 1 + cnd/Cargo.toml | 1 + cnd/src/network.rs | 3 +- cnd/src/network/oneshot_behaviour.rs | 25 +++++++++-- cnd/src/network/oneshot_protocol.rs | 6 +++ cnd/src/network/protocols.rs | 1 - cnd/src/network/protocols/announce.rs | 35 +++++++++++---- .../network/protocols/announce/behaviour.rs | 18 ++++---- .../network/protocols/announce/protocol.rs | 2 +- cnd/src/network/protocols/bitcoin_identity.rs | 4 +- .../network/protocols/ethereum_identity.rs | 4 +- cnd/src/network/protocols/finalize.rs | 2 +- .../network/protocols/lightning_identity.rs | 43 ------------------- cnd/src/network/protocols/secret_hash.rs | 4 +- 14 files changed, 75 insertions(+), 74 deletions(-) delete mode 100644 cnd/src/network/protocols/lightning_identity.rs diff --git a/Cargo.lock b/Cargo.lock index 488b364b0c..a903703b85 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -506,6 +506,7 @@ dependencies = [ "libsqlite3-sys", "log 0.4.8", "lru", + "multihash", "num 0.2.1", "paste", "pem", diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index 995b4754be..971973b908 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -36,6 +36,7 @@ libsqlite3-sys = { version = ">=0.8.0, <0.13.0", features = ["bundled"] } log = { version = "0.4", features = ["serde"] } lru = "0.4.3" num = "0.2" +multihash = "0.10" paste = "0.1" pem = "0.7" primitive-types = { version = "0.7.0", features = ["serde"] } diff --git a/cnd/src/network.rs b/cnd/src/network.rs index c4b69da795..eceb5cb509 100644 --- a/cnd/src/network.rs +++ b/cnd/src/network.rs @@ -1,5 +1,4 @@ -mod oneshot_behaviour; - +pub mod oneshot_behaviour; pub mod oneshot_protocol; pub mod protocols; pub mod transport; diff --git a/cnd/src/network/oneshot_behaviour.rs b/cnd/src/network/oneshot_behaviour.rs index 150aaf8a3a..87cf819260 100644 --- a/cnd/src/network/oneshot_behaviour.rs +++ b/cnd/src/network/oneshot_behaviour.rs @@ -7,7 +7,7 @@ use libp2p::{ }; use serde::{de::DeserializeOwned, Serialize}; use std::{ - collections::VecDeque, + collections::{HashMap, VecDeque}, fmt::Debug, task::{Context, Poll}, }; @@ -18,12 +18,31 @@ use tracing::trace; pub struct Behaviour { /// Events that need to be yielded to the outside when polling. events: VecDeque, OutEvent>>, + address_book: HashMap>, +} + +impl Behaviour { + pub fn send(&mut self, peer_id: PeerId, message: M) { + self.events.push_back(NetworkBehaviourAction::SendEvent { + peer_id, + event: oneshot_protocol::OutboundConfig::new(message), + }) + } + + // If we decide to keep these different network behaviour (and not use a + // multi-protocols handler or something) then we should do our own + // connection handling in these as-well by extracting the one from the + // announce protocol in a reusable-manner. + pub fn register_addresses(&mut self, peer_id: PeerId, addresses: Vec) { + self.address_book.insert(peer_id, addresses); + } } impl Default for Behaviour { fn default() -> Self { Behaviour { events: VecDeque::new(), + address_book: HashMap::default(), } } } @@ -52,8 +71,8 @@ where Default::default() } - fn addresses_of_peer(&mut self, _: &PeerId) -> Vec { - Vec::new() // Announce protocol takes care of this. + fn addresses_of_peer(&mut self, peer: &PeerId) -> Vec { + self.address_book.get(peer).cloned().unwrap_or_default() } fn inject_connected(&mut self, _: &PeerId) { diff --git a/cnd/src/network/oneshot_protocol.rs b/cnd/src/network/oneshot_protocol.rs index d5ed475dc7..60ad6259e0 100644 --- a/cnd/src/network/oneshot_protocol.rs +++ b/cnd/src/network/oneshot_protocol.rs @@ -25,6 +25,12 @@ pub struct OutboundConfig { msg: M, } +impl OutboundConfig { + pub fn new(msg: M) -> Self { + Self { msg } + } +} + /// Events that are produced as part of the connection upgrade. /// /// The oneshot protocol is push-based, meaning the outbound upgrade will diff --git a/cnd/src/network/protocols.rs b/cnd/src/network/protocols.rs index aad90493ad..8c6b1c819f 100644 --- a/cnd/src/network/protocols.rs +++ b/cnd/src/network/protocols.rs @@ -2,5 +2,4 @@ pub mod announce; pub mod bitcoin_identity; pub mod ethereum_identity; pub mod finalize; -pub mod lightning_identity; pub mod secret_hash; diff --git a/cnd/src/network/protocols/announce.rs b/cnd/src/network/protocols/announce.rs index ffa7558291..5b525c6452 100644 --- a/cnd/src/network/protocols/announce.rs +++ b/cnd/src/network/protocols/announce.rs @@ -2,28 +2,45 @@ pub mod behaviour; pub mod handler; pub mod protocol; -use libp2p::multihash::Multihash; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use multihash::{self, Multihash}; +use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; +use std::fmt; -#[derive(Clone, Debug, PartialEq)] -pub struct SwapDigest { - inner: Multihash, +#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash)] +pub struct SwapDigest(Multihash); + +impl SwapDigest { + pub fn new(multihash: Multihash) -> Self { + Self(multihash) + } +} + +impl fmt::Display for SwapDigest { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", hex::encode(self.0.as_bytes())) + } } impl Serialize for SwapDigest { - fn serialize(&self, _serializer: S) -> Result + fn serialize(&self, serializer: S) -> Result where S: Serializer, { - unimplemented!() + let hex = hex::encode(self.0.as_bytes()); + + serializer.serialize_str(&hex) } } impl<'de> Deserialize<'de> for SwapDigest { - fn deserialize(_deserializer: D) -> Result>::Error> + fn deserialize(deserializer: D) -> Result>::Error> where D: Deserializer<'de>, { - unimplemented!() + let hex = String::deserialize(deserializer)?; + let bytes = hex::decode(hex).map_err(D::Error::custom)?; + let multihash = multihash::Multihash::from_bytes(bytes).map_err(D::Error::custom)?; + + Ok(SwapDigest::new(multihash)) } } diff --git a/cnd/src/network/protocols/announce/behaviour.rs b/cnd/src/network/protocols/announce/behaviour.rs index 295bc6a747..65193b3b3b 100644 --- a/cnd/src/network/protocols/announce/behaviour.rs +++ b/cnd/src/network/protocols/announce/behaviour.rs @@ -26,7 +26,7 @@ use std::{ #[derive(Debug)] pub struct Announce { /// Pending events to be emitted when polled. - events: VecDeque>, + events: VecDeque>, /// Stores connection state for nodes we connect to. connections: HashMap, } @@ -52,6 +52,8 @@ impl Announce { /// * `swap_digest` - The swap to announce. /// * `dial_info` - The `PeerId` and address hint to dial to Bob's node. pub fn start_announce_protocol(&mut self, swap_digest: SwapDigest, dial_info: DialInformation) { + tracing::info!("Announcing swap {} to {}", swap_digest, dial_info.peer_id); + match self.connections.entry(dial_info.peer_id.clone()) { Entry::Vacant(entry) => { self.events.push_back(NetworkBehaviourAction::DialPeer { @@ -104,7 +106,7 @@ impl Announce { impl NetworkBehaviour for Announce { type ProtocolsHandler = Handler; - type OutEvent = BehaviourEvent; + type OutEvent = BehaviourOutEvent; fn new_handler(&mut self) -> Self::ProtocolsHandler { Handler::default() @@ -215,7 +217,7 @@ impl NetworkBehaviour for Announce { match event { HandlerEvent::ReceivedConfirmation(confirmed) => { self.events.push_back(NetworkBehaviourAction::GenerateEvent( - BehaviourEvent::ReceivedConfirmation { + BehaviourOutEvent::ReceivedConfirmation { peer: peer_id, swap_id: confirmed.swap_id, swap_digest: confirmed.swap_digest, @@ -224,7 +226,7 @@ impl NetworkBehaviour for Announce { } HandlerEvent::AwaitingConfirmation(sender) => { self.events.push_back(NetworkBehaviourAction::GenerateEvent( - BehaviourEvent::AwaitingConfirmation { + BehaviourOutEvent::ReceivedAnnouncement { peer: peer_id, io: sender, }, @@ -232,7 +234,7 @@ impl NetworkBehaviour for Announce { } HandlerEvent::Error(error) => { self.events.push_back(NetworkBehaviourAction::GenerateEvent( - BehaviourEvent::Error { + BehaviourOutEvent::Error { peer: peer_id, error, }, @@ -275,9 +277,9 @@ enum ConnectionState { /// Event emitted by the `Announce` behaviour. #[derive(Debug)] -pub enum BehaviourEvent { +pub enum BehaviourOutEvent { /// This event created when a confirmation message containing a `swap_id` is - /// received in response to an announce message containing a + /// received in response to an announce messagunlo e containing a /// `swap_digest`. The Event contains both the swap id and /// the swap digest. The announce message is sent by Alice to Bob. ReceivedConfirmation { @@ -293,7 +295,7 @@ pub enum BehaviourEvent { /// contains a reply substream for the receiver to send back the /// `swap_id` that corresponds to the swap digest. Bob sends the /// confirmations message to Alice using the the reply substream. - AwaitingConfirmation { + ReceivedAnnouncement { /// The peer (Alice) that the reply substream is connected to. peer: PeerId, /// The substream (inc. `swap_digest`) to reply on (i.e., send diff --git a/cnd/src/network/protocols/announce/protocol.rs b/cnd/src/network/protocols/announce/protocol.rs index b2334f98db..acbf5f935a 100644 --- a/cnd/src/network/protocols/announce/protocol.rs +++ b/cnd/src/network/protocols/announce/protocol.rs @@ -10,7 +10,7 @@ const INFO: &str = "/comit/swap/announce/1.0.0"; /// side. #[derive(Debug, Clone)] pub struct OutboundConfig { - swap_digest: SwapDigest, + pub swap_digest: SwapDigest, } impl OutboundConfig { diff --git a/cnd/src/network/protocols/bitcoin_identity.rs b/cnd/src/network/protocols/bitcoin_identity.rs index 70f2d52a93..dc8ebc9dda 100644 --- a/cnd/src/network/protocols/bitcoin_identity.rs +++ b/cnd/src/network/protocols/bitcoin_identity.rs @@ -6,11 +6,11 @@ use serdebug::SerDebug; /// The message for the Bitcoin identity sharing protocol. #[derive(Clone, Copy, Deserialize, Serialize, SerDebug)] pub struct Message { - swap_id: SwapId, + pub swap_id: SwapId, /// A compressed Bitcoin public key, serialized as hex without a `0x` prefix /// as per convention in the Bitcoin ecosystem. #[serde(with = "SerHex::")] - pubkey: [u8; 33], + pub pubkey: [u8; 33], } impl Message { diff --git a/cnd/src/network/protocols/ethereum_identity.rs b/cnd/src/network/protocols/ethereum_identity.rs index fc1c629c25..733c420627 100644 --- a/cnd/src/network/protocols/ethereum_identity.rs +++ b/cnd/src/network/protocols/ethereum_identity.rs @@ -5,11 +5,11 @@ use serde_hex::{SerHex, StrictPfx}; /// The message for the Ethereum identity sharing protocol. #[derive(Clone, Copy, Deserialize, Debug, Serialize)] pub struct Message { - swap_id: SwapId, + pub swap_id: SwapId, /// An Ethereum address, serialized with a `0x` prefix as per convention in /// the Ethereum ecosystem. #[serde(with = "SerHex::")] - address: [u8; 20], + pub address: [u8; 20], } impl Message { diff --git a/cnd/src/network/protocols/finalize.rs b/cnd/src/network/protocols/finalize.rs index 1cc9c63c15..e7c2788bf0 100644 --- a/cnd/src/network/protocols/finalize.rs +++ b/cnd/src/network/protocols/finalize.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; /// The message for the finalize protocol. #[derive(Clone, Copy, Deserialize, Debug, Serialize)] pub struct Message { - swap_id: SwapId, + pub swap_id: SwapId, } impl Message { diff --git a/cnd/src/network/protocols/lightning_identity.rs b/cnd/src/network/protocols/lightning_identity.rs deleted file mode 100644 index 7a0dbab152..0000000000 --- a/cnd/src/network/protocols/lightning_identity.rs +++ /dev/null @@ -1,43 +0,0 @@ -use crate::{network::oneshot_protocol, swap_protocols::SwapId}; -use serde::{Deserialize, Serialize}; -use serde_hex::{SerHex, Strict}; -use serdebug::SerDebug; - -/// The message for the Lightning identity sharing protocol. -#[derive(Clone, Copy, Deserialize, Serialize, SerDebug)] -pub struct Message { - swap_id: SwapId, - /// A Lightning node identifier is a compressed secp256k1 public key, - /// serialized without a `0x` prefix. - #[serde(with = "SerHex::")] - pubkey: [u8; 33], -} - -impl Message { - pub fn new(swap_id: SwapId, pubkey: [u8; 33]) -> Self { - Self { swap_id, pubkey } - } -} - -impl oneshot_protocol::Message for Message { - const INFO: &'static str = "/comit/swap/identity/lightning/1.0.0"; -} - -#[cfg(test)] -mod tests { - use super::*; - use spectral::prelude::*; - use uuid::Uuid; - - #[test] - fn serialization_format_stability_test() { - let given = Message { - swap_id: SwapId(Uuid::nil()), - pubkey: [0u8; 33], - }; - - let actual = serde_json::to_string(&given); - - assert_that(&actual).is_ok_containing(r#"{"swap_id":"00000000-0000-0000-0000-000000000000","pubkey":"000000000000000000000000000000000000000000000000000000000000000000"}"#.to_owned()) - } -} diff --git a/cnd/src/network/protocols/secret_hash.rs b/cnd/src/network/protocols/secret_hash.rs index c59200a247..ca2f6521d2 100644 --- a/cnd/src/network/protocols/secret_hash.rs +++ b/cnd/src/network/protocols/secret_hash.rs @@ -8,10 +8,10 @@ use serde_hex::{SerHex, Strict}; /// The message for the secret hash sharing protocol. #[derive(Clone, Copy, Deserialize, Debug, Serialize)] pub struct Message { - swap_id: SwapId, + pub swap_id: SwapId, /// A SHA-256 hash, serialized as hex without a `0x` prefix. #[serde(with = "SerHex::")] - secret_hash: [u8; 32], + pub secret_hash: [u8; 32], } impl Message { From c3895c8561f77cc931a1c7076cf492bc0b85b655 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 7 Apr 2020 08:30:17 +1000 Subject: [PATCH 68/88] Add lightning module and communication protocol Add the lightning module (for `identity::lightning` as is done for the others). Add the lightning identity sharing communication protocol. --- cnd/src/lib.rs | 6 +- cnd/src/lightning.rs | 132 ++++++++++++++++++ cnd/src/network/protocols.rs | 1 + .../network/protocols/lightning_identity.rs | 46 ++++++ 4 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 cnd/src/lightning.rs create mode 100644 cnd/src/network/protocols/lightning_identity.rs diff --git a/cnd/src/lib.rs b/cnd/src/lib.rs index 8f2a3465c0..41f51a2df2 100644 --- a/cnd/src/lib.rs +++ b/cnd/src/lib.rs @@ -37,6 +37,7 @@ pub mod config; pub mod ethereum; pub mod http_api; pub mod init_swap; +pub mod lightning; pub mod load_swaps; #[macro_use] pub mod network; @@ -60,7 +61,10 @@ use std::{ /// Define domain specific terms using identity module so that we can refer to /// things in an ergonomic fashion e.g., `identity::Bitcoin`. pub mod identity { - pub use crate::{bitcoin::PublicKey as Bitcoin, ethereum::Address as Ethereum}; + pub use crate::{ + bitcoin::PublicKey as Bitcoin, ethereum::Address as Ethereum, + lightning::PublicKey as Lightning, + }; } /// Define domain specific terms using transaction module so that we can refer diff --git a/cnd/src/lightning.rs b/cnd/src/lightning.rs new file mode 100644 index 0000000000..f2d4cc81fd --- /dev/null +++ b/cnd/src/lightning.rs @@ -0,0 +1,132 @@ +//! This module is the home of lightning-specific types and functionality that +//! is needed across several places in cnd. +//! +//! This involves: +//! - Creating wrapper types to allow for more ergonomic APIs of upstream +//! libraries +//! - Common functionality that is not (yet) available upstream + +use bitcoin::secp256k1; +use serde::{ + de::{self, Visitor}, + Deserialize, Deserializer, Serialize, Serializer, +}; +use std::{fmt, str::FromStr}; + +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct PublicKey(bitcoin::PublicKey); + +impl PublicKey { + pub fn from_secret_key( + secp: &secp256k1::Secp256k1, + secret_key: &secp256k1::SecretKey, + ) -> Self + where + C: secp256k1::Signing, + { + secp256k1::PublicKey::from_secret_key(secp, secret_key).into() + } + + pub fn to_bytes(self) -> Vec { + self.0.to_bytes() + } +} + +impl From for PublicKey { + fn from(key: secp256k1::PublicKey) -> Self { + Self(bitcoin::PublicKey { + compressed: true, // we always want the PublicKey to be serialized in a compressed way + key, + }) + } +} + +impl From for bitcoin::PublicKey { + fn from(pubkey: PublicKey) -> bitcoin::PublicKey { + pubkey.0 + } +} + +impl From for PublicKey { + fn from(key: bitcoin::util::key::PublicKey) -> Self { + Self(key) + } +} + +impl FromStr for PublicKey { + type Err = bitcoin::util::key::Error; + + fn from_str(s: &str) -> Result { + Ok(bitcoin::PublicKey::from_str(s)?.into()) + } +} + +impl Serialize for PublicKey { + fn serialize(&self, serializer: S) -> Result<::Ok, ::Error> + where + S: Serializer, + { + serializer.serialize_str(&self.0.to_string()) + } +} + +impl<'de> Deserialize<'de> for PublicKey { + fn deserialize(deserializer: D) -> Result>::Error> + where + D: Deserializer<'de>, + { + struct PublicKeyVisitor; + + impl<'de> Visitor<'de> for PublicKeyVisitor { + type Value = PublicKey; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(formatter, "a hex-encoded, compressed public key") + } + + fn visit_str(self, v: &str) -> Result + where + E: de::Error, + { + v.parse().map_err(E::custom) + } + } + + deserializer.deserialize_str(PublicKeyVisitor) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::str::FromStr; + + #[test] + fn serialize_bitcoin_identity() { + let secp_pubkey = secp256k1::PublicKey::from_str( + "02c2a8efce029526d364c2cf39d89e3cdda05e5df7b2cbfc098b4e3d02b70b5275", + ) + .unwrap(); + let pubkey = PublicKey::from(secp_pubkey); + + let str = serde_json::to_string(&pubkey).unwrap(); + assert_eq!( + str, + "\"02c2a8efce029526d364c2cf39d89e3cdda05e5df7b2cbfc098b4e3d02b70b5275\"" + ) + } + + #[test] + fn deserialize_bitcoin_identity() { + let pubkey_str = "\"02c2a8efce029526d364c2cf39d89e3cdda05e5df7b2cbfc098b4e3d02b70b5275\""; + let pubkey = serde_json::from_str::(pubkey_str).unwrap(); + + let expected_pubkey = secp256k1::PublicKey::from_str( + "02c2a8efce029526d364c2cf39d89e3cdda05e5df7b2cbfc098b4e3d02b70b5275", + ) + .unwrap(); + let expected_pubkey = PublicKey::from(expected_pubkey); + + assert_eq!(pubkey, expected_pubkey); + } +} diff --git a/cnd/src/network/protocols.rs b/cnd/src/network/protocols.rs index 8c6b1c819f..aad90493ad 100644 --- a/cnd/src/network/protocols.rs +++ b/cnd/src/network/protocols.rs @@ -2,4 +2,5 @@ pub mod announce; pub mod bitcoin_identity; pub mod ethereum_identity; pub mod finalize; +pub mod lightning_identity; pub mod secret_hash; diff --git a/cnd/src/network/protocols/lightning_identity.rs b/cnd/src/network/protocols/lightning_identity.rs new file mode 100644 index 0000000000..008bfca49c --- /dev/null +++ b/cnd/src/network/protocols/lightning_identity.rs @@ -0,0 +1,46 @@ +use crate::{identity, network::oneshot_protocol, swap_protocols::SwapId}; +use serde::{Deserialize, Serialize}; +use serde_hex::{SerHex, Strict}; +use serdebug::SerDebug; + +/// The message for the Lightning identity sharing protocol. +#[derive(Clone, Copy, Deserialize, Serialize, SerDebug)] +pub struct Message { + pub swap_id: SwapId, + /// A Lightning node identifier is a compressed secp256k1 public key, + /// serialized without a `0x` prefix. + #[serde(with = "SerHex::")] + pub pubkey: [u8; 33], +} + +impl Message { + pub fn new(swap_id: SwapId, pubkey: identity::Lightning) -> Self { + Self { + swap_id, + pubkey: bitcoin::PublicKey::from(pubkey).key.serialize(), + } + } +} + +impl oneshot_protocol::Message for Message { + const INFO: &'static str = "/comit/swap/identity/lightning/1.0.0"; +} + +#[cfg(test)] +mod tests { + use super::*; + use spectral::prelude::*; + use uuid::Uuid; + + #[test] + fn serialization_format_stability_test() { + let given = Message { + swap_id: SwapId(Uuid::nil()), + pubkey: [0u8; 33], + }; + + let actual = serde_json::to_string(&given); + + assert_that(&actual).is_ok_containing(r#"{"swap_id":"00000000-0000-0000-0000-000000000000","pubkey":"000000000000000000000000000000000000000000000000000000000000000000"}"#.to_owned()) + } +} From 187eaa49366c48ef2f06875f3063b8fa66f1453a Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 7 Apr 2020 14:24:08 +1000 Subject: [PATCH 69/88] Box reply future --- cnd/src/network/protocols/announce/behaviour.rs | 2 +- cnd/src/network/protocols/announce/handler.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cnd/src/network/protocols/announce/behaviour.rs b/cnd/src/network/protocols/announce/behaviour.rs index 65193b3b3b..8cdbc354d6 100644 --- a/cnd/src/network/protocols/announce/behaviour.rs +++ b/cnd/src/network/protocols/announce/behaviour.rs @@ -300,7 +300,7 @@ pub enum BehaviourOutEvent { peer: PeerId, /// The substream (inc. `swap_digest`) to reply on (i.e., send /// `swap_id`). - io: ReplySubstream, + io: Box>, }, /// Error while attempting to announce swap to the remote. diff --git a/cnd/src/network/protocols/announce/handler.rs b/cnd/src/network/protocols/announce/handler.rs index b7b997add0..558cd6ecc1 100644 --- a/cnd/src/network/protocols/announce/handler.rs +++ b/cnd/src/network/protocols/announce/handler.rs @@ -45,7 +45,7 @@ pub enum HandlerEvent { /// The event is created when a remote sends a `swap_digest`. The event /// contains a reply substream for the receiver to send back the /// `swap_id` that corresponds to the swap digest. - AwaitingConfirmation(ReplySubstream), + AwaitingConfirmation(Box>), /// Failed to announce swap to peer. Error(Error), @@ -68,7 +68,7 @@ impl ProtocolsHandler for Handler { sender: >::Output, ) { self.events - .push_back(HandlerEvent::AwaitingConfirmation(sender)) + .push_back(HandlerEvent::AwaitingConfirmation(Box::new(sender))) } fn inject_fully_negotiated_outbound( From 71f41fe845c36abbcb8bfca9c63081427534dc2e Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 9 Apr 2020 09:16:35 +1000 Subject: [PATCH 70/88] Use new `NetworkBehaviourAction::NotifyHandler libp2p just updated the way events are passed to the protocol handler from the behaviour. We need to use `NotifyHandler` now instead of the old `SendEvent`. --- cnd/src/network/oneshot_behaviour.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/cnd/src/network/oneshot_behaviour.rs b/cnd/src/network/oneshot_behaviour.rs index 87cf819260..da8eb7f9cf 100644 --- a/cnd/src/network/oneshot_behaviour.rs +++ b/cnd/src/network/oneshot_behaviour.rs @@ -2,7 +2,8 @@ use crate::network::oneshot_protocol; use libp2p::{ core::{connection::ConnectionId, Multiaddr, PeerId}, swarm::{ - NetworkBehaviour, NetworkBehaviourAction, OneShotHandler, PollParameters, ProtocolsHandler, + NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, OneShotHandler, PollParameters, + ProtocolsHandler, }, }; use serde::{de::DeserializeOwned, Serialize}; @@ -23,10 +24,12 @@ pub struct Behaviour { impl Behaviour { pub fn send(&mut self, peer_id: PeerId, message: M) { - self.events.push_back(NetworkBehaviourAction::SendEvent { - peer_id, - event: oneshot_protocol::OutboundConfig::new(message), - }) + self.events + .push_back(NetworkBehaviourAction::NotifyHandler { + peer_id, + handler: NotifyHandler::Any, + event: oneshot_protocol::OutboundConfig::new(message), + }) } // If we decide to keep these different network behaviour (and not use a From 204a115c179137f4a55ccdd94feaeb63a93df4d3 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 19 Mar 2020 13:25:07 +1100 Subject: [PATCH 71/88] Download blockchain nodes in TS instead of with shell scripts This has a number of advantages: - The nodes are kept inside the `node_modules` folder and are transparently downloaded if we need them on a new install. This should also speed up CI because we are caching the node_modules folder. - It will ultimately allow us to remove a top-level directory from the source tree, leaving behind a cleaner repository. - We appropriately download those nodes into versioned folders. - Typescript is easier to maintain compared to shell scripts. - An implementation detail (the use of binaries instead of Docker images) does not leak to the rest of the system. - We will ultimately be able to simplify the API of the BitcoindInstance and ParityInstance classes because we no longer need to pass the project-root in. --- Makefile | 8 +- api_tests/package.json | 5 + api_tests/src/ledgers/bitcoind_instance.ts | 78 +- api_tests/src/ledgers/parity_instance.ts | 70 +- api_tests/types/chmod/index.d.ts | 9 + api_tests/yarn.lock | 1310 ++++++++++++++------ blockchain_nodes/ensure_bitcoind.sh | 26 - blockchain_nodes/ensure_parity.sh | 25 - 8 files changed, 1113 insertions(+), 418 deletions(-) create mode 100644 api_tests/types/chmod/index.d.ts delete mode 100755 blockchain_nodes/ensure_bitcoind.sh delete mode 100755 blockchain_nodes/ensure_parity.sh diff --git a/Makefile b/Makefile index dc3cfea4b8..df77f0241c 100644 --- a/Makefile +++ b/Makefile @@ -54,10 +54,6 @@ endif ## User install -download_bc_nodes: - @./blockchain_nodes/ensure_bitcoind.sh - @./blockchain_nodes/ensure_parity.sh - install: $(CARGO) install --force --path cnd @@ -82,10 +78,10 @@ test: doc: $(CARGO) doc -e2e: download_bc_nodes build +e2e: build (cd ./api_tests; yarn install; yarn test) -ci_gha: download_bc_nodes +ci_gha: (cd ./api_tests; yarn install; yarn ci) check_format: check_rust_format check_toml_format check_ts_format diff --git a/api_tests/package.json b/api_tests/package.json index 33632a9e32..8e94c272a3 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -22,6 +22,8 @@ "@types/chai-as-promised": "^7.1.2", "@types/chai-json-schema": "^1.4.5", "@types/chai-subset": "^1.3.3", + "@types/download": "^6.2.4", + "@types/find-cache-dir": "^3.2.0", "@types/glob": "^7.1.1", "@types/jasmine": "^3.5.10", "@types/jest": "^25.2.1", @@ -43,8 +45,11 @@ "chai-json-schema": "^1.5.0", "chai-string": "^1.5.0", "chai-subset": "^1.6.0", + "chmod": "^0.2.1", "comit-sdk": "^0.15.2", + "download": "^7.1.0", "ethers": "^4.0.46", + "find-cache-dir": "^3.3.1", "get-port": "^5.1.1", "glob": "^7.1.6", "jasmine": "^3.5.0", diff --git a/api_tests/src/ledgers/bitcoind_instance.ts b/api_tests/src/ledgers/bitcoind_instance.ts index 2460fd981e..8cc1883ebe 100644 --- a/api_tests/src/ledgers/bitcoind_instance.ts +++ b/api_tests/src/ledgers/bitcoind_instance.ts @@ -1,11 +1,14 @@ import { ChildProcess, spawn } from "child_process"; import * as fs from "fs"; import * as path from "path"; -import { writeFileAsync } from "../utils"; +import { existsAsync, writeFileAsync } from "../utils"; import getPort from "get-port"; import { Logger } from "log4js"; import waitForLogMessage from "../wait_for_log_message"; import { BitcoinNodeConfig, LedgerInstance } from "./index"; +import findCacheDir from "find-cache-dir"; +import download from "download"; +import { platform } from "os"; export class BitcoindInstance implements LedgerInstance { private process: ChildProcess; @@ -42,16 +45,8 @@ export class BitcoindInstance implements LedgerInstance { ) {} public async start() { - const bin = process.env.BITCOIND_BIN - ? process.env.BITCOIND_BIN - : path.join( - this.projectRoot, - "blockchain_nodes", - "bitcoin", - "bitcoin-0.17.0", - "bin", - "bitcoind" - ); + const bin = await this.findBinary("0.17.0"); + this.logger.info("Using binary", bin); await this.createConfigFile(this.dataDir); @@ -101,6 +96,56 @@ export class BitcoindInstance implements LedgerInstance { }; } + private async findBinary(version: string): Promise { + const envOverride = process.env.BITCOIND_BIN; + + if (envOverride) { + this.logger.info( + "Overriding bitcoind bin with BITCOIND_BIN: ", + envOverride + ); + + return envOverride; + } + + const archiveName = `bitcoin-core-${version}`; + + const cacheDir = findCacheDir({ + name: archiveName, + create: true, + thunk: true, + }); + + // This path depends on the directory structure inside the archive + const binaryPath = cacheDir(`bitcoin-${version}`, "bin", "bitcoind"); + + if (await existsAsync(binaryPath)) { + return binaryPath; + } + + const url = downloadUrlFor(version); + + this.logger.info( + "Binary for version ", + version, + " not found at ", + binaryPath, + ", downloading from ", + url + ); + + const destination = cacheDir(""); + await download(url, destination, { + decompress: true, + extract: true, + filename: archiveName, + }); + + this.logger.info("Download completed"); + + return binaryPath; + } + private logPath() { return path.join(this.dataDir, "regtest", "debug.log"); } @@ -128,3 +173,14 @@ rpcbind=0.0.0.0:${this.rpcPort} await writeFileAsync(config, output); } } + +function downloadUrlFor(version: string) { + switch (platform()) { + case "darwin": + return `https://bitcoincore.org/bin/bitcoin-core-${version}/bitcoin-${version}-osx64.tar.gz`; + case "linux": + return `https://bitcoincore.org/bin/bitcoin-core-${version}/bitcoin-${version}-x86_64-linux-gnu.tar.gz`; + default: + throw new Error(`Unsupported platform ${platform()}`); + } +} diff --git a/api_tests/src/ledgers/parity_instance.ts b/api_tests/src/ledgers/parity_instance.ts index a7c581e86c..79df8674e4 100644 --- a/api_tests/src/ledgers/parity_instance.ts +++ b/api_tests/src/ledgers/parity_instance.ts @@ -4,9 +4,14 @@ import tmp from "tmp"; import waitForLogMessage from "../wait_for_log_message"; import { promisify } from "util"; import { writeFileAsync } from "../utils"; +import { existsAsync } from "../utils"; import getPort from "get-port"; import { Logger } from "log4js"; import { LedgerInstance } from "./index"; +import findCacheDir from "find-cache-dir"; +import download from "download"; +import { platform } from "os"; +import chmod from "chmod"; const openAsync = promisify(fs.open); @@ -40,9 +45,7 @@ export class ParityInstance implements LedgerInstance { ) {} public async start() { - const bin = process.env.PARITY_BIN - ? process.env.PARITY_BIN - : this.projectRoot + "/blockchain_nodes/parity/parity"; + const bin = await this.findBinary("2.7.2"); this.logger.info("Using binary", bin); @@ -91,7 +94,68 @@ export class ParityInstance implements LedgerInstance { }); } + private async findBinary(version: string): Promise { + const envOverride = process.env.PARITY_BIN; + + if (envOverride) { + this.logger.info( + "Overriding parity bin with PARITY_BIN: ", + envOverride + ); + + return envOverride; + } + + const cacheDirPath = `parity-${version}`; + const binaryName = "parity"; + + const cacheDir = findCacheDir({ + name: cacheDirPath, + create: true, + thunk: true, + }); + const binaryPath = cacheDir(binaryName); + + if (await existsAsync(binaryPath)) { + return binaryPath; + } + + const url = downloadUrl(version); + + this.logger.info( + "Binary for version ", + version, + " not found at ", + binaryPath, + ", downloading from ", + url + ); + + await download(url, cacheDir(""), { + filename: binaryName, + }); + + chmod(binaryPath, { + execute: true, + }); + + this.logger.info("Download completed"); + + return binaryPath; + } + public get rpcUrl() { return `http://localhost:${this.rpcPort}`; } } + +function downloadUrl(version: string) { + switch (platform()) { + case "darwin": + return `https://releases.parity.io/ethereum/v${version}/x86_64-apple-darwin/parity`; + case "linux": + return `https://releases.parity.io/ethereum/v${version}/x86_64-unknown-linux-gnu/parity`; + default: + throw new Error(`Unsupported platform ${platform()}`); + } +} diff --git a/api_tests/types/chmod/index.d.ts b/api_tests/types/chmod/index.d.ts new file mode 100644 index 0000000000..2ea38e2cf8 --- /dev/null +++ b/api_tests/types/chmod/index.d.ts @@ -0,0 +1,9 @@ +declare module "chmod" { + // there is more to this API but this is what we need + export default function chmod( + file: string, + options: { + execute?: boolean; + } + ); +} diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index ca21107fdb..b39fbede6e 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -10,44 +10,45 @@ "@babel/highlight" "^7.8.3" "@babel/core@^7.1.0", "@babel/core@^7.7.5": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.6.tgz#27d7df9258a45c2e686b6f18b6c659e563aa4636" - integrity sha512-Sheg7yEJD51YHAvLEV/7Uvw95AeWqYPL3Vk3zGujJKIhJ+8oLw2ALaf3hbucILhKsgSoADOvtKRJuNVdcJkOrg== + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.0.tgz#ac977b538b77e132ff706f3b8a4dbad09c03c56e" + integrity sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w== dependencies: "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.8.6" - "@babel/helpers" "^7.8.4" - "@babel/parser" "^7.8.6" + "@babel/generator" "^7.9.0" + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helpers" "^7.9.0" + "@babel/parser" "^7.9.0" "@babel/template" "^7.8.6" - "@babel/traverse" "^7.8.6" - "@babel/types" "^7.8.6" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" - json5 "^2.1.0" + json5 "^2.1.2" lodash "^4.17.13" resolve "^1.3.2" semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.8.6": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.6.tgz#57adf96d370c9a63c241cd719f9111468578537a" - integrity sha512-4bpOR5ZBz+wWcMeVtcf7FbjcFzCp+817z2/gHNncIRcM9MmKzUhtWCYAq27RAfUrAFwb+OCG1s9WEaVxfi6cjg== +"@babel/generator@^7.9.0", "@babel/generator@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.5.tgz#27f0917741acc41e6eaaced6d68f96c3fa9afaf9" + integrity sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ== dependencies: - "@babel/types" "^7.8.6" + "@babel/types" "^7.9.5" jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" -"@babel/helper-function-name@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca" - integrity sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA== +"@babel/helper-function-name@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz#2b53820d35275120e1874a82e5aabe1376920a5c" + integrity sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw== dependencies: "@babel/helper-get-function-arity" "^7.8.3" "@babel/template" "^7.8.3" - "@babel/types" "^7.8.3" + "@babel/types" "^7.9.5" "@babel/helper-get-function-arity@^7.8.3": version "7.8.3" @@ -56,11 +57,63 @@ dependencies: "@babel/types" "^7.8.3" +"@babel/helper-member-expression-to-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz#659b710498ea6c1d9907e0c73f206eee7dadc24c" + integrity sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-module-imports@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz#7fe39589b39c016331b6b8c3f441e8f0b1419498" + integrity sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-module-transforms@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz#43b34dfe15961918707d247327431388e9fe96e5" + integrity sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA== + dependencies: + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.6" + "@babel/helper-simple-access" "^7.8.3" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/template" "^7.8.6" + "@babel/types" "^7.9.0" + lodash "^4.17.13" + +"@babel/helper-optimise-call-expression@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz#7ed071813d09c75298ef4f208956006b6111ecb9" + integrity sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ== + dependencies: + "@babel/types" "^7.8.3" + "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz#9ea293be19babc0f52ff8ca88b34c3611b208670" integrity sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ== +"@babel/helper-replace-supers@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz#5ada744fd5ad73203bf1d67459a27dcba67effc8" + integrity sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.8.3" + "@babel/helper-optimise-call-expression" "^7.8.3" + "@babel/traverse" "^7.8.6" + "@babel/types" "^7.8.6" + +"@babel/helper-simple-access@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz#7f8109928b4dab4654076986af575231deb639ae" + integrity sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw== + dependencies: + "@babel/template" "^7.8.3" + "@babel/types" "^7.8.3" + "@babel/helper-split-export-declaration@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9" @@ -68,28 +121,33 @@ dependencies: "@babel/types" "^7.8.3" -"@babel/helpers@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.8.4.tgz#754eb3ee727c165e0a240d6c207de7c455f36f73" - integrity sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w== +"@babel/helper-validator-identifier@^7.9.0", "@babel/helper-validator-identifier@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80" + integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g== + +"@babel/helpers@^7.9.0": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.9.2.tgz#b42a81a811f1e7313b88cba8adc66b3d9ae6c09f" + integrity sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA== dependencies: "@babel/template" "^7.8.3" - "@babel/traverse" "^7.8.4" - "@babel/types" "^7.8.3" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" "@babel/highlight@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.8.3.tgz#28f173d04223eaaa59bc1d439a3836e6d1265797" - integrity sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg== + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" + integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ== dependencies: + "@babel/helper-validator-identifier" "^7.9.0" chalk "^2.0.0" - esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.7.5", "@babel/parser@^7.8.6": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.6.tgz#ba5c9910cddb77685a008e3c587af8d27b67962c" - integrity sha512-trGNYSfwq5s0SgM1BMEB8hX3NDmO7EP2wsDGDexiaKMB92BaRpS+qZfpkMqUBhcsOTBwNy9B/jieo4ad/t/z2g== +"@babel/parser@^7.1.0", "@babel/parser@^7.7.5", "@babel/parser@^7.8.6", "@babel/parser@^7.9.0": + version "7.9.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.4.tgz#68a35e6b0319bbc014465be43828300113f2f2e8" + integrity sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA== "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -170,27 +228,27 @@ "@babel/parser" "^7.8.6" "@babel/types" "^7.8.6" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.7.4", "@babel/traverse@^7.8.4", "@babel/traverse@^7.8.6": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.6.tgz#acfe0c64e1cd991b3e32eae813a6eb564954b5ff" - integrity sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A== +"@babel/traverse@^7.1.0", "@babel/traverse@^7.7.4", "@babel/traverse@^7.8.6", "@babel/traverse@^7.9.0": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.5.tgz#6e7c56b44e2ac7011a948c21e283ddd9d9db97a2" + integrity sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ== dependencies: "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.8.6" - "@babel/helper-function-name" "^7.8.3" + "@babel/generator" "^7.9.5" + "@babel/helper-function-name" "^7.9.5" "@babel/helper-split-export-declaration" "^7.8.3" - "@babel/parser" "^7.8.6" - "@babel/types" "^7.8.6" + "@babel/parser" "^7.9.0" + "@babel/types" "^7.9.5" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.13" -"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.8.3", "@babel/types@^7.8.6": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.6.tgz#629ecc33c2557fcde7126e58053127afdb3e6d01" - integrity sha512-wqz7pgWMIrht3gquyEFPVXeXCti72Rm8ep9b5tQKz9Yg9LzJA3HxosF1SB3Kc81KD1A3XBkkVYtJvCKS2Z/QrA== +"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0", "@babel/types@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.5.tgz#89231f82915a8a566a703b3b20133f73da6b9444" + integrity sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg== dependencies: - esutils "^2.0.2" + "@babel/helper-validator-identifier" "^7.9.5" lodash "^4.17.13" to-fast-properties "^2.0.0" @@ -381,16 +439,6 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" -"@jest/types@^25.2.6": - version "25.2.6" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.2.6.tgz#c12f44af9bed444438091e4b59e7ed05f8659cb6" - integrity sha512-myJTTV37bxK7+3NgKc4Y/DlQ5q92/NOwZsZ+Uch7OXdElxOg61QYc72fPYNAjlvbnJ2YvbXLamIsa9tj48BmyQ== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^1.1.1" - "@types/yargs" "^15.0.0" - chalk "^3.0.0" - "@jest/types@^25.3.0": version "25.3.0" resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.3.0.tgz#88f94b277a1d028fd7117bc1f74451e0fc2131e7" @@ -476,10 +524,15 @@ pkg-dir "^2.0.0" ts-protoc-gen "^0.8.0" +"@sindresorhus/is@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" + integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== + "@sinonjs/commons@^1.7.0": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.1.tgz#da5fd19a5f71177a53778073978873964f49acf1" - integrity sha512-Debi3Baff1Qu1Unc3mjJ96MgpbwTn43S1+9yJ0llWygPwDNu2aaWBD6yc9y/Z8XDRNhx7U+u2UDg2OGQXkclUQ== + version "1.7.2" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.2.tgz#505f55c74e0272b43f6c52d81946bed7058fc0e2" + integrity sha512-+DUO6pnp3udV/v2VfUWgaY5BIE1IfT7lLfeDzPVeMT1XKkaAp9LgSI9x5RtrFQoZ9Oi0PgXQQHPaoKu7dCjVxw== dependencies: type-detect "4.0.8" @@ -510,9 +563,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.0.9" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.9.tgz#be82fab304b141c3eee81a4ce3b034d0eba1590a" - integrity sha512-jEFQ8L1tuvPjOI8lnpaf73oCJe+aoxL6ygqSy6c8LcW98zaC+4mzWuQIRCEvKeCOu+lbqdXcg4Uqmm1S8AP1tw== + version "7.0.10" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.10.tgz#d9a99f017317d9b3d1abc2ced45d3bca68df0daf" + integrity sha512-74fNdUGrWsgIB/V9kTO5FGHPWYY6Eqn+3Z7L6Hc4e/BxjYV7puvBqp5HwsVYYfLm6iURYBNCx4Ut37OF9yitCw== dependencies: "@babel/types" "^7.3.0" @@ -560,11 +613,32 @@ resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.1.tgz#90b68446364baf9efd8e8349bb36bd3852b75b80" integrity sha512-aRnpPa7ysx3aNW60hTiCtLHlQaIFsXFCgQlpakNgDNVFzbtusSY8PwjAQgRWfSk0ekNoBjO51eQRB6upA9uuyw== +"@types/decompress@*": + version "4.2.3" + resolved "https://registry.yarnpkg.com/@types/decompress/-/decompress-4.2.3.tgz#98eed48af80001038aa05690b2094915f296fe65" + integrity sha512-W24e3Ycz1UZPgr1ZEDHlK4XnvOr+CpJH3qNsFeqXwwlW/9END9gxn3oJSsp7gYdiQxrXUHwUUd3xuzVz37MrZQ== + dependencies: + "@types/node" "*" + +"@types/download@^6.2.4": + version "6.2.4" + resolved "https://registry.yarnpkg.com/@types/download/-/download-6.2.4.tgz#d9fb74defe20d75f59a38a9b5b0eb5037d37161a" + integrity sha512-Lo5dy3ai6LNnbL663sgdzqL1eib11u1yKH6w3v3IXEOO4kRfQpMn1qWUTaumcHLACjFp1RcBx9tUXEvJoR3vcA== + dependencies: + "@types/decompress" "*" + "@types/got" "^8" + "@types/node" "*" + "@types/events@*": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== +"@types/find-cache-dir@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@types/find-cache-dir/-/find-cache-dir-3.2.0.tgz#eaaf331699dccf52c47926e4d4f8f3ed8db33f3c" + integrity sha512-+JeT9qb2Jwzw72WdjU+TSvD5O1QRPWCeRpDJV+guiIq+2hwR0DFGw+nZNbTFjMIVe6Bf4GgAKeB/6Ytx6+MbeQ== + "@types/glob@*", "@types/glob@^7.1.1": version "7.1.1" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" @@ -579,6 +653,13 @@ resolved "https://registry.yarnpkg.com/@types/google-protobuf/-/google-protobuf-3.7.2.tgz#cd8a360c193ce4d672575a20a79f49ba036d38d2" integrity sha512-ifFemzjNchFBCtHS6bZNhSZCBu7tbtOe0e8qY0z2J4HtFXmPJjm6fXSaQsTG7yhShBEZtt2oP/bkwu5k+emlkQ== +"@types/got@^8": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@types/got/-/got-8.3.5.tgz#d8a0e8fa7598681b332a4d27779b022b2e55fb7f" + integrity sha512-AaXSrIF99SjjtPVNmCmYb388HML+PKEJb/xmj4SbL2ZO0hHuETZZzyDIKfOqaEoAHZEuX4sC+FRFrHYJoIby6A== + dependencies: + "@types/node" "*" + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" @@ -630,14 +711,14 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*", "@types/node@^13.11": - version "13.11.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.0.tgz#390ea202539c61c8fa6ba4428b57e05bc36dc47b" - integrity sha512-uM4mnmsIIPK/yeO+42F2RQhGUIs39K2RFmugcJANppXe6J1nvH87PvzPZYpza7Xhhs8Yn9yIAVdLZ84z61+0xQ== + version "13.11.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.1.tgz#49a2a83df9d26daacead30d0ccc8762b128d53c7" + integrity sha512-eWQGP3qtxwL8FGneRrC5DwrJLGN4/dH1clNTuLfN81HCrxVtxRjygDTUoZJ5ASlDEeo0ppYFQjQIlXhtXpOn6g== "@types/node@^10.1.0": - version "10.17.17" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.17.tgz#7a183163a9e6ff720d86502db23ba4aade5999b8" - integrity sha512-gpNnRnZP3VWzzj5k3qrpRC6Rk3H/uclhAVo1aIvwzK5p5cOrs9yEyQ8H/HBsBY0u5rrWxXEiVPQ0dEB6pkjE8Q== + version "10.17.19" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.19.tgz#1d31ddd5503dba2af7a901aafef3392e4955620e" + integrity sha512-46/xThm3zvvc9t9/7M3AaLEqtOpqlYYYcCZbpYVAQHG20+oMZBkae/VMrn4BTi6AJ8cpack0mEXhGiKmDNbLrQ== "@types/prettier@^1.19.0": version "1.19.1" @@ -748,9 +829,9 @@ acorn-walk@^6.0.1: integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== acorn@^6.0.1: - version "6.4.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784" - integrity sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw== + version "6.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" + integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== acorn@^7.1.0: version "7.1.1" @@ -763,11 +844,11 @@ aes-js@3.0.0: integrity sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= ajv@^6.5.5: - version "6.10.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1" - integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg== + version "6.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" + integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== dependencies: - fast-deep-equal "^2.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" @@ -835,6 +916,13 @@ aproba@^1.0.3: resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== +archive-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/archive-type/-/archive-type-4.0.0.tgz#f92e72233056dfc6969472749c267bdb046b1d70" + integrity sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA= + dependencies: + file-type "^4.2.0" + are-we-there-yet@~1.1.2: version "1.1.5" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" @@ -844,9 +932,9 @@ are-we-there-yet@~1.1.2: readable-stream "^2.0.6" arg@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.0.tgz#583c518199419e0037abb74062c37f8519e575f0" - integrity sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg== + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== argparse@^1.0.7: version "1.0.10" @@ -936,17 +1024,16 @@ aws-sign2@~0.7.0: integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= aws4@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" - integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== + version "1.9.1" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" + integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== axios@^0.19.0: - version "0.19.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8" - integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ== + version "0.19.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" + integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== dependencies: follow-redirects "1.5.10" - is-buffer "^2.0.2" babel-jest@^25.3.0: version "25.3.0" @@ -1008,6 +1095,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= +base64-js@^1.0.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + base@^0.11.1: version "0.11.2" resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" @@ -1109,9 +1201,9 @@ bevent@~0.1.5: bsert "~0.0.10" bfile@~0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/bfile/-/bfile-0.2.1.tgz#2d19ac27f355fef861d5d1a4cd0e4a7f27bb4151" - integrity sha512-du2QjKNkqZ1YJweWEQeq3CEqd+nQD/WOnmAMfs52ok5ujBBagWYLZC5ORDuqfV2fuF88of44PZdsnAVfxoH31g== + version "0.2.2" + resolved "https://registry.yarnpkg.com/bfile/-/bfile-0.2.2.tgz#b0c205cee1ff22a9525304ec51f09195a7afa077" + integrity sha512-X205SsJ7zFAnjeJ/pBLqDqF10x/4Su3pBy8UdVKw4hdGJk7t5pLoRi+uG4rPaDAClGbrEfT/06PGUbYiMYKzTg== bfilter@~1.0.5: version "1.0.5" @@ -1179,6 +1271,14 @@ bitcoin-core@^3.0.0: semver "^5.1.0" standard-error "^1.1.0" +bl@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" + integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA== + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + blgr@~0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/blgr/-/blgr-0.1.7.tgz#69ed054282e5d3be7b6b19b03962a397227ab498" @@ -1201,9 +1301,9 @@ blst@~0.1.5: bsert "~0.0.10" bluebird@^3.4.1: - version "3.7.1" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.1.tgz#df70e302b471d7473489acf26a93d63b53f874de" - integrity sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg== + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== bmutex@~0.1.6: version "0.1.6" @@ -1269,10 +1369,10 @@ brorand@^1.0.1: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= -browser-process-hrtime@^0.1.2: - version "0.1.3" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4" - integrity sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw== +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== browser-resolve@^1.11.3: version "1.11.3" @@ -1296,9 +1396,9 @@ bs-logger@0.x: fast-json-stable-stringify "2.x" bs32@~0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/bs32/-/bs32-0.1.5.tgz#b36da53d547e60282ae3225219331f7cfa77a22d" - integrity sha512-YR9OXFjx8qmW/TpuJKc1RSdzRogpCYh1ygCSMi5Z3fG2QkP+Ra1IfcHsICqd/I/tmFAtc7ov8BpEyN8HJD7jlw== + version "0.1.6" + resolved "https://registry.yarnpkg.com/bs32/-/bs32-0.1.6.tgz#2710cb70da3f55447138181fa645e2c54b1ef6d0" + integrity sha512-usjDesQqZ8ihHXOnOEQuAdymBHnJEfSd+aELFSg1jN/V3iAf12HrylHlRJwIt6DTMmXpBDQ+YBg3Q3DIYdhRgQ== dependencies: bsert "~0.0.10" @@ -1352,6 +1452,29 @@ btcp@~0.1.5: resolved "https://registry.yarnpkg.com/btcp/-/btcp-0.1.5.tgz#f76262415a0f6eaa592cdbb91c8b18386530ac28" integrity sha512-tkrtMDxeJorn5p0KxaLXELneT8AbfZMpOFeoKYZ5qCCMMSluNuwut7pGccLC5YOJqmuk0DR774vNVQLC9sNq/A== +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + buffer-from@1.x, buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -1362,6 +1485,14 @@ buffer-map@~0.0.7: resolved "https://registry.yarnpkg.com/buffer-map/-/buffer-map-0.0.7.tgz#5c2db65f7b3a723a2d9dff8e896fada3d2dc1c5d" integrity sha512-95try3p/vMRkIAAnJDaGkFhGpT/65NoeW6XelEPjAomWYR58RQtW4khn0SwKj34kZoE7uxL7w2koZSwbnszvQQ== +buffer@^5.2.1: + version "5.5.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.5.0.tgz#9c3caa3d623c33dd1c7ef584b89b88bf9c9bc1ce" + integrity sha512-9FTEDjLjwoAkEwyMGDjYJQN2gfRgOKBKRfiglhvibGbpeeU/pQn1bJxQqm32OD/AIeEuHxU9roxXxg34Byp/Ww== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + bufio@~1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/bufio/-/bufio-1.0.6.tgz#e0eb6d70b2efcc997b6f8872173540967f90fa4d" @@ -1399,9 +1530,9 @@ bval@~0.1.6: bsert "~0.0.10" bweb@~0.1.9: - version "0.1.9" - resolved "https://registry.yarnpkg.com/bweb/-/bweb-0.1.9.tgz#9a542d98fdac8b39ce0551634dec19424be7d193" - integrity sha512-Ozz6Vq7mC0ydHxnykvkUIiwduKAW4Qewj+au0osTCSssfXfRYrO7O2UluLgZQL0sSrXiifqEdJaGtOQ+GAeC8A== + version "0.1.10" + resolved "https://registry.yarnpkg.com/bweb/-/bweb-0.1.10.tgz#7b28c905e09fd4d4d7114c0f70a8bdc076f1ed08" + integrity sha512-3Kkz/rfsyAWUS+8DV5XYhwcgVN4DfDewrP+iFTcpQfdZzcF6+OypAq7dHOtXV0sW7U/3msA/sEEqz0MHZ9ERWg== dependencies: bsert "~0.0.10" bsock "~0.1.8" @@ -1433,6 +1564,19 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" +cacheable-request@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" + integrity sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0= + dependencies: + clone-response "1.0.2" + get-stream "3.0.0" + http-cache-semantics "3.8.1" + keyv "3.0.0" + lowercase-keys "1.0.0" + normalize-url "2.0.1" + responselike "1.0.2" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -1460,6 +1604,16 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= +caw@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/caw/-/caw-2.0.1.tgz#6c3ca071fc194720883c2dc5da9b074bfc7e9e95" + integrity sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA== + dependencies: + get-proxy "^2.0.0" + isurl "^1.0.0-alpha5" + tunnel-agent "^0.6.0" + url-to-options "^1.0.1" + chai-as-promised@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" @@ -1542,10 +1696,18 @@ check-error@^1.0.2: resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= +chmod@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/chmod/-/chmod-0.2.1.tgz#dee71c420fc00bf523d572b14922f55d919f9d0a" + integrity sha1-3uccQg/AC/Uj1XKxSSL1XZGfnQo= + dependencies: + deep-extend "^0.2.8" + stat-mode "~0.1.0" + chownr@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.2.tgz#a18f1e0b269c8a6a5d3c86eb298beb14c3dd7bf6" - integrity sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A== + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== ci-info@^2.0.0: version "2.0.0" @@ -1580,6 +1742,13 @@ cliui@^6.0.0: strip-ansi "^6.0.0" wrap-ansi "^6.2.0" +clone-response@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -1591,9 +1760,9 @@ code-point-at@^1.0.0: integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= collect-v8-coverage@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.0.tgz#150ee634ac3650b71d9c985eb7f608942334feb1" - integrity sha512-VKIhJgvk8E1W28m5avZ2Gv2Ruv5YiF56ug2oclvaG9md69BuZImMG2sk9g7QNKLUbtYAKQjXjYxbYZVUlMMKmQ== + version "1.0.1" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== collection-visit@^1.0.0: version "1.0.0" @@ -1657,9 +1826,21 @@ comit-sdk@^0.15.2: urijs "^1.19.2" commander@^2.12.1: - version "2.20.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" - integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@~2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" + integrity sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ= + dependencies: + graceful-readlink ">= 1.0.0" + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= component-emitter@^1.2.0, component-emitter@^1.2.1: version "1.3.0" @@ -1671,12 +1852,20 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +config-chain@^1.1.11: + version "1.1.12" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" + integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= -content-disposition@0.5.3: +content-disposition@0.5.3, content-disposition@^0.5.2: version "0.5.3" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== @@ -1732,9 +1921,9 @@ cross-spawn@^6.0.0: which "^1.2.9" cross-spawn@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" - integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg== + version "7.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.2.tgz#d0d7dcfa74e89115c7619f4f721a94e1fdb716d6" + integrity sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" @@ -1829,6 +2018,66 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" + integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== + dependencies: + file-type "^5.2.0" + is-stream "^1.1.0" + tar-stream "^1.5.2" + +decompress-tarbz2@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" + integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== + dependencies: + decompress-tar "^4.1.0" + file-type "^6.1.0" + is-stream "^1.1.0" + seek-bzip "^1.0.5" + unbzip2-stream "^1.0.9" + +decompress-targz@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" + integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== + dependencies: + decompress-tar "^4.1.1" + file-type "^5.2.0" + is-stream "^1.1.0" + +decompress-unzip@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" + integrity sha1-3qrM39FK6vhVePczroIQ+bSEj2k= + dependencies: + file-type "^3.8.0" + get-stream "^2.2.0" + pify "^2.3.0" + yauzl "^2.4.2" + +decompress@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118" + integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ== + dependencies: + decompress-tar "^4.0.0" + decompress-tarbz2 "^4.0.0" + decompress-targz "^4.0.0" + decompress-unzip "^4.0.1" + graceful-fs "^4.1.10" + make-dir "^1.0.0" + pify "^2.3.0" + strip-dirs "^2.0.0" + deep-eql@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" @@ -1836,6 +2085,11 @@ deep-eql@^3.0.1: dependencies: type-detect "^4.0.0" +deep-extend@^0.2.8: + version "0.2.11" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.2.11.tgz#7a16ba69729132340506170494bc83f7076fe08f" + integrity sha1-eha6aXKRMjQFBhcElLyD9wdv4I8= + deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -1909,9 +2163,9 @@ diff-sequences@^25.2.6: integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg== diff@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff" - integrity sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q== + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== domexception@^1.0.1: version "1.0.1" @@ -1920,12 +2174,35 @@ domexception@^1.0.1: dependencies: webidl-conversions "^4.0.2" +download@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/download/-/download-7.1.0.tgz#9059aa9d70b503ee76a132897be6dec8e5587233" + integrity sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ== + dependencies: + archive-type "^4.0.0" + caw "^2.0.1" + content-disposition "^0.5.2" + decompress "^4.2.0" + ext-name "^5.0.0" + file-type "^8.1.0" + filenamify "^2.0.0" + get-stream "^3.0.0" + got "^8.3.1" + make-dir "^1.2.0" + p-event "^2.1.0" + pify "^3.0.0" + dtrace-provider@~0.8: - version "0.8.7" - resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.7.tgz#dc939b4d3e0620cfe0c1cd803d0d2d7ed04ffd04" - integrity sha1-3JObTT4GIM/gwc2APQ0tftBP/QQ= + version "0.8.8" + resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.8.tgz#2996d5490c37e1347be263b423ed7b297fb0d97e" + integrity sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg== dependencies: - nan "^2.10.0" + nan "^2.14.0" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= ecc-jsbn@~0.1.1: version "0.1.2" @@ -1963,10 +2240,10 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -end-of-stream@^1.1.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" - integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" @@ -1975,7 +2252,7 @@ escape-html@~1.0.3: resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= -escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -2003,9 +2280,9 @@ estraverse@^4.2.0: integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== etag@~1.8.1: version "1.8.1" @@ -2127,6 +2404,21 @@ express@^4.17.1: utils-merge "1.0.1" vary "~1.1.2" +ext-list@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/ext-list/-/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37" + integrity sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA== + dependencies: + mime-db "^1.28.0" + +ext-name@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ext-name/-/ext-name-5.0.0.tgz#70781981d183ee15d13993c8822045c506c8f0a6" + integrity sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ== + dependencies: + ext-list "^2.0.0" + sort-keys-length "^1.0.0" + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" @@ -2171,10 +2463,10 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: version "2.1.0" @@ -2193,6 +2485,52 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= + dependencies: + pend "~1.2.0" + +file-type@^3.8.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek= + +file-type@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-4.4.0.tgz#1b600e5fca1fbdc6e80c0a70c71c8dba5f7906c5" + integrity sha1-G2AOX8ofvcboDApwxxyNul95BsU= + +file-type@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" + integrity sha1-LdvqfHP/42No365J3DOMBYwritY= + +file-type@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" + integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== + +file-type@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-8.1.0.tgz#244f3b7ef641bbe0cca196c7276e4b332399f68c" + integrity sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ== + +filename-reserved-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" + integrity sha1-q/c9+rc10EVECr/qLZHzieu/oik= + +filenamify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-2.1.0.tgz#88faf495fb1b47abfd612300002a16228c677ee9" + integrity sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA== + dependencies: + filename-reserved-regex "^2.0.0" + strip-outer "^1.0.0" + trim-repeated "^1.0.0" + fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -2223,6 +2561,15 @@ finalhandler@~1.1.2: statuses "~1.5.0" unpipe "~1.0.0" +find-cache-dir@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" + integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" @@ -2239,9 +2586,9 @@ find-up@^4.0.0, find-up@^4.1.0: path-exists "^4.0.0" flatted@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" - integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" + integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== follow-redirects@1.5.10: version "1.5.10" @@ -2260,7 +2607,16 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -form-data@^2.3.1, form-data@~2.3.2: +form-data@^2.3.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" + integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== @@ -2270,9 +2626,9 @@ form-data@^2.3.1, form-data@~2.3.2: mime-types "^2.1.12" formidable@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.1.tgz#70fb7ca0290ee6ff961090415f4b3df3d2082659" - integrity sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg== + version "1.2.2" + resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.2.tgz#bf69aea2972982675f00865342b982986f6b8dd9" + integrity sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q== forwarded@~0.1.2: version "0.1.2" @@ -2291,6 +2647,19 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= +from2@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" @@ -2351,6 +2720,26 @@ get-port@^5.1.1: resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== +get-proxy@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/get-proxy/-/get-proxy-2.1.0.tgz#349f2b4d91d44c4d4d4e9cba2ad90143fac5ef93" + integrity sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw== + dependencies: + npm-conf "^1.1.0" + +get-stream@3.0.0, get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-stream@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4= + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + get-stream@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -2410,15 +2799,38 @@ google-protobuf@^3.6.1: resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.11.4.tgz#598ca405a3cfa917a2132994d008b5932ef42014" integrity sha512-lL6b04rDirurUBOgsY2+LalI6Evq8eH5TcNzi7TYQ3BsIWelT0KSOQSBsXuavEkNf+odQU6c0lgz3UsZXeNX9Q== -graceful-fs@^4.1.11, graceful-fs@^4.2.3: +got@^8.3.1: + version "8.3.2" + resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" + integrity sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw== + dependencies: + "@sindresorhus/is" "^0.7.0" + cacheable-request "^2.1.1" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + into-stream "^3.1.0" + is-retry-allowed "^1.1.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + mimic-response "^1.0.0" + p-cancelable "^0.4.0" + p-timeout "^2.0.1" + pify "^3.0.0" + safe-buffer "^5.1.1" + timed-out "^4.0.1" + url-parse-lax "^3.0.0" + url-to-options "^1.0.1" + +graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== -graceful-fs@^4.1.15, graceful-fs@^4.1.6, graceful-fs@^4.2.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02" - integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q== +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= growly@^1.3.0: version "1.3.0" @@ -2442,7 +2854,7 @@ har-schema@^2.0.0: resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= -har-validator@~5.1.0, har-validator@~5.1.3: +har-validator@~5.1.3: version "5.1.3" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== @@ -2460,6 +2872,18 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== + +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== + dependencies: + has-symbol-support-x "^1.4.1" + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -2529,9 +2953,14 @@ html-encoding-sniffer@^1.0.2: whatwg-encoding "^1.0.1" html-escaper@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.0.tgz#71e87f931de3fe09e56661ab9a29aadec707b491" - integrity sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig== + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +http-cache-semantics@3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== http-errors@1.7.2: version "1.7.2" @@ -2576,6 +3005,11 @@ iconv-lite@0.4.24, iconv-lite@^0.4.4: dependencies: safer-buffer ">= 2.1.2 < 3" +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + ignore-walk@^3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" @@ -2614,11 +3048,19 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@~1.3.0: +ini@^1.3.4, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== +into-stream@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" + integrity sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY= + dependencies: + from2 "^2.1.1" + p-is-promise "^1.1.0" + invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" @@ -2629,10 +3071,10 @@ ip-regex@^2.0.0, ip-regex@^2.1.0: resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= -ipaddr.js@1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65" - integrity sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA== +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== is-accessor-descriptor@^0.1.6: version "0.1.6" @@ -2653,11 +3095,6 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-buffer@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" - integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== - is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" @@ -2738,6 +3175,11 @@ is-ip@^2.0.0: dependencies: ip-regex "^2.0.0" +is-natural-number@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" + integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg= + is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -2750,6 +3192,16 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= + +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -2757,6 +3209,11 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-retry-allowed@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" + integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== + is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -2853,6 +3310,14 @@ istanbul-reports@^3.0.2: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + jasmine-core@~3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.5.0.tgz#132c23e645af96d85c8bca13c8758b18429fc1e4" @@ -2918,17 +3383,7 @@ jest-config@^25.3.0: pretty-format "^25.3.0" realpath-native "^2.0.0" -jest-diff@^25.2.1: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.2.6.tgz#a6d70a9ab74507715ea1092ac513d1ab81c1b5e7" - integrity sha512-KuadXImtRghTFga+/adnNrv9s61HudRMR7gVSbP35UKZdn4IK2/0N0PpGZIqtmllK9aUyye54I3nu28OYSnqOg== - dependencies: - chalk "^3.0.0" - diff-sequences "^25.2.6" - jest-get-type "^25.2.6" - pretty-format "^25.2.6" - -jest-diff@^25.3.0: +jest-diff@^25.2.1, jest-diff@^25.3.0: version "25.3.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.3.0.tgz#0d7d6f5d6171e5dacde9e05be47b3615e147c26f" integrity sha512-vyvs6RPoVdiwARwY4kqFWd4PirPLm2dmmkNzKqo38uZOzJvLee87yzDjIZLmY1SjM3XR5DwsUH+cdQ12vgqi1w== @@ -3300,6 +3755,11 @@ json-bigint@^0.2.0: dependencies: bignumber.js "^4.0.0" +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -3315,12 +3775,12 @@ json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -json5@2.x, json5@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.1.tgz#81b6cb04e9ba496f1c7005d07b4368a2638f90b6" - integrity sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ== +json5@2.x, json5@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== dependencies: - minimist "^1.2.0" + minimist "^1.2.5" jsonfile@^4.0.0: version "4.0.0" @@ -3344,6 +3804,13 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" +keyv@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" + integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA== + dependencies: + json-buffer "3.0.0" + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -3466,10 +3933,27 @@ long@~3: resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" integrity sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s= -make-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.0.tgz#1b5f39f6b9270ed33f9f054c5c0f84304989f801" - integrity sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw== +lowercase-keys@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + integrity sha1-TjNms55/VFfjXxMkvfb4jQv8cwY= + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +make-dir@^1.0.0, make-dir@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + +make-dir@^3.0.0, make-dir@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.2.tgz#04a1acbf22221e1d6ef43559f43e05a90dbb4392" + integrity sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w== dependencies: semver "^6.0.0" @@ -3544,29 +4028,17 @@ micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" -mime-db@1.40.0: - version "1.40.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" - integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== - -mime-db@1.42.0: - version "1.42.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" - integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== - -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.24" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" - integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== - dependencies: - mime-db "1.40.0" +mime-db@1.43.0, mime-db@^1.28.0: + version "1.43.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" + integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== -mime-types@~2.1.24: - version "2.1.25" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437" - integrity sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg== +mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.26" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" + integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== dependencies: - mime-db "1.42.0" + mime-db "1.43.0" mime@1.6.0, mime@^1.4.1: version "1.6.0" @@ -3578,6 +4050,11 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -3595,12 +4072,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: dependencies: brace-expansion "^1.1.7" -minimist@^1.1.1, minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -minimist@^1.2.5: +minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== @@ -3629,14 +4101,14 @@ mixin-deep@^1.2.0: is-extendable "^1.0.1" mkdirp@1.x: - version "1.0.3" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.3.tgz#4cf2e30ad45959dddea53ad97d518b6c8205e1ea" - integrity sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g== + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1: - version "0.5.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.4.tgz#fd01504a6797ec5c9be81ff43d204961ed64a512" - integrity sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw== + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: minimist "^1.2.5" @@ -3646,13 +4118,12 @@ moment@^2.10.6, moment@^2.24.0: integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== mrmr@~0.1.6, mrmr@~0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/mrmr/-/mrmr-0.1.8.tgz#206b7975157543d2cffe762eec23966000b3fd12" - integrity sha512-lNav10EJsPZvlMqlBOYQ5atIO9jrlvbJ4/7asqunXY89dHooN5c+W6AV7jtvBRw4wFDR7TpEWfmBQgRGRVwBzA== + version "0.1.9" + resolved "https://registry.yarnpkg.com/mrmr/-/mrmr-0.1.9.tgz#6a4f39b39bb7d837879ef74ddc1a58ca3796d22b" + integrity sha512-t3nbygZEPN0vkoW+985GAVw/OOQODmAwPwCfaQUCQbTaZG40s7wmFaC8AKu4oL0g7hF4xcstwkvzW6bu4QxRSg== dependencies: bsert "~0.0.10" loady "~0.0.1" - nan "^2.13.1" ms@2.0.0: version "2.0.0" @@ -3683,7 +4154,7 @@ n64@~0.2.10: resolved "https://registry.yarnpkg.com/n64/-/n64-0.2.10.tgz#e5831073dd527e6934b880231a43f3a8e36c096a" integrity sha512-uH9geV4+roR1tohsrrqSOLCJ9Mh1iFcDI+9vUuydDlDxUS1UCAWUfuGb06p3dj3flzywquJNrGsQ7lHP8+4RVQ== -nan@^2.10.0, nan@^2.13.1, nan@^2.13.2: +nan@^2.13.1, nan@^2.13.2, nan@^2.14.0: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== @@ -3716,9 +4187,9 @@ ncp@~2.0.0: integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M= needle@^2.2.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.3.2.tgz#3342dea100b7160960a450dc8c22160ac712a528" - integrity sha512-DUzITvPVDUy6vczKKYTnWc/pBZ0EnjMJnQ3y+Jo5zfKFimJs7S3HFCxCRZYB9FUZcrzUQr3WsmvZgddMEIZv6w== + version "2.4.1" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.1.tgz#14af48732463d7475696f937626b1b993247a56a" + integrity sha512-x/gi6ijr4B7fwl6WYL9FwlCvRQKGlUNvnceho8wxkwXqN8jvVmmmATTmZPRRG7b/yC1eode26C2HO9jl78Du9g== dependencies: debug "^3.2.6" iconv-lite "^0.4.4" @@ -3772,9 +4243,9 @@ node-pre-gyp@^0.14.0: tar "^4.4.2" nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= + version "4.0.3" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" + integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== dependencies: abbrev "1" osenv "^0.1.4" @@ -3791,6 +4262,15 @@ normalize-path@^3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +normalize-url@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" + integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== + dependencies: + prepend-http "^2.0.0" + query-string "^5.0.1" + sort-keys "^2.0.0" + npm-bundled@^1.0.1: version "1.1.1" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" @@ -3798,6 +4278,14 @@ npm-bundled@^1.0.1: dependencies: npm-normalize-package-bin "^1.0.1" +npm-conf@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" + integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw== + dependencies: + config-chain "^1.1.11" + pify "^3.0.0" + npm-normalize-package-bin@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" @@ -3851,7 +4339,7 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4.1.0: +object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -3942,11 +4430,23 @@ osenv@^0.1.4: os-homedir "^1.0.0" os-tmpdir "^1.0.0" +p-cancelable@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" + integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ== + p-each-series@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.1.0.tgz#961c8dd3f195ea96c747e636b262b800a6b1af48" integrity sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ== +p-event@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-2.3.1.tgz#596279ef169ab2c3e0cae88c1cfbb08079993ef6" + integrity sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA== + dependencies: + p-timeout "^2.0.1" + p-event@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.1.0.tgz#e92bb866d7e8e5b732293b1c8269d38e9982bf8e" @@ -3964,6 +4464,11 @@ p-finally@^2.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= + p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -3972,9 +4477,9 @@ p-limit@^1.1.0: p-try "^1.0.0" p-limit@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" - integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" @@ -4051,12 +4556,7 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-key@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.0.tgz#99a10d870a803bdd5ee6f0470e58dfcd2f9a54d3" - integrity sha512-8cChqz0RP6SHJkMt48FW0A7+qUOn+OsnOsVtzI59tZ8m+5bCSk7hzwET0pulwOM2YMn9J1efb07KB9l9f30SGg== - -path-key@^3.1.0: +path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== @@ -4076,15 +4576,42 @@ pathval@^1.1.0: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= picomatch@^2.0.4, picomatch@^2.0.5: - version "2.2.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a" - integrity sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA== + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= pirates@^4.0.1: version "4.0.1" @@ -4100,7 +4627,7 @@ pkg-dir@^2.0.0: dependencies: find-up "^2.1.0" -pkg-dir@^4.2.0: +pkg-dir@^4.1.0, pkg-dir@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== @@ -4122,22 +4649,17 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + prettier@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.4.tgz#2d1bae173e355996ee355ec9830a7a1ee05457ef" integrity sha512-SVJIQ51spzFDvh4fIbCLvciiDMCrRhlN3mbZvv/+ycjvmF5E73bKdGfU8QDLNmjYJf+lsGnDBC4UUnvTe5OO0w== -pretty-format@^25.2.1, pretty-format@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.2.6.tgz#542a1c418d019bbf1cca2e3620443bc1323cb8d7" - integrity sha512-DEiWxLBaCHneffrIT4B+TpMvkV9RNvvJrd3lY9ew1CEQobDzEXmYT1mg0hJhljZty7kCc10z13ohOFAE8jrUDg== - dependencies: - "@jest/types" "^25.2.6" - ansi-regex "^5.0.0" - ansi-styles "^4.0.0" - react-is "^16.12.0" - -pretty-format@^25.3.0: +pretty-format@^25.2.1, pretty-format@^25.3.0: version "25.3.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.3.0.tgz#d0a4f988ff4a6cd350342fdabbb809aeb4d49ad5" integrity sha512-wToHwF8bkQknIcFkBqNfKu4+UZqnrLn/Vr+wwKQwwvPzkBfDDKp/qIabFqdgtoi5PEnM8LFByVsOrHoa3SpTVA== @@ -4155,14 +4677,14 @@ process-exists@^4.0.0: ps-list "^6.3.0" process-nextick-args@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" - integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== prompts@^2.0.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.3.1.tgz#b63a9ce2809f106fa9ae1277c275b167af46ea05" - integrity sha512-qIP2lQyCwYbdzcqHIUi2HAxiWixhoM9OdLCWf8txXsapC/X9YdsCoeyRIXE/GP+Q0J37Q7+XN/MFqbUa7IzXNA== + version "2.3.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.3.2.tgz#480572d89ecf39566d2bd3fe2c9fccb7c4c0b068" + integrity sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA== dependencies: kleur "^3.0.3" sisteransi "^1.0.4" @@ -4176,6 +4698,11 @@ proper-lockfile@^4.1.1: retry "^0.12.0" signal-exit "^3.0.2" +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= + protobufjs@^5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-5.0.3.tgz#e4dfe9fb67c90b2630d15868249bcc4961467a17" @@ -4187,9 +4714,9 @@ protobufjs@^5.0.3: yargs "^3.10.0" protobufjs@^6.8.6: - version "6.8.8" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c" - integrity sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw== + version "6.8.9" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.9.tgz#0b1adbcdaa983d369c3d9108a97c814edc030754" + integrity sha512-j2JlRdUeL/f4Z6x4aU4gj9I2LECglC+5qR2TrWb193Tla1qfdaNQTZ8I27Pt7K0Ajmvjjpft7O3KWTGciz4gpw== dependencies: "@protobufjs/aspromise" "^1.1.2" "@protobufjs/base64" "^1.1.2" @@ -4206,27 +4733,22 @@ protobufjs@^6.8.6: long "^4.0.0" proxy-addr@~2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34" - integrity sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ== + version "2.0.6" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" + integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== dependencies: forwarded "~0.1.2" - ipaddr.js "1.9.0" + ipaddr.js "1.9.1" ps-list@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/ps-list/-/ps-list-6.3.0.tgz#a2b775c2db7d547a28fbaa3a05e4c281771259be" integrity sha512-qau0czUSB0fzSlBOQt0bo+I2v6R+xiQdj78e1BR/Qjfl5OHWJ/urXi8+ilw1eHe+5hSeDI1wrwVTgDp2wst4oA== -psl@^1.1.24: - version "1.1.32" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.32.tgz#3f132717cf2f9c169724b2b6caf373cf694198db" - integrity sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g== - psl@^1.1.28: - version "1.7.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c" - integrity sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ== + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== pump@^3.0.0: version "3.0.0" @@ -4236,26 +4758,35 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -qs@6.7.0, qs@^6.5.1: +qs@6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== +qs@^6.5.1: + version "6.9.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.3.tgz#bfadcd296c2d549f1dffa560619132c977f5008e" + integrity sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw== + qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" @@ -4282,11 +4813,11 @@ rc@^1.2.7: strip-json-comments "~2.0.1" react-is@^16.12.0: - version "16.13.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.0.tgz#0f37c3613c34fe6b37cd7f763a0d6293ab15c527" - integrity sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA== + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -readable-stream@^2.0.6: +readable-stream@^2.0.0, readable-stream@^2.0.6, readable-stream@^2.3.0, readable-stream@^2.3.5: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -4299,19 +4830,6 @@ readable-stream@^2.0.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== - 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" - realpath-native@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-2.0.0.tgz#7377ac429b6e1fd599dc38d08ed942d0d7beb866" @@ -4356,33 +4874,7 @@ request-promise-native@^1.0.7: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.53.0: - version "2.88.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" - integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.0" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.4.3" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -request@^2.88.0: +request@^2.53.0, request@^2.88.0: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -4447,6 +4939,13 @@ resolve@1.x, resolve@^1.15.1, resolve@^1.3.2: dependencies: path-parse "^1.0.6" +responselike@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -4488,11 +4987,16 @@ rsvp@^4.8.4: resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== -safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + safe-json-stringify@~1: version "1.2.0" resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd" @@ -4549,6 +5053,13 @@ scrypt-js@2.0.4: resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== +seek-bzip@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.5.tgz#cfe917cb3d274bcffac792758af53173eb1fabdc" + integrity sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w= + dependencies: + commander "~2.8.1" + semver@6.x, semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -4643,14 +5154,14 @@ shellwords@^0.1.1: integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== sisteransi@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.4.tgz#386713f1ef688c7c0304dc4c0632898941cad2e3" - integrity sha512-/ekMoM4NJ59ivGSfKapeG+FWtrmWvA1p6FBZwXrqojw90vJu8lBmrTxCMuBCydKtkaUe2zt4PlxeTKpjwMbyig== + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== slash@^3.0.0: version "3.0.0" @@ -4687,6 +5198,27 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" +sort-keys-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" + integrity sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg= + dependencies: + sort-keys "^1.0.0" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= + dependencies: + is-plain-obj "^1.0.0" + +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= + dependencies: + is-plain-obj "^1.0.0" + source-map-resolve@^0.5.0: version "0.5.3" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" @@ -4699,9 +5231,9 @@ source-map-resolve@^0.5.0: urix "^0.1.0" source-map-support@^0.5.6: - version "0.5.12" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" - integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== + version "0.5.16" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" + integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -4763,6 +5295,11 @@ standard-error@^1.1.0: resolved "https://registry.yarnpkg.com/standard-error/-/standard-error-1.1.0.tgz#23e5168fa1c0820189e5812701a79058510d0d34" integrity sha1-I+UWj6HAggGJ5YEnAaeQWFENDTQ= +stat-mode@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-0.1.0.tgz#0cfbec3af29e6059122d2f7efc3e96a8203556a9" + integrity sha1-DPvsOvKeYFkSLS9+/D6WqCA1Vqk= + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -4790,6 +5327,11 @@ streamroller@^2.2.3: debug "^4.1.1" fs-extra "^8.1.0" +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + string-length@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-length/-/string-length-3.1.0.tgz#107ef8c23456e187a8abd4a61162ff4ac6e25837" @@ -4864,6 +5406,13 @@ strip-bom@^4.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== +strip-dirs@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" + integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== + dependencies: + is-natural-number "^4.0.1" + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -4879,6 +5428,13 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= +strip-outer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" + integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg== + dependencies: + escape-string-regexp "^1.0.2" + superagent@^3.7.0: version "3.8.3" resolved "https://registry.yarnpkg.com/superagent/-/superagent-3.8.3.tgz#460ea0dbdb7d5b11bc4f78deba565f86a178e128" @@ -4927,6 +5483,19 @@ tail@^2.0.3: resolved "https://registry.yarnpkg.com/tail/-/tail-2.0.3.tgz#37567adc4624a70b35f1d146c3376fa3d6ef7c04" integrity sha512-s9NOGkLqqiDEtBttQZI7acLS8ycYK5sTlDwNjGnpXG9c8AWj0cfAtwEIzo/hVRMMiC5EYz+bXaJWC1u1u0GPpQ== +tar-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== + dependencies: + 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" + tar@^4.4.2: version "4.4.13" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" @@ -4978,6 +5547,16 @@ throat@^5.0.0: resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== +through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + tmp@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" @@ -4990,6 +5569,11 @@ tmpl@1.0.x: resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= +to-buffer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" + integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -5049,14 +5633,6 @@ tough-cookie@^3.0.1: psl "^1.1.28" punycode "^2.1.1" -tough-cookie@~2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" - integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== - dependencies: - psl "^1.1.24" - punycode "^1.4.1" - tr46@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" @@ -5064,6 +5640,13 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" +trim-repeated@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" + integrity sha1-42RqLqTokTEr9+rObPsFOAvAHCE= + dependencies: + escape-string-regexp "^1.0.2" + ts-jest@^25.3.1: version "25.3.1" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-25.3.1.tgz#58e2ed3506e4e4487c0b9b532846a5cade9656ba" @@ -5143,9 +5726,9 @@ tsutils@^2.29.0: tslib "^1.8.1" tsutils@^3.0.0: - version "3.14.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.14.0.tgz#bf8d5a7bae5369331fa0f2b0a5a10bd7f7396c77" - integrity sha512-SmzGbB0l+8I0QwsPgjooFRaRvHLBLNYM8SeQ0k6rtNDru5sCGeLJcZdwilNndN+GysuFjF5EIYgN8GfFG6UeUw== + version "3.17.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" + integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== dependencies: tslib "^1.8.1" @@ -5203,6 +5786,14 @@ typescript@^3.8.3: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== +unbzip2-stream@^1.0.9: + version "1.4.0" + resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.0.tgz#097ca7b18b5b71e6c8bc8e514a0f1884a12d6eb1" + integrity sha512-kVx7CDAsdBSWVf404Mw7oI9i09w5/mTT/Ruk+RWa64PLYKvsAucLLFHvQtnvjeADM4ZizxrvG5SHnF4Te4T2Cg== + dependencies: + buffer "^5.2.1" + through "^2.3.8" + union-value@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" @@ -5248,6 +5839,18 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" @@ -5274,9 +5877,9 @@ uuid@^3.0.1, uuid@^3.3.2: integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== v8-to-istanbul@^4.0.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-4.1.2.tgz#387d173be5383dbec209d21af033dcb892e3ac82" - integrity sha512-G9R+Hpw0ITAmPSr47lSlc5A1uekSYzXxTMlFxso2xoffwo4jQnzbv1p9yXIinO8UMZKfAFewaCHwWvnH4Jb4Ug== + version "4.1.3" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-4.1.3.tgz#22fe35709a64955f49a08a7c7c959f6520ad6f20" + integrity sha512-sAjOC+Kki6aJVbUOXJbcR0MnbfjvBzwKZazEJymA2IX49uoOdEdk+4fBq5cXgYgiyKtAyrrJNtBZdOeDIF+Fng== dependencies: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" @@ -5297,11 +5900,11 @@ verror@1.10.0: extsprintf "^1.2.0" w3c-hr-time@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" - integrity sha1-gqwr/2PZUOqeMYmlimViX+3xkEU= + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== dependencies: - browser-process-hrtime "^0.1.2" + browser-process-hrtime "^1.0.0" w3c-xmlserializer@^1.1.2: version "1.1.2" @@ -5433,6 +6036,11 @@ xmlhttprequest@1.8.0: resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw= +xtend@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + y18n@^3.2.0: version "3.2.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" @@ -5486,6 +6094,14 @@ yargs@^3.10.0: window-size "^0.1.4" y18n "^3.2.0" +yauzl@^2.4.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" diff --git a/blockchain_nodes/ensure_bitcoind.sh b/blockchain_nodes/ensure_bitcoind.sh deleted file mode 100755 index 8b97fddd0d..0000000000 --- a/blockchain_nodes/ensure_bitcoind.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -set -e - -case "$OSTYPE" in - darwin*) OS="OSX"; url="https://bitcoincore.org/bin/bitcoin-core-0.17.0/bitcoin-0.17.0-osx64.tar.gz";; - linux*) OS="Linux"; url="https://bitcoincore.org/bin/bitcoin-core-0.17.0/bitcoin-0.17.0-x86_64-linux-gnu.tar.gz";; - *) echo "unknown: $OSTYPE. Sorry, this is currently not supported"; exit 1 ;; -esac - - -TARGET_FOLDER=./blockchain_nodes/bitcoin - -if [ ! -d "${TARGET_FOLDER}" ] -then - mkdir -p "${TARGET_FOLDER}" -fi - -TARGET_FILE="${TARGET_FOLDER}/bitcoin-0.17.0" -if [ -d "$TARGET_FILE" ]; then - exit 0; -fi - - -echo "Downloading bitcoind for ${OS}"; -curl -s "$url" | tar xvz -C $TARGET_FOLDER -chmod +x "${TARGET_FILE}/bin/bitcoind" diff --git a/blockchain_nodes/ensure_parity.sh b/blockchain_nodes/ensure_parity.sh deleted file mode 100755 index 944ac5a22f..0000000000 --- a/blockchain_nodes/ensure_parity.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -set -e - - -case "$OSTYPE" in - darwin*) OS="OSX"; url="https://releases.parity.io/ethereum/v2.7.2/x86_64-apple-darwin/parity";; - linux*) OS="Linux"; url="https://releases.parity.io/ethereum/v2.7.2/x86_64-unknown-linux-gnu/parity";; - *) echo "unknown: $OSTYPE. Sorry, this is currently not supported"; exit 1 ;; -esac - -TARGET_FOLDER=./blockchain_nodes/parity - -if [ ! -d "${TARGET_FOLDER}" ] -then - mkdir -p "${TARGET_FOLDER}" -fi - -TARGET_FILE="${TARGET_FOLDER}/parity" -if [ -f "$TARGET_FILE" ]; then - exit 0; -fi - -echo "Downloading parity for ${OS}"; -curl -s "$url" -o $TARGET_FILE -chmod +x $TARGET_FILE From 92d633852aad60c386ce868a92173b04dd355589 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 19 Mar 2020 15:24:36 +1100 Subject: [PATCH 72/88] Make ParityInstance automatically create the necessary configuration Instead of keep the configuration around all the time, messing up the source tree, we create it one demand when running the instance for the test, same as we do for bitcoind. This allows us to completely delete the blockchain_nodes directory. --- api_tests/.prettierignore | 1 + api_tests/src/ledgers/parity_instance.ts | 266 ++++++++++++++++-- api_tests/src/test_environment.ts | 2 +- .../share/io.parity.ethereum/chain.json | 129 --------- .../DevelopmentChain/network/nodes.json | 4 - .../chains/DevelopmentChain/user_defaults | 1 - .../keys/DevelopmentChain/address_book.json | 1 - .../keys/DevelopmentChain/authority.pwd | 1 - .../share/io.parity.ethereum/chains/ver.lock | 1 - .../share/io.parity.ethereum/config.toml | 26 -- .../keys/DevelopmentChain/address_book.json | 1 - .../keys/DevelopmentChain/authority.json | 22 -- .../DevelopmentChain/address_book.json | 1 - .../share/io.parity.ethereum/network/key | 1 - .../DevelopmentChain/address_book.json | 1 - .../home/parity/authorities/authority.pwd | 1 - 16 files changed, 248 insertions(+), 211 deletions(-) delete mode 100644 blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chain.json delete mode 100644 blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/DevelopmentChain/network/nodes.json delete mode 100644 blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/DevelopmentChain/user_defaults delete mode 100644 blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/keys/DevelopmentChain/address_book.json delete mode 100644 blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/keys/DevelopmentChain/authority.pwd delete mode 100644 blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/ver.lock delete mode 100644 blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/config.toml delete mode 100644 blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/keys/DevelopmentChain/address_book.json delete mode 100644 blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/keys/DevelopmentChain/authority.json delete mode 100644 blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/network/DevelopmentChain/address_book.json delete mode 100644 blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/network/key delete mode 100644 blockchain_nodes/parity/home/parity/authorities/DevelopmentChain/address_book.json delete mode 100644 blockchain_nodes/parity/home/parity/authorities/authority.pwd diff --git a/api_tests/.prettierignore b/api_tests/.prettierignore index 0ab6eaa5d1..a470274432 100644 --- a/api_tests/.prettierignore +++ b/api_tests/.prettierignore @@ -1,3 +1,4 @@ gen/ dist/ +log/ locks/ diff --git a/api_tests/src/ledgers/parity_instance.ts b/api_tests/src/ledgers/parity_instance.ts index 79df8674e4..dd5091eac5 100644 --- a/api_tests/src/ledgers/parity_instance.ts +++ b/api_tests/src/ledgers/parity_instance.ts @@ -1,10 +1,6 @@ import { ChildProcess, spawn } from "child_process"; -import * as fs from "fs"; -import tmp from "tmp"; import waitForLogMessage from "../wait_for_log_message"; -import { promisify } from "util"; -import { writeFileAsync } from "../utils"; -import { existsAsync } from "../utils"; +import { existsAsync, mkdirAsync, writeFileAsync } from "../utils"; import getPort from "get-port"; import { Logger } from "log4js"; import { LedgerInstance } from "./index"; @@ -12,22 +8,20 @@ import findCacheDir from "find-cache-dir"; import download from "download"; import { platform } from "os"; import chmod from "chmod"; - -const openAsync = promisify(fs.open); +import * as path from "path"; export class ParityInstance implements LedgerInstance { private process: ChildProcess; - private dbDir: any; public static async new( projectRoot: string, - logFile: string, + dataDir: string, pidFile: string, logger: Logger ) { return new ParityInstance( projectRoot, - logFile, + dataDir, pidFile, logger, await getPort({ port: 8545 }), @@ -37,7 +31,7 @@ export class ParityInstance implements LedgerInstance { constructor( private readonly projectRoot: string, - private readonly logFile: string, + private readonly dataDir: string, private readonly pidFile: string, private readonly logger: Logger, public readonly rpcPort: number, @@ -49,29 +43,32 @@ export class ParityInstance implements LedgerInstance { this.logger.info("Using binary", bin); - this.dbDir = tmp.dirSync(); + await this.createConfigurationFiles(); this.process = spawn( bin, [ `--force-direct`, `--no-download`, - `--config=${this.projectRoot}/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/config.toml`, - `--chain=${this.projectRoot}/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chain.json`, - `--base-path=${this.projectRoot}/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum`, - `--db-path=${this.dbDir.name}`, - `--password=${this.projectRoot}/blockchain_nodes/parity/home/parity/authorities/authority.pwd`, + `--base-path=${this.dataDir}`, + `--config=${this.configTomlPath}`, + `--chain=${this.chainJsonPath}`, + `--log-file=${this.logFilePath}`, + `--password=${this.authorityPwdPath}`, + `--logging=own_tx=trace,sync=debug,rpc=trace,mining=trace`, `--jsonrpc-port=${this.rpcPort}`, `--port=${this.p2pPort}`, `--no-ws`, + `--no-ipc`, + `--unsafe-expose`, ], { cwd: this.projectRoot, stdio: [ "ignore", // stdin - await openAsync(this.logFile, "w"), // stdout - await openAsync(this.logFile, "w"), // stderr + "ignore", // stdout + "ignore", // stderr ], } ); @@ -85,7 +82,7 @@ export class ParityInstance implements LedgerInstance { ); }); - await waitForLogMessage(this.logFile, "Public node URL:"); + await waitForLogMessage(this.logFilePath, "Public node URL:"); this.logger.info("parity started with PID", this.process.pid); @@ -94,6 +91,57 @@ export class ParityInstance implements LedgerInstance { }); } + private async createConfigurationFiles() { + await ParityInstance.writeFile(this.configTomlPath, CONFIG_TOML); + await ParityInstance.writeFile(this.authorityJsonPath, AUTHORITY_JSON); + await ParityInstance.writeFile(this.authorityKeyPath, AUTHORITY_KEY); + await ParityInstance.writeFile(this.chainJsonPath, CHAIN_JSON); + await ParityInstance.writeFile(this.authorityPwdPath, AUTHORITY_PWD); + } + + /** + * Writes the given string to the given path, creating the necessary directory structure while doing so. + * @param pathToFile + * @param content + */ + private static async writeFile(pathToFile: string, content: string) { + const { dir } = path.parse(pathToFile); + await mkdirAsync(dir, { recursive: true }); + + await writeFileAsync(pathToFile, content, { + encoding: "utf-8", + }); + } + + private get logFilePath() { + return path.join(this.dataDir, "parity.log"); + } + + private get authorityPwdPath() { + return path.join(this.dataDir, "authority.pwd"); + } + + private get chainJsonPath() { + return path.join(this.dataDir, "chain.json"); + } + + private get authorityKeyPath() { + return path.join(this.dataDir, "network", "key"); + } + + private get authorityJsonPath() { + return path.join( + this.dataDir, + "keys", + "DevelopmentChain", + "authority.json" + ); + } + + private get configTomlPath() { + return path.join(this.dataDir, "config.toml"); + } + private async findBinary(version: string): Promise { const envOverride = process.env.PARITY_BIN; @@ -159,3 +207,181 @@ function downloadUrl(version: string) { throw new Error(`Unsupported platform ${platform()}`); } } + +const AUTHORITY_JSON = `{ + "id": "0902d04b-f26e-5c1f-e3ae-78d2c1cb16e7", + "version": 3, + "crypto": { + "cipher": "aes-128-ctr", + "cipherparams": { + "iv": "6a829fe7bc656d85f6c2e9fd21784952" + }, + "ciphertext": "1bfec0b054a648af8fdd0e85662206c65a4af0ed15fede4ad41ca9ab7b504ce2", + "kdf": "pbkdf2", + "kdfparams": { + "c": 10240, + "dklen": 32, + "prf": "hmac-sha256", + "salt": "95f96b5ee22dd537e06076eb8d7078eb7275d29af935782fe476696b11be50e5" + }, + "mac": "4af2215c3cd9447a5b0512d7d1c3ea5a4435981e1c8f48bf71d7a49c0e5b4986" + }, + "address": "00bd138abd70e2f00903268f3db08f2d25677c9e", + "name": "Authority0", + "meta": "{}" +}`; + +const AUTHORITY_KEY = + "b3244c104fb56d28d3979f6cd14a8b5cf5b109171d293f4454c97c173a9f9374\n"; +const AUTHORITY_PWD = "node0"; + +const CHAIN_JSON = `{ + "name": "DevelopmentChain", + "engine": { + "authorityRound": { + "params": { + "stepDuration": "1", + "immediateTransitions": true, + "maximumEmptySteps": 1000000000, + "validators": { + "list": ["0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e"] + }, + "maximumUncleCount": 1000000000 + } + } + }, + "params": { + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x0", + "networkID": "0x11", + "gasLimitBoundDivisor": "0x400", + "eip155Transition": 0, + "eip140Transition": 0, + "eip211Transition": 0, + "eip214Transition": 0, + "eip658Transition": 0, + "wasmActivationTransition": 0, + "eip145Transition": 0, + "maxTransactionSize": 1000000000, + "maxCodeSize": 4294967295 + }, + "genesis": { + "seal": { + "authorityRound": { + "step": "0x0", + "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x20000", + "gasLimit": "0x165A0BC00" + }, + "accounts": { + "0x0000000000000000000000000000000000000001": { + "balance": "1", + "builtin": { + "name": "ecrecover", + "pricing": { + "linear": { + "base": 3000, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000002": { + "balance": "1", + "builtin": { + "name": "sha256", + "pricing": { + "linear": { + "base": 60, + "word": 12 + } + } + } + }, + "0x0000000000000000000000000000000000000003": { + "balance": "1", + "builtin": { + "name": "ripemd160", + "pricing": { + "linear": { + "base": 600, + "word": 120 + } + } + } + }, + "0x0000000000000000000000000000000000000004": { + "balance": "1", + "builtin": { + "name": "identity", + "pricing": { + "linear": { + "base": 15, + "word": 3 + } + } + } + }, + "0x0000000000000000000000000000000000000005": { + "builtin": { + "name": "modexp", + "activate_at": 5067000, + "pricing": { + "modexp": { + "divisor": 20 + } + } + } + }, + "0x0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", + "activate_at": 5067000, + "pricing": { + "linear": { + "base": 500, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", + "activate_at": 5067000, + "pricing": { + "linear": { + "base": 40000, + "word": 0 + } + } + } + }, + "0x00a329c0648769a73afac7f9381e08fb43dbea72": { + "balance": "1606938044258990275541962092341162602522202993782792835301376" + } + } +}`; + +const CONFIG_TOML = ` +[rpc] +disable = false +interface = "all" +cors = ["all"] +hosts = ["all"] +apis = ["web3", "eth", "net", "parity", "traces", "rpc", "personal", "parity_accounts", "signer", "parity_set"] + +[mining] +engine_signer = "0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e" +reseal_on_txs = "none" +reseal_min_period = 1000 +reseal_max_period = 5000 +gas_floor_target = "0x165A0BC00" +tx_queue_size = 16384 +tx_queue_mem_limit = 4096 +tx_queue_per_sender = 16384 +usd_per_tx = "0" +force_sealing= true +`; diff --git a/api_tests/src/test_environment.ts b/api_tests/src/test_environment.ts index 2fcfbc5023..c612933d80 100644 --- a/api_tests/src/test_environment.ts +++ b/api_tests/src/test_environment.ts @@ -204,7 +204,7 @@ export default class TestEnvironment extends NodeEnvironment { const parity = await ParityInstance.new( this.projectRoot, - path.join(this.logDir, "parity.log"), + await this.global.getDataDir("parity"), path.join(lockDir, "parity.pid"), this.logger ); diff --git a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chain.json b/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chain.json deleted file mode 100644 index d7203a1440..0000000000 --- a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chain.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "name": "DevelopmentChain", - "engine": { - "authorityRound": { - "params": { - "stepDuration": "1", - "immediateTransitions": true, - "maximumEmptySteps": 1000000000, - "validators": { - "list": ["0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e"] - }, - "maximumUncleCount": 1000000000 - } - } - }, - "params": { - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x0", - "networkID": "0x11", - "gasLimitBoundDivisor": "0x400", - "eip155Transition": 0, - "eip140Transition": 0, - "eip211Transition": 0, - "eip214Transition": 0, - "eip658Transition": 0, - "wasmActivationTransition": 0, - "eip145Transition": 0, - "maxTransactionSize": 1000000000, - "maxCodeSize": 4294967295 - }, - "genesis": { - "seal": { - "authorityRound": { - "step": "0x0", - "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x20000", - "gasLimit": "0x165A0BC00" - }, - "accounts": { - "0x0000000000000000000000000000000000000001": { - "balance": "1", - "builtin": { - "name": "ecrecover", - "pricing": { - "linear": { - "base": 3000, - "word": 0 - } - } - } - }, - "0x0000000000000000000000000000000000000002": { - "balance": "1", - "builtin": { - "name": "sha256", - "pricing": { - "linear": { - "base": 60, - "word": 12 - } - } - } - }, - "0x0000000000000000000000000000000000000003": { - "balance": "1", - "builtin": { - "name": "ripemd160", - "pricing": { - "linear": { - "base": 600, - "word": 120 - } - } - } - }, - "0x0000000000000000000000000000000000000004": { - "balance": "1", - "builtin": { - "name": "identity", - "pricing": { - "linear": { - "base": 15, - "word": 3 - } - } - } - }, - "0x0000000000000000000000000000000000000005": { - "builtin": { - "name": "modexp", - "activate_at": 5067000, - "pricing": { - "modexp": { - "divisor": 20 - } - } - } - }, - "0x0000000000000000000000000000000000000006": { - "builtin": { - "name": "alt_bn128_add", - "activate_at": 5067000, - "pricing": { - "linear": { - "base": 500, - "word": 0 - } - } - } - }, - "0x0000000000000000000000000000000000000007": { - "builtin": { - "name": "alt_bn128_mul", - "activate_at": 5067000, - "pricing": { - "linear": { - "base": 40000, - "word": 0 - } - } - } - }, - "0x00a329c0648769a73afac7f9381e08fb43dbea72": { - "balance": "1606938044258990275541962092341162602522202993782792835301376" - } - } -} diff --git a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/DevelopmentChain/network/nodes.json b/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/DevelopmentChain/network/nodes.json deleted file mode 100644 index 69959ae8c9..0000000000 --- a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/DevelopmentChain/network/nodes.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "nodes": [ - ] -} diff --git a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/DevelopmentChain/user_defaults b/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/DevelopmentChain/user_defaults deleted file mode 100644 index 2d61d4168c..0000000000 --- a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/DevelopmentChain/user_defaults +++ /dev/null @@ -1 +0,0 @@ -{"is_first_launch":false,"pruning":"fast","tracing":false,"fat_db":false,"mode":"active"} \ No newline at end of file diff --git a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/keys/DevelopmentChain/address_book.json b/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/keys/DevelopmentChain/address_book.json deleted file mode 100644 index 9e26dfeeb6..0000000000 --- a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/keys/DevelopmentChain/address_book.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/keys/DevelopmentChain/authority.pwd b/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/keys/DevelopmentChain/authority.pwd deleted file mode 100644 index ce118daada..0000000000 --- a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/keys/DevelopmentChain/authority.pwd +++ /dev/null @@ -1 +0,0 @@ -node0 diff --git a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/ver.lock b/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/ver.lock deleted file mode 100644 index e128db9d67..0000000000 --- a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/chains/ver.lock +++ /dev/null @@ -1 +0,0 @@ -2.5.12 \ No newline at end of file diff --git a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/config.toml b/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/config.toml deleted file mode 100644 index 5cf99a55bf..0000000000 --- a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/config.toml +++ /dev/null @@ -1,26 +0,0 @@ -[rpc] -disable = false -interface = "all" -cors = ["all"] -hosts = ["all"] -apis = ["web3", "eth", "net", "parity", "traces", "rpc", "personal", "parity_accounts", "signer", "parity_set"] - -[mining] -engine_signer = "0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e" -reseal_on_txs = "none" -reseal_min_period = 1000 -reseal_max_period = 5000 -gas_floor_target = "0x165A0BC00" -tx_queue_size = 16384 -tx_queue_mem_limit = 4096 -tx_queue_per_sender = 16384 -usd_per_tx = "0" -force_sealing= true - -[misc] -logging = "own_tx=trace,sync=debug,rpc=trace,mining=trace" -color = true -unsafe_expose = true - -[ipc] -disable = true diff --git a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/keys/DevelopmentChain/address_book.json b/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/keys/DevelopmentChain/address_book.json deleted file mode 100644 index 9e26dfeeb6..0000000000 --- a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/keys/DevelopmentChain/address_book.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/keys/DevelopmentChain/authority.json b/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/keys/DevelopmentChain/authority.json deleted file mode 100644 index dbe6388bfd..0000000000 --- a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/keys/DevelopmentChain/authority.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "id": "0902d04b-f26e-5c1f-e3ae-78d2c1cb16e7", - "version": 3, - "crypto": { - "cipher": "aes-128-ctr", - "cipherparams": { - "iv": "6a829fe7bc656d85f6c2e9fd21784952" - }, - "ciphertext": "1bfec0b054a648af8fdd0e85662206c65a4af0ed15fede4ad41ca9ab7b504ce2", - "kdf": "pbkdf2", - "kdfparams": { - "c": 10240, - "dklen": 32, - "prf": "hmac-sha256", - "salt": "95f96b5ee22dd537e06076eb8d7078eb7275d29af935782fe476696b11be50e5" - }, - "mac": "4af2215c3cd9447a5b0512d7d1c3ea5a4435981e1c8f48bf71d7a49c0e5b4986" - }, - "address": "00bd138abd70e2f00903268f3db08f2d25677c9e", - "name": "Authority0", - "meta": "{}" -} diff --git a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/network/DevelopmentChain/address_book.json b/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/network/DevelopmentChain/address_book.json deleted file mode 100644 index 9e26dfeeb6..0000000000 --- a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/network/DevelopmentChain/address_book.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/network/key b/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/network/key deleted file mode 100644 index 4ca292b496..0000000000 --- a/blockchain_nodes/parity/home/parity/.local/share/io.parity.ethereum/network/key +++ /dev/null @@ -1 +0,0 @@ -b3244c104fb56d28d3979f6cd14a8b5cf5b109171d293f4454c97c173a9f9374 diff --git a/blockchain_nodes/parity/home/parity/authorities/DevelopmentChain/address_book.json b/blockchain_nodes/parity/home/parity/authorities/DevelopmentChain/address_book.json deleted file mode 100644 index 9e26dfeeb6..0000000000 --- a/blockchain_nodes/parity/home/parity/authorities/DevelopmentChain/address_book.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/blockchain_nodes/parity/home/parity/authorities/authority.pwd b/blockchain_nodes/parity/home/parity/authorities/authority.pwd deleted file mode 100644 index ce118daada..0000000000 --- a/blockchain_nodes/parity/home/parity/authorities/authority.pwd +++ /dev/null @@ -1 +0,0 @@ -node0 From 791e7763eb49c2aa8110f4d3cb96961782a4e794 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 19 Mar 2020 16:46:52 +1100 Subject: [PATCH 73/88] Don't pass around the projectRoot variable Resolving paths in different places is problematic because it makes the system brittle. Instead, paths should only be resolved in a central place and independently of each other. With the blockchain nodes being cached in a specific location, the only need for passing around the projectRoot is to resolve the cargo target directory. Computing that from the projectRoot is actually also prone to be wrong if we ever decide to change where the e2e tests are placed. To be resilient against those kind of changes, we use the `cargo metadata` subcommand to know, where the target directory is. --- api_tests/src/actors/actor.ts | 4 +- api_tests/src/cnd/cnd_instance.ts | 7 ++-- api_tests/src/create_actors.ts | 2 +- api_tests/src/ledgers/bitcoind_instance.ts | 5 +-- api_tests/src/ledgers/parity_instance.ts | 11 +----- api_tests/src/test_environment.ts | 45 +++++++++++----------- api_tests/src/utils.ts | 2 +- 7 files changed, 34 insertions(+), 42 deletions(-) diff --git a/api_tests/src/actors/actor.ts b/api_tests/src/actors/actor.ts index 93bf8c8166..7dd58334c9 100644 --- a/api_tests/src/actors/actor.ts +++ b/api_tests/src/actors/actor.ts @@ -39,7 +39,7 @@ export class Actor { public static async newInstance( name: ActorNames, ledgerConfig: LedgerConfig, - projectRoot: string, + cargoTargetDirectory: string, cndLogFile: string, logger: Logger ) { @@ -47,7 +47,7 @@ export class Actor { const cndConfigFile = actorConfig.generateCndConfigFile(ledgerConfig); const cndInstance = new CndInstance( - projectRoot, + cargoTargetDirectory, cndLogFile, logger, cndConfigFile diff --git a/api_tests/src/cnd/cnd_instance.ts b/api_tests/src/cnd/cnd_instance.ts index 7326442097..eb3cf6af6f 100644 --- a/api_tests/src/cnd/cnd_instance.ts +++ b/api_tests/src/cnd/cnd_instance.ts @@ -7,6 +7,7 @@ import { CndConfigFile } from "../config"; import { sleep } from "../utils"; import waitForLogMessage from "../wait_for_log_message"; import { Logger } from "log4js"; +import path from "path"; const openAsync = promisify(fs.open); @@ -14,7 +15,7 @@ export class CndInstance { private process: ChildProcess; constructor( - private readonly projectRoot: string, + private readonly cargoTargetDirectory: string, private readonly logFile: string, private readonly logger: Logger, private readonly configFile: CndConfigFile @@ -27,7 +28,7 @@ export class CndInstance { public async start() { const bin = process.env.CND_BIN ? process.env.CND_BIN - : this.projectRoot + "/target/debug/cnd"; + : path.join(this.cargoTargetDirectory, "debug", "cnd"); this.logger.info("Using binary", bin); @@ -37,7 +38,7 @@ export class CndInstance { ); this.process = spawn(bin, ["--config", configFile], { - cwd: this.projectRoot, + cwd: this.cargoTargetDirectory, stdio: [ "ignore", // stdin await openAsync(this.logFile, "w"), // stdout diff --git a/api_tests/src/create_actors.ts b/api_tests/src/create_actors.ts index 1d71a308d4..b0ff688cac 100644 --- a/api_tests/src/create_actors.ts +++ b/api_tests/src/create_actors.ts @@ -19,7 +19,7 @@ export async function createActors( Actor.newInstance( name, global.ledgerConfigs, - global.projectRoot, + global.cargoTargetDir, cndLogFile, actorLogger ) diff --git a/api_tests/src/ledgers/bitcoind_instance.ts b/api_tests/src/ledgers/bitcoind_instance.ts index 8cc1883ebe..9483639a1f 100644 --- a/api_tests/src/ledgers/bitcoind_instance.ts +++ b/api_tests/src/ledgers/bitcoind_instance.ts @@ -16,13 +16,11 @@ export class BitcoindInstance implements LedgerInstance { private password: string; public static async new( - projectRoot: string, dataDir: string, pidFile: string, logger: Logger ): Promise { return new BitcoindInstance( - projectRoot, dataDir, pidFile, logger, @@ -34,7 +32,6 @@ export class BitcoindInstance implements LedgerInstance { } constructor( - private readonly projectRoot: string, private readonly dataDir: string, private readonly pidFile: string, private readonly logger: Logger, @@ -52,7 +49,7 @@ export class BitcoindInstance implements LedgerInstance { await this.createConfigFile(this.dataDir); this.process = spawn(bin, [`-datadir=${this.dataDir}`], { - cwd: this.projectRoot, + cwd: this.dataDir, stdio: "ignore", }); diff --git a/api_tests/src/ledgers/parity_instance.ts b/api_tests/src/ledgers/parity_instance.ts index dd5091eac5..ec0ebc4609 100644 --- a/api_tests/src/ledgers/parity_instance.ts +++ b/api_tests/src/ledgers/parity_instance.ts @@ -13,14 +13,8 @@ import * as path from "path"; export class ParityInstance implements LedgerInstance { private process: ChildProcess; - public static async new( - projectRoot: string, - dataDir: string, - pidFile: string, - logger: Logger - ) { + public static async new(dataDir: string, pidFile: string, logger: Logger) { return new ParityInstance( - projectRoot, dataDir, pidFile, logger, @@ -30,7 +24,6 @@ export class ParityInstance implements LedgerInstance { } constructor( - private readonly projectRoot: string, private readonly dataDir: string, private readonly pidFile: string, private readonly logger: Logger, @@ -64,7 +57,7 @@ export class ParityInstance implements LedgerInstance { ], { - cwd: this.projectRoot, + cwd: this.dataDir, stdio: [ "ignore", // stdin "ignore", // stdout diff --git a/api_tests/src/test_environment.ts b/api_tests/src/test_environment.ts index c612933d80..eee0af2f50 100644 --- a/api_tests/src/test_environment.ts +++ b/api_tests/src/test_environment.ts @@ -1,5 +1,6 @@ import { Config } from "@jest/types"; import { + execAsync, existsAsync, HarnessGlobal, mkdirAsync, @@ -23,14 +24,16 @@ import { ParityInstance } from "./ledgers/parity_instance"; import { LndInstance } from "./ledgers/lnd_instance"; export default class TestEnvironment extends NodeEnvironment { - private readonly projectRoot: string; private readonly testSuite: string; private readonly ledgers: string[]; + private readonly logDir: string; + private readonly locksDir: string; + private readonly nodeModulesBinDir: string; + private readonly srcDir: string; public global: HarnessGlobal; private logger: Logger; - private logDir: string; constructor(config: Config.ProjectConfig, context: EnvironmentContext) { super(config); @@ -38,19 +41,30 @@ export default class TestEnvironment extends NodeEnvironment { this.ledgers = TestEnvironment.extractLedgersToBeStarted( context.docblockPragmas ); - this.projectRoot = path.resolve(config.rootDir, ".."); + this.logDir = path.resolve(config.rootDir, "log"); + this.locksDir = path.resolve(config.rootDir, "locks"); + this.nodeModulesBinDir = path.resolve( + config.rootDir, + "node_modules", + ".bin" + ); + this.srcDir = path.resolve(config.rootDir, "src"); this.testSuite = path.parse(context.testPath).name; } async setup() { await super.setup(); + const cargoTargetDir = await execAsync( + "cargo metadata --format-version=1 --no-deps" + ) + .then(({ stdout }) => JSON.parse(stdout)) + .then((metadata) => metadata.target_directory); + // setup global variables - this.global.projectRoot = this.projectRoot; this.global.ledgerConfigs = {}; this.global.lndWallets = {}; - - this.logDir = path.join(this.projectRoot, "api_tests", "log"); + this.global.cargoTargetDir = cargoTargetDir; const log4js = configure({ appenders: { @@ -149,7 +163,6 @@ export default class TestEnvironment extends NodeEnvironment { const release = await ledgerLock(lockDir); const bitcoind = await BitcoindInstance.new( - this.projectRoot, await this.global.getDataDir("bitcoind"), path.join(lockDir, "bitcoind.pid"), this.logger @@ -165,19 +178,8 @@ export default class TestEnvironment extends NodeEnvironment { const minerAlreadyRunning = await existsAsync(minerPidFile); if (!minerAlreadyRunning) { - const tsNode = path.join( - this.projectRoot, - "api_tests", - "node_modules", - ".bin", - "ts-node" - ); - const minerProgram = path.join( - this.projectRoot, - "api_tests", - "src", - "bitcoin_miner.ts" - ); + const tsNode = path.join(this.nodeModulesBinDir, "ts-node"); + const minerProgram = path.join(this.srcDir, "bitcoin_miner.ts"); await BitcoinMinerInstance.start( tsNode, @@ -203,7 +205,6 @@ export default class TestEnvironment extends NodeEnvironment { const release = await ledgerLock(lockDir); const parity = await ParityInstance.new( - this.projectRoot, await this.global.getDataDir("parity"), path.join(lockDir, "parity.pid"), this.logger @@ -372,7 +373,7 @@ export default class TestEnvironment extends NodeEnvironment { } private async getLockDirectory(process: string): Promise { - const dir = path.join(this.projectRoot, "api_tests", "locks", process); + const dir = path.join(this.locksDir, process); await mkdirAsync(dir, { recursive: true, diff --git a/api_tests/src/utils.ts b/api_tests/src/utils.ts index e2a2d46f12..9885b09fb6 100644 --- a/api_tests/src/utils.ts +++ b/api_tests/src/utils.ts @@ -20,9 +20,9 @@ export interface HarnessGlobal extends Global.Global { alice?: LightningWallet; bob?: LightningWallet; }; - projectRoot: string; tokenContract: string; parityLockDir: string; + cargoTargetDir: string; getDataDir: (program: string) => Promise; getLogFile: (pathElements: string[]) => string; From e6fc2daf2635cab3aff347045702f1e24d819c8d Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 8 Apr 2020 18:48:08 +1000 Subject: [PATCH 74/88] Add a walking skeleton for the halight-based swaps To make the skeleton walk, we opted to only support swaps from han-ethereum-ether to halight-lightning-bitcoin. --- .circleci/config.yml | 4 +- .github/workflows/ci.yml | 4 +- Cargo.lock | 4 +- api_tests/src/actors/actor.ts | 121 ++- api_tests/src/actors/defaults.ts | 132 ---- api_tests/src/actors/swap_factory.ts | 228 ++++++ api_tests/src/config.ts | 2 +- api_tests/src/test_environment.ts | 9 +- api_tests/src/wallets/index.ts | 3 +- api_tests/src/wallets/lightning.ts | 7 +- api_tests/tests/ether_halight.ts | 37 + api_tests/tests/lightning_routes.ts | 31 +- cnd/Cargo.toml | 8 +- cnd/src/asset.rs | 2 + cnd/src/asset/ethereum/ether.rs | 4 + cnd/src/asset/lightning.rs | 45 ++ cnd/src/http_api.rs | 65 +- cnd/src/http_api/action.rs | 163 +++- cnd/src/http_api/problem.rs | 9 +- cnd/src/http_api/route_factory.rs | 57 +- cnd/src/http_api/routes.rs | 545 ++++++++++++- cnd/src/http_api/routes/index.rs | 71 +- cnd/src/lib.rs | 1 + cnd/src/lnd.rs | 448 +++++++++++ cnd/src/main.rs | 41 +- cnd/src/network.rs | 67 +- cnd/src/network/comit_ln.rs | 723 ++++++++++++++++++ cnd/src/network/protocols/announce.rs | 15 +- cnd/src/seed.rs | 17 +- cnd/src/swap_protocols.rs | 46 +- cnd/src/swap_protocols/actions.rs | 61 +- cnd/src/swap_protocols/facade2.rs | 112 +++ cnd/src/swap_protocols/halight.rs | 226 ++++++ cnd/src/swap_protocols/han.rs | 131 ++++ cnd/src/swap_protocols/ledger.rs | 1 + cnd/src/swap_protocols/ledger/lightning.rs | 8 + cnd/src/swap_protocols/rfc003/actions.rs | 12 +- .../swap_protocols/rfc003/actions/bitcoin.rs | 14 +- .../swap_protocols/rfc003/actions/erc20.rs | 8 +- .../swap_protocols/rfc003/actions/ether.rs | 20 +- .../rfc003/alice/actions/erc20.rs | 26 +- .../rfc003/alice/actions/generic_impl.rs | 24 +- .../rfc003/bob/actions/erc20.rs | 26 +- .../rfc003/bob/actions/generic_impl.rs | 24 +- cnd/src/swap_protocols/rfc003/ethereum.rs | 4 +- .../rfc003/ethereum/htlc_events.rs | 14 +- cnd/src/swap_protocols/swap_id.rs | 37 + cnd/src/timestamp.rs | 4 + 48 files changed, 3353 insertions(+), 308 deletions(-) create mode 100644 api_tests/src/actors/swap_factory.ts create mode 100644 api_tests/tests/ether_halight.ts create mode 100644 cnd/src/asset/lightning.rs create mode 100644 cnd/src/lnd.rs create mode 100644 cnd/src/network/comit_ln.rs create mode 100644 cnd/src/swap_protocols/facade2.rs create mode 100644 cnd/src/swap_protocols/halight.rs create mode 100644 cnd/src/swap_protocols/han.rs create mode 100644 cnd/src/swap_protocols/ledger/lightning.rs diff --git a/.circleci/config.yml b/.circleci/config.yml index 9ef46f3769..2f483e0258 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -94,7 +94,7 @@ commands: install_lnd: steps: - run: - name: "Install go 1.13 & lnd" + name: "Install go 1.13 & lnd v0.9.1-beta" command: | sudo rm -rf /usr/local/go wget https://dl.google.com/go/go1.13.3.linux-amd64.tar.gz @@ -102,7 +102,7 @@ commands: unset GOPATH go get -d github.com/lightningnetwork/lnd cd ~/go/src/github.com/lightningnetwork/lnd - git checkout v0.9.0-beta + git checkout v0.9.1-beta make tags=invoicesrpc && make tags=invoicesrpc install echo 'export PATH=$HOME/.cargo/bin:$HOME/.local/bin:$HOME/go/bin:$PATH' >> $BASH_ENV print_current_versions: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 650fe5be2c..c6138699a0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -114,11 +114,11 @@ jobs: with: go-version: '1.13.3' - - name: Install LND v0.9.0-beta + - name: Install LND v0.9.1-beta run: | go get -d github.com/lightningnetwork/lnd cd ~/go/src/github.com/lightningnetwork/lnd - git checkout v0.9.0-beta + git checkout v0.9.1-beta make tags=invoicesrpc make tags=invoicesrpc install diff --git a/Cargo.lock b/Cargo.lock index a903703b85..63c91c4ca6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -506,7 +506,6 @@ dependencies = [ "libsqlite3-sys", "log 0.4.8", "lru", - "multihash", "num 0.2.1", "paste", "pem", @@ -1099,6 +1098,7 @@ version = "0.99.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c86bd0361bcbde39b13475e6e36cb24c329964aa2611be285289d1e4b751c1a0" dependencies = [ + "futures-core", "genawaiter-macro", "genawaiter-proc-macro", "proc-macro-hack", @@ -3444,6 +3444,8 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58b0b7fd92dc7b71f29623cc6836dd7200f32161a2313dd78be233a8405694f6" dependencies = [ + "futures", + "futures-task", "pin-project", "tracing", ] diff --git a/api_tests/src/actors/actor.ts b/api_tests/src/actors/actor.ts index 7dd58334c9..448fc8b2c4 100644 --- a/api_tests/src/actors/actor.ts +++ b/api_tests/src/actors/actor.ts @@ -4,11 +4,13 @@ import { Cnd, ComitClient, Entity, + HanEthereumEtherHalightLightningBitcoinRequestBody, LedgerAction, Swap, SwapDetails, - TransactionStatus, Transaction, + TransactionStatus, + Wallets as SdkWallets, } from "comit-sdk"; import { Logger } from "log4js"; import { E2ETestActorConfig } from "../config"; @@ -80,7 +82,7 @@ export class Actor { private readonly expectedBalanceChanges: Map; constructor( - private readonly logger: Logger, + public readonly logger: Logger, private readonly cndInstance: CndInstance, private readonly name: ActorNames ) { @@ -202,6 +204,7 @@ export class Actor { this.logger.debug("Using lightning routes on cnd REST API"); return; } + const comitClient: ComitClient = this.getComitClient(); const payload = { @@ -237,6 +240,80 @@ export class Actor { await this.swap.accept(Actor.defaultActionConfig); } + public async createSwap( + createSwapPayload: HanEthereumEtherHalightLightningBitcoinRequestBody + ) { + this.alphaLedger = { + name: LedgerKind.Ethereum, + chain_id: createSwapPayload.alpha.chain_id, + }; + this.betaLedger = { + name: LedgerKind.Lightning, + network: createSwapPayload.beta.network, + }; + this.alphaAsset = { + name: AssetKind.Ether, + quantity: createSwapPayload.alpha.amount, + ledger: LedgerKind.Ethereum, + }; + this.betaAsset = { + name: AssetKind.Bitcoin, + quantity: createSwapPayload.beta.amount, + ledger: LedgerKind.Lightning, + }; + + switch (this.name) { + case "alice": { + // Alice purchases beta asset with alpha asset + await this.setStartingBalance([ + this.alphaAsset, + { + ...this.betaAsset, + quantity: "0", + }, + ]); + this.expectedBalanceChanges.set( + toKey(this.betaAsset), + new BigNumber(this.betaAsset.quantity) + ); + break; + } + case "bob": { + // Bob purchases alpha asset with beta asset + await this.setStartingBalance([ + this.betaAsset, + { + ...this.alphaAsset, + quantity: "0", + }, + ]); + this.expectedBalanceChanges.set( + toKey(this.alphaAsset), + new BigNumber(this.alphaAsset.quantity) + ); + break; + } + default: { + throw new Error( + `createSwap does not support the actor ${this.name} yet` + ); + } + } + + const location = await this.cnd.createHanEthereumEtherHalightLightningBitcoin( + createSwapPayload + ); + + this.swap = new Swap( + this.cnd, + location, + new SdkWallets({ + ethereum: this.wallets.ethereum.inner, + lightning: this.wallets.lightning.inner, + }) + ); + } + public async deploy() { if (!this.swap) { throw new Error("Cannot deploy htlc for nonexistent swap"); @@ -277,12 +354,32 @@ export class Actor { } } + public async init() { + if (!this.swap) { + throw new Error("Cannot init nonexistent swap"); + } + + const response = await this.swap.tryExecuteSirenAction( + "init", + { + maxTimeoutSecs: 30, + tryIntervalSecs: 1, + } + ); + await this.swap.doLedgerAction(response.data); + } + public async fund() { if (!this.swap) { throw new Error("Cannot fund nonexistent swap"); } const txid = await this.swap.fund(Actor.defaultActionConfig); + + if (txid instanceof Transaction) { + await txid.status(1); + } + this.logger.debug("Funded swap %s in %s", this.swap.self, txid); const role = await this.whoAmI(); @@ -464,6 +561,10 @@ export class Actor { } } + await this.assertBalances(); + } + + public async assertBalances() { for (const [ assetKey, expectedBalanceChange, @@ -669,7 +770,7 @@ export class Actor { } private async assertLedgerState( - ledger: string, + ledger: "alpha_ledger" | "beta_ledger", status: | "NOT_DEPLOYED" | "DEPLOYED" @@ -678,6 +779,20 @@ export class Actor { | "REFUNDED" | "INCORRECTLY_FUNDED" ) { + if ( + ledger === "alpha_ledger" && + this.alphaLedger.name === LedgerKind.Lightning + ) { + return; + } + + if ( + ledger === "beta_ledger" && + this.betaLedger.name === LedgerKind.Lightning + ) { + return; + } + this.logger.debug( "Waiting for cnd to see %s in state %s for swap @ %s", ledger, diff --git a/api_tests/src/actors/defaults.ts b/api_tests/src/actors/defaults.ts index ecd14c98f6..1957b19cbd 100644 --- a/api_tests/src/actors/defaults.ts +++ b/api_tests/src/actors/defaults.ts @@ -1,142 +1,10 @@ import { HarnessGlobal } from "../utils"; -import { - HalightLightningBitcoinHanEthereumEtherRequestBody, - HalightLightningBitcoinHerc20EthereumErc20RequestBody, - HanEthereumEtherHalightLightningBitcoinRequestBody, - Herc20EthereumErc20HalightLightningBitcoinRequestBody, - HanEthereumEtherRequestParams, - HalightLightningBitcoinRequestParams, - Herc20EthereumErc20RequestParams, - Peer, -} from "comit-sdk"; import { Asset, AssetKind } from "../asset"; import { Ledger, LedgerKind } from "../ledgers/ledger"; import { parseEther } from "ethers/utils"; declare var global: HarnessGlobal; -function defaultHanEthereumEtherRequestParams( - absoluteExpiry: number -): HanEthereumEtherRequestParams { - return { - amount: "5000000000000000000", - chain_id: 17, - identity: "0x00a329c0648769a73afac7f9381e08fb43dbea72", - absolute_expiry: absoluteExpiry, - }; -} - -function defaultHalightLightningBitcoinRequestParams( - cltvExpiry: number, - lndPubkey: string -): HalightLightningBitcoinRequestParams { - return { - amount: "10000000", - network: "regtest", - identity: lndPubkey, - cltv_expiry: cltvExpiry, - }; -} - -function defaultHerc20EthereumErc20RequestParams( - absoluteExpiry: number -): Herc20EthereumErc20RequestParams { - return { - amount: "9000000000000000000", - contract_address: "0xB97048628DB6B661D4C2aA833e95Dbe1A905B280", - chain_id: 17, - identity: "0x00a329c0648769a73afac7f9381e08fb43dbea72", - absolute_expiry: absoluteExpiry, - }; -} -export function defaultHanEthereumEtherHalightLightningBitcoin( - lndPubkey: string, - peer: Peer -): HanEthereumEtherHalightLightningBitcoinRequestBody { - const { - alphaAbsoluteExpiry, - betaCltvExpiry, - } = defaultHalightHanHerc20Expiries(); - return { - alpha: defaultHanEthereumEtherRequestParams(alphaAbsoluteExpiry), - beta: defaultHalightLightningBitcoinRequestParams( - betaCltvExpiry, - lndPubkey - ), - role: "Alice", - peer, - }; -} - -export function defaultHerc20EthereumErc20HalightLightningBitcoin( - lndPubkey: string, - peer: Peer -): Herc20EthereumErc20HalightLightningBitcoinRequestBody { - const { - alphaAbsoluteExpiry, - betaCltvExpiry, - } = defaultHalightHanHerc20Expiries(); - return { - alpha: defaultHerc20EthereumErc20RequestParams(alphaAbsoluteExpiry), - beta: defaultHalightLightningBitcoinRequestParams( - betaCltvExpiry, - lndPubkey - ), - role: "Alice", - peer, - }; -} - -export function defaultHalightLightningBitcoinHanEthereumEther( - lndPubkey: string, - peer: Peer -): HalightLightningBitcoinHanEthereumEtherRequestBody { - const { - alphaCltvExpiry, - betaAbsoluteExpiry, - } = defaultHalightHanHerc20Expiries(); - return { - alpha: defaultHalightLightningBitcoinRequestParams( - alphaCltvExpiry, - lndPubkey - ), - beta: defaultHanEthereumEtherRequestParams(betaAbsoluteExpiry), - role: "Alice", - peer, - }; -} - -export function defaultHalightLightningBitcoinHerc20EthereumErc20( - lndPubkey: string, - peer: Peer -): HalightLightningBitcoinHerc20EthereumErc20RequestBody { - const { - alphaCltvExpiry, - betaAbsoluteExpiry, - } = defaultHalightHanHerc20Expiries(); - return { - alpha: defaultHalightLightningBitcoinRequestParams( - alphaCltvExpiry, - lndPubkey - ), - beta: defaultHerc20EthereumErc20RequestParams(betaAbsoluteExpiry), - role: "Alice", - peer, - }; -} - -function defaultHalightHanHerc20Expiries() { - const alphaAbsoluteExpiry = Math.round(Date.now() / 1000) + 8; - const betaAbsoluteExpiry = Math.round(Date.now() / 1000) + 3; - - return { - alphaAbsoluteExpiry, - betaAbsoluteExpiry, - alphaCltvExpiry: 35, - betaCltvExpiry: 35, - }; -} - export function defaultLedgerKindForAsset(asset: AssetKind): LedgerKind { switch (asset) { case AssetKind.Bitcoin: diff --git a/api_tests/src/actors/swap_factory.ts b/api_tests/src/actors/swap_factory.ts new file mode 100644 index 0000000000..8273cdc0b9 --- /dev/null +++ b/api_tests/src/actors/swap_factory.ts @@ -0,0 +1,228 @@ +/* + * Creates swaps for the given actors. + * + * In order for cnd to successfully execute swaps, the parameters (expiry-times etc) need to exactly match. + * Hence, we generate this data in one single place. + * The swap factory is this place. + * + * It is a replacement for a negotiation/order protocol that takes care of this in a real application. + */ +import { Actor } from "./actor"; +import { + AllWallets, + HalightLightningBitcoinHanEthereumEtherRequestBody, + HalightLightningBitcoinHerc20EthereumErc20RequestBody, + HalightLightningBitcoinRequestParams, + HanEthereumEtherHalightLightningBitcoinRequestBody, + HanEthereumEtherRequestParams, + Herc20EthereumErc20HalightLightningBitcoinRequestBody, + Herc20EthereumErc20RequestParams, + Peer, +} from "comit-sdk"; + +export default class SwapFactory { + public static async newSwap( + alice: Actor, + bob: Actor + ): Promise< + [ + HanEthereumEtherHalightLightningBitcoinRequestBody, + HanEthereumEtherHalightLightningBitcoinRequestBody + ] + > { + const ledgers: (keyof AllWallets)[] = ["ethereum", "lightning"]; + + for (const ledger of ledgers) { + await alice.wallets.initializeForLedger( + ledger, + alice.logger, + "alice" + ); + await bob.wallets.initializeForLedger(ledger, bob.logger, "bob"); + } + + const { + alphaAbsoluteExpiry, + betaCltvExpiry, + } = defaultHalightHanHerc20Expiries(); + + const aliceCreateSwapBody = await makeCreateSwapBody( + alice, + "Alice", + bob, + alphaAbsoluteExpiry, + betaCltvExpiry + ); + const bobCreateSwapBody = await makeCreateSwapBody( + bob, + "Bob", + alice, + alphaAbsoluteExpiry, + betaCltvExpiry + ); + + return [aliceCreateSwapBody, bobCreateSwapBody]; + } +} + +async function makeCreateSwapBody( + self: Actor, + cryptoRole: "Alice" | "Bob", + counterparty: Actor, + alphaAbsoluteExpiry: number, + betaCltvExpiry: number +): Promise { + return { + alpha: defaultHanEthereumEtherRequestParams( + alphaAbsoluteExpiry, + self.wallets.ethereum.account() + ), + beta: defaultHalightLightningBitcoinRequestParams( + betaCltvExpiry, + await self.wallets.lightning.inner.getPubkey() + ), + role: cryptoRole, + peer: await makePeer(counterparty), + }; +} + +async function makePeer(actor: Actor): Promise { + return { + peer_id: await actor.cnd.getPeerId(), + address_hint: await actor.cnd + .getPeerListenAddresses() + .then((addresses) => addresses[0]), + }; +} + +function defaultHanEthereumEtherRequestParams( + absoluteExpiry: number, + identity: string +): HanEthereumEtherRequestParams { + return { + amount: "5000000000000000000", + chain_id: 17, + identity, + absolute_expiry: absoluteExpiry, + }; +} + +function defaultHalightLightningBitcoinRequestParams( + cltvExpiry: number, + lndPubkey: string +): HalightLightningBitcoinRequestParams { + return { + amount: "10000", + network: "regtest", + identity: lndPubkey, + cltv_expiry: cltvExpiry, + }; +} + +function defaultHerc20EthereumErc20RequestParams( + absoluteExpiry: number +): Herc20EthereumErc20RequestParams { + return { + amount: "9000000000000000000", + contract_address: "0xB97048628DB6B661D4C2aA833e95Dbe1A905B280", + chain_id: 17, + identity: "0x00a329c0648769a73afac7f9381e08fb43dbea72", + absolute_expiry: absoluteExpiry, + }; +} +export function defaultHanEthereumEtherHalightLightningBitcoin( + lndPubkey: string, + peer: Peer, + role: "Alice" | "Bob", + ethereumIdentity: string +): HanEthereumEtherHalightLightningBitcoinRequestBody { + const { + alphaAbsoluteExpiry, + betaCltvExpiry, + } = defaultHalightHanHerc20Expiries(); + return { + alpha: defaultHanEthereumEtherRequestParams( + alphaAbsoluteExpiry, + ethereumIdentity + ), + beta: defaultHalightLightningBitcoinRequestParams( + betaCltvExpiry, + lndPubkey + ), + role, + peer, + }; +} + +export function defaultHerc20EthereumErc20HalightLightningBitcoin( + lndPubkey: string, + peer: Peer +): Herc20EthereumErc20HalightLightningBitcoinRequestBody { + const { + alphaAbsoluteExpiry, + betaCltvExpiry, + } = defaultHalightHanHerc20Expiries(); + return { + alpha: defaultHerc20EthereumErc20RequestParams(alphaAbsoluteExpiry), + beta: defaultHalightLightningBitcoinRequestParams( + betaCltvExpiry, + lndPubkey + ), + role: "Alice", + peer, + }; +} + +export function defaultHalightLightningBitcoinHanEthereumEther( + lndPubkey: string, + peer: Peer, + ethereumIdentity: string +): HalightLightningBitcoinHanEthereumEtherRequestBody { + const { + alphaCltvExpiry, + betaAbsoluteExpiry, + } = defaultHalightHanHerc20Expiries(); + return { + alpha: defaultHalightLightningBitcoinRequestParams( + alphaCltvExpiry, + lndPubkey + ), + beta: defaultHanEthereumEtherRequestParams( + betaAbsoluteExpiry, + ethereumIdentity + ), + role: "Alice", + peer, + }; +} + +export function defaultHalightLightningBitcoinHerc20EthereumErc20( + lndPubkey: string, + peer: Peer +): HalightLightningBitcoinHerc20EthereumErc20RequestBody { + const { + alphaCltvExpiry, + betaAbsoluteExpiry, + } = defaultHalightHanHerc20Expiries(); + return { + alpha: defaultHalightLightningBitcoinRequestParams( + alphaCltvExpiry, + lndPubkey + ), + beta: defaultHerc20EthereumErc20RequestParams(betaAbsoluteExpiry), + role: "Alice", + peer, + }; +} + +function defaultHalightHanHerc20Expiries() { + const alphaAbsoluteExpiry = Math.round(Date.now() / 1000) + 8; + const betaAbsoluteExpiry = Math.round(Date.now() / 1000) + 3; + + return { + alphaAbsoluteExpiry, + betaAbsoluteExpiry, + alphaCltvExpiry: 350, + betaCltvExpiry: 350, + }; +} diff --git a/api_tests/src/config.ts b/api_tests/src/config.ts index 39672c18eb..54119fc557 100644 --- a/api_tests/src/config.ts +++ b/api_tests/src/config.ts @@ -2,9 +2,9 @@ import * as tmp from "tmp"; import { LedgerConfig } from "./utils"; import getPort from "get-port"; import { + LightningNodeConfig, BitcoinNodeConfig, EthereumNodeConfig, - LightningNodeConfig, } from "./ledgers"; import { ActorNames } from "./actors/actor"; diff --git a/api_tests/src/test_environment.ts b/api_tests/src/test_environment.ts index eee0af2f50..96946d6591 100644 --- a/api_tests/src/test_environment.ts +++ b/api_tests/src/test_environment.ts @@ -260,7 +260,12 @@ export default class TestEnvironment extends NodeEnvironment { private async setupLightningChannels() { const { alice, bob } = this.global.lndWallets; - await alice.connectPeer(bob); + const alicePeers = await alice.listPeers(); + const bobPubkey = await bob.inner.getPubkey(); + + if (!alicePeers.find((peer) => peer.pubKey === bobPubkey)) { + await alice.connectPeer(bob); + } await alice.mint({ name: AssetKind.Bitcoin, @@ -287,6 +292,7 @@ export default class TestEnvironment extends NodeEnvironment { private async startAliceLightning() { const config = await this.initLightningLedger("lnd-alice"); this.global.lndWallets.alice = await this.initLightningWallet(config); + this.global.ledgerConfigs.aliceLnd = config; } /** @@ -298,6 +304,7 @@ export default class TestEnvironment extends NodeEnvironment { private async startBobLightning() { const config = await this.initLightningLedger("lnd-bob"); this.global.lndWallets.bob = await this.initLightningWallet(config); + this.global.ledgerConfigs.bobLnd = config; } private async initLightningWallet(config: LightningNodeConfig) { diff --git a/api_tests/src/wallets/index.ts b/api_tests/src/wallets/index.ts index 9b65a73774..05c511e4d7 100644 --- a/api_tests/src/wallets/index.ts +++ b/api_tests/src/wallets/index.ts @@ -4,6 +4,7 @@ import { BitcoinWallet } from "./bitcoin"; import { EthereumWallet } from "./ethereum"; import { LightningWallet } from "./lightning"; import { Logger } from "log4js"; +import { ActorNames } from "../actors/actor"; declare var global: HarnessGlobal; @@ -50,7 +51,7 @@ export class Wallets { public async initializeForLedger( name: K, logger: Logger, - actor?: string + actor?: ActorNames ) { switch (name) { case "ethereum": diff --git a/api_tests/src/wallets/lightning.ts b/api_tests/src/wallets/lightning.ts index 0bfabdedb5..77abcf8256 100644 --- a/api_tests/src/wallets/lightning.ts +++ b/api_tests/src/wallets/lightning.ts @@ -4,7 +4,7 @@ import BigNumber from "bignumber.js"; import { BitcoinWallet } from "./bitcoin"; import { sleep } from "../utils"; import { LightningWallet as LightningWalletSdk, Outpoint } from "comit-sdk"; -import { AddressType } from "@radar/lnrpc"; +import { AddressType, Peer } from "@radar/lnrpc"; import { Logger } from "log4js"; import { LightningNodeConfig } from "../ledgers"; @@ -92,8 +92,9 @@ export class LightningWallet implements Wallet { return this.inner.lnd.lnrpc.connectPeer({ addr: { pubkey, host } }); } - public async listPeers() { - return this.inner.lnd.lnrpc.listPeers(); + public async listPeers(): Promise { + const response = await this.inner.lnd.lnrpc.listPeers(); + return response.peers ? response.peers : []; } public async getChannels() { diff --git a/api_tests/tests/ether_halight.ts b/api_tests/tests/ether_halight.ts new file mode 100644 index 0000000000..53cf6fa5b7 --- /dev/null +++ b/api_tests/tests/ether_halight.ts @@ -0,0 +1,37 @@ +/** + * @ledger ethereum + * @ledger lightning + */ + +import { twoActorTest } from "../src/actor_test"; +import SwapFactory from "../src/actors/swap_factory"; +import { sleep } from "../src/utils"; + +it( + "han-ethereum-ether-halight-lightning-bitcoin-alice-redeems-bob-redeems", + twoActorTest(async ({ alice, bob }) => { + const [aliceBody, bobBody] = await SwapFactory.newSwap(alice, bob); + + // Bob needs to know about the swap first because he is not buffering incoming announcements about swaps he doesn't know about + await bob.createSwap(bobBody); + await sleep(500); + + await alice.createSwap(aliceBody); + + await alice.init(); + + await alice.fund(); + + // we must not wait for bob's funding because `sendpayment` on a hold-invoice is a blocking call. + // tslint:disable-next-line:no-floating-promises + bob.fund(); + + await alice.redeem(); + await bob.redeem(); + + await sleep(2000); + + await alice.assertBalances(); + await bob.assertBalances(); + }) +); diff --git a/api_tests/tests/lightning_routes.ts b/api_tests/tests/lightning_routes.ts index 33724a5639..7398154ca9 100644 --- a/api_tests/tests/lightning_routes.ts +++ b/api_tests/tests/lightning_routes.ts @@ -4,21 +4,28 @@ import { defaultHalightLightningBitcoinHerc20EthereumErc20, defaultHanEthereumEtherHalightLightningBitcoin, defaultHerc20EthereumErc20HalightLightningBitcoin, -} from "../src/actors/defaults"; +} from "../src/actors/swap_factory"; // ******************************************** // // Lightning routes // // ******************************************** // + describe("Lightning routes tests", () => { it( - "lightning-routes-post-eth-lnbtc-return-400", + "lightning-routes-post-eth-lnbtc-return-201", oneActorTest(async ({ alice }) => { - const promise = alice.cnd.createHanEthereumEtherHalightLightningBitcoin( - defaultHanEthereumEtherHalightLightningBitcoin("", { - peer_id: "", - }) + const body = defaultHanEthereumEtherHalightLightningBitcoin( + "0346093cc4b9010fa3885df8dfcb6015bc2190bc9f46f5935a48df0417eeb7667e", + { + peer_id: "QmXfGiwNESAFWUvDVJ4NLaKYYVopYdV5HbpDSgz5TSypkb", + }, + "Alice", + "0x00a329c0648769a73afac7f9381e08fb43dbea72" ); - await expect(promise).rejects.toThrow("Route not yet supported"); + const location = await alice.cnd.createHanEthereumEtherHalightLightningBitcoin( + body + ); + expect(typeof location).toBe("string"); }) ); @@ -38,9 +45,13 @@ describe("Lightning routes tests", () => { "lightning-routes-post-lnbtc-eth-return-400", oneActorTest(async ({ alice }) => { const promise = alice.cnd.createHalightLightningBitcoinHanEthereumEther( - defaultHalightLightningBitcoinHanEthereumEther("", { - peer_id: "", - }) + defaultHalightLightningBitcoinHanEthereumEther( + "", + { + peer_id: "", + }, + "0x00a329c0648769a73afac7f9381e08fb43dbea72" + ) ); await expect(promise).rejects.toThrow("Route not yet supported"); }) diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index 971973b908..95c92ba235 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -9,6 +9,7 @@ description = "Reference implementation of a COMIT network daemon." ambassador = "0.2" anyhow = "1" async-trait = "0.1" +base64 = "0.12.0" bigdecimal = "0.1.0" bitcoin = { version = "0.23", features = ["use-serde"] } blockchain_contracts = "0.3.1" @@ -24,7 +25,7 @@ ethbloom = "0.9.0" fern = { version = "0.6", features = ["colored"] } fs2 = "0.4.3" futures = { version = "0.3", features = ["async-await"], default-features = false } -genawaiter = "0.99" +genawaiter = { version = "0.99", features = ["futures03"] } hex = "0.4" http-api-problem = { version = "0.15", features = ["with_warp"] } impl-template = "1.0.0-alpha" @@ -36,7 +37,6 @@ libsqlite3-sys = { version = ">=0.8.0, <0.13.0", features = ["bundled"] } log = { version = "0.4", features = ["serde"] } lru = "0.4.3" num = "0.2" -multihash = "0.10" paste = "0.1" pem = "0.7" primitive-types = { version = "0.7.0", features = ["serde"] } @@ -55,9 +55,9 @@ thiserror = "1" tiny-keccak = { version = "2.0", features = ["keccak"] } tokio = { version = "0.2", features = ["rt-threaded", "time", "macros", "sync"] } toml = "0.5" -tracing = "0.1" +tracing = { version = "0.1", features = ["attributes"] } tracing-core = "0.1" -tracing-futures = { version = "0.2", features = ["std-future"] } +tracing-futures = { version = "0.2", features = ["std-future", "futures-03"] } tracing-log = "0.1" tracing-subscriber = "0.2" url = { version = "2", features = ["serde"] } diff --git a/cnd/src/asset.rs b/cnd/src/asset.rs index aa9f323fb7..99f4443a89 100644 --- a/cnd/src/asset.rs +++ b/cnd/src/asset.rs @@ -1,8 +1,10 @@ mod bitcoin; pub mod ethereum; +pub mod lightning; pub use self::{ bitcoin::Bitcoin, ethereum::{Erc20, Erc20Quantity, Ether}, + lightning::Lightning, }; use crate::asset; use derivative::Derivative; diff --git a/cnd/src/asset/ethereum/ether.rs b/cnd/src/asset/ethereum/ether.rs index 4dd2d6a7b9..e929cb223b 100644 --- a/cnd/src/asset/ethereum/ether.rs +++ b/cnd/src/asset/ethereum/ether.rs @@ -45,6 +45,10 @@ impl Ether { let buf = self.0.to_bytes_be(); U256::from_big_endian(&buf) } + + pub fn to_bytes(&self) -> Vec { + self.0.to_bytes_le() + } } impl fmt::Display for Ether { diff --git a/cnd/src/asset/lightning.rs b/cnd/src/asset/lightning.rs new file mode 100644 index 0000000000..9e2c473c4b --- /dev/null +++ b/cnd/src/asset/lightning.rs @@ -0,0 +1,45 @@ +use bitcoin::{util::amount::Denomination, Amount}; +use std::fmt; + +#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)] +pub struct Lightning(Amount); + +impl Lightning { + pub fn from_sat(sat: u64) -> Lightning { + Lightning(Amount::from_sat(sat)) + } + + pub fn as_sat(self) -> u64 { + Amount::as_sat(self.0) + } + + pub fn to_le_bytes(self) -> [u8; 8] { + self.0.as_sat().to_le_bytes() + } +} + +impl From for Amount { + fn from(lightning: Lightning) -> Self { + Amount::from_sat(lightning.as_sat()) + } +} + +impl fmt::Display for Lightning { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + let bitcoin = self.0.to_string_in(Denomination::Bitcoin); + write!(f, "{} BTC", bitcoin) + } +} + +#[cfg(test)] +mod tests { + use crate::asset; + + #[test] + fn display_bitcoin() { + assert_eq!( + asset::Lightning::from_sat(900_000_000_000).to_string(), + "9000.00000000 BTC" + ); + } +} diff --git a/cnd/src/http_api.rs b/cnd/src/http_api.rs index 81c1e8a41b..d9607a194f 100644 --- a/cnd/src/http_api.rs +++ b/cnd/src/http_api.rs @@ -10,6 +10,7 @@ pub use self::{ problem::*, swap_resource::{OnFail, SwapParameters, SwapResource, SwapStatus}, }; +use crate::swap_protocols::actions::lnd::Chain; pub const PATH: &str = "swaps"; @@ -18,7 +19,7 @@ use crate::{ network::DialInformation, swap_protocols::{ ledger::{self, bitcoin::Network, ethereum::ChainId, Bitcoin}, - SwapId, SwapProtocol, + Role, SwapId, SwapProtocol, }, transaction, }; @@ -37,6 +38,12 @@ use std::{ #[derive(Clone, Debug, PartialEq)] pub struct Http(pub I); +impl From for Http { + fn from(inner: I) -> Self { + Http(inner) + } +} + impl Deref for Http { type Target = I; @@ -45,6 +52,28 @@ impl Deref for Http { } } +impl Serialize for Http { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(&self.0.to_string()) + } +} + +impl<'de> Deserialize<'de> for Http { + fn deserialize(deserializer: D) -> Result>::Error> + where + D: Deserializer<'de>, + { + let role = String::deserialize(deserializer)?; + let role = + Role::from_str(role.as_str()).map_err(>::Error::custom)?; + + Ok(Http(role)) + } +} + impl Serialize for Http { fn serialize(&self, serializer: S) -> Result where @@ -68,6 +97,29 @@ impl<'de> Deserialize<'de> for Http { } } +impl Serialize for Http { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(&self.0.as_sat().to_string()) + } +} + +impl<'de> Deserialize<'de> for Http { + fn deserialize(deserializer: D) -> Result>::Error> + where + D: Deserializer<'de>, + { + let value = String::deserialize(deserializer)?; + let value = + u64::from_str(value.as_str()).map_err(>::Error::custom)?; + let amount = asset::Lightning::from_sat(value); + + Ok(Http(amount)) + } +} + impl Serialize for Http { fn serialize(&self, serializer: S) -> Result where @@ -96,6 +148,17 @@ impl Serialize for Http { } } +impl Serialize for Http { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match &self.0 { + Chain::Bitcoin => serializer.serialize_str("bitcoin"), + } + } +} + impl_serialize_type_with_fields!(htlc_location::Bitcoin { "txid" => txid, "vout" => vout }); impl_serialize_http!(crate::ethereum::Address); impl_serialize_http!(SwapId); diff --git a/cnd/src/http_api/action.rs b/cnd/src/http_api/action.rs index 32aafd31a5..654d9d621e 100644 --- a/cnd/src/http_api/action.rs +++ b/cnd/src/http_api/action.rs @@ -5,9 +5,12 @@ use crate::{ swap_protocols::{ actions::{ bitcoin::{SendToAddress, SpendOutput}, - ethereum, + ethereum, lnd, + lnd::Chain, }, - ledger, SwapId, + ledger, + rfc003::{Secret, SecretHash}, + SwapId, }, timestamp::Timestamp, transaction, @@ -67,6 +70,30 @@ pub enum ActionResponseBody { #[serde(skip_serializing_if = "Option::is_none")] min_block_timestamp: Option, }, + LndAddHoldInvoice { + amount: Http, + secret_hash: SecretHash, + expiry: u32, + cltv_expiry: u32, + chain: Http, + network: Http, + self_public_key: identity::Lightning, + }, + LndSendPayment { + to_public_key: identity::Lightning, + amount: Http, + secret_hash: SecretHash, + final_cltv_delta: u32, + chain: Http, + network: Http, + self_public_key: identity::Lightning, + }, + LndSettleInvoice { + secret: Secret, + chain: Http, + network: Http, + self_public_key: identity::Lightning, + }, None, } @@ -129,6 +156,110 @@ impl From for ActionResponseBody { } } +impl From for ActionResponseBody { + fn from(action: lnd::AddHoldInvoice) -> Self { + let lnd::AddHoldInvoice { + amount, + secret_hash, + expiry, + cltv_expiry, + chain, + network, + self_public_key, + } = action; + + ActionResponseBody::LndAddHoldInvoice { + amount: Http(amount), + secret_hash, + expiry, + cltv_expiry, + chain: Http(chain), + network: Http(network), + self_public_key, + } + } +} + +impl From for ActionResponseBody { + fn from(action: ethereum::DeployContract) -> Self { + let ethereum::DeployContract { + amount, + chain_id, + gas_limit, + data, + } = action; + + ActionResponseBody::EthereumDeployContract { + data, + amount, + gas_limit: gas_limit.into(), + chain_id, + } + } +} + +impl From for ActionResponseBody { + fn from(action: lnd::SendPayment) -> Self { + let lnd::SendPayment { + to_public_key, + amount, + secret_hash, + network, + chain, + final_cltv_delta, + self_public_key, + } = action; + + ActionResponseBody::LndSendPayment { + to_public_key, + amount: amount.into(), + secret_hash, + network: network.into(), + chain: chain.into(), + final_cltv_delta, + self_public_key, + } + } +} + +impl From for ActionResponseBody { + fn from(action: lnd::SettleInvoice) -> Self { + let lnd::SettleInvoice { + secret, + chain, + network, + self_public_key, + } = action; + + ActionResponseBody::LndSettleInvoice { + secret, + chain: chain.into(), + network: network.into(), + self_public_key, + } + } +} + +impl From for ActionResponseBody { + fn from(action: ethereum::CallContract) -> Self { + let ethereum::CallContract { + to, + data, + gas_limit, + chain_id, + min_block_timestamp, + } = action; + + ActionResponseBody::EthereumCallContract { + contract_address: to, + data, + gas_limit: gas_limit.into(), + chain_id, + min_block_timestamp, + } + } +} + impl ListRequiredFields for SendToAddress { fn list_required_fields() -> Vec { vec![] @@ -232,19 +363,8 @@ impl IntoResponsePayload for ethereum::DeployContract { self, query_params: ActionExecutionParameters, ) -> anyhow::Result { - let ethereum::DeployContract { - data, - amount, - gas_limit, - chain_id, - } = self; match query_params { - ActionExecutionParameters::None {} => Ok(ActionResponseBody::EthereumDeployContract { - data, - amount, - gas_limit, - chain_id, - }), + ActionExecutionParameters::None {} => Ok(self.into()), _ => Err(anyhow::Error::from(UnexpectedQueryParameters { action: "ethereum::ContractDeploy", parameters: &["address", "fee_per_wu"], @@ -264,21 +384,8 @@ impl IntoResponsePayload for ethereum::CallContract { self, query_params: ActionExecutionParameters, ) -> anyhow::Result { - let ethereum::CallContract { - to, - data, - gas_limit, - chain_id, - min_block_timestamp, - } = self; match query_params { - ActionExecutionParameters::None {} => Ok(ActionResponseBody::EthereumCallContract { - contract_address: to, - data, - gas_limit, - chain_id, - min_block_timestamp, - }), + ActionExecutionParameters::None {} => Ok(self.into()), _ => Err(anyhow::Error::from(UnexpectedQueryParameters { action: "ethereum::SendTransaction", parameters: &["address", "fee_per_wu"], diff --git a/cnd/src/http_api/problem.rs b/cnd/src/http_api/problem.rs index b2da894ebf..b7fbd0c38a 100644 --- a/cnd/src/http_api/problem.rs +++ b/cnd/src/http_api/problem.rs @@ -1,7 +1,8 @@ use crate::{ db, - http_api::routes::rfc003::handlers::{ - post_swap::UnsupportedSwap, InvalidAction, InvalidActionInvocation, + http_api::routes::{ + rfc003::handlers::{post_swap::UnsupportedSwap, InvalidAction, InvalidActionInvocation}, + LndActionError, }, }; use http_api_problem::HttpApiProblem; @@ -102,6 +103,10 @@ pub fn from_anyhow(e: anyhow::Error) -> HttpApiProblem { .set_detail("The requested combination of ledgers and assets is not supported."); } + if e.is::() { + return HttpApiProblem::new("Action not found.").set_status(StatusCode::NOT_FOUND); + } + tracing::error!("internal error occurred: {:#}", e); HttpApiProblem::with_title_and_type_from_status(StatusCode::INTERNAL_SERVER_ERROR) diff --git a/cnd/src/http_api/route_factory.rs b/cnd/src/http_api/route_factory.rs index aed055bb7f..ef025f2e4a 100644 --- a/cnd/src/http_api/route_factory.rs +++ b/cnd/src/http_api/route_factory.rs @@ -2,7 +2,7 @@ use crate::{ config::settings::AllowedOrigins, http_api, network::LocalPeerId, - swap_protocols::{self, Facade, SwapId}, + swap_protocols::{self, Facade, Facade2, NodeLocalSwapId, SwapId}, }; use warp::{self, filters::BoxedFilter, Filter, Reply}; @@ -18,6 +18,7 @@ pub fn new_action_link(id: &SwapId, action: &str) -> String { pub fn create( dependencies: Facade, + facade2: Facade2, allowed_origins: &AllowedOrigins, ) -> BoxedFilter<(impl Reply,)> { let peer_id = dependencies.local_peer_id(); @@ -26,6 +27,7 @@ pub fn create( let peer_id = warp::any().map(move || peer_id.clone()); let empty_json_body = warp::any().map(|| serde_json::json!({})); let dependencies = warp::any().map(move || dependencies.clone()); + let facade2 = warp::any().map(move || facade2.clone()); let cors = warp::cors() .allow_methods(vec!["GET", "POST"]) @@ -91,13 +93,14 @@ pub fn create( .and(dependencies) .and_then(http_api::routes::index::get_info); - let han_ether_halight_bitcoin = swaps + let han_ether_halight_bitcoin = warp::post() .and(warp::path!( - "han" / "ethereum" / "ether" / "halight" / "lightning" / "bitcoin" + "swaps" / "han" / "ethereum" / "ether" / "halight" / "lightning" / "bitcoin" )) - .and(warp::post()) .and(warp::path::end()) - .and_then(http_api::routes::index::post_lightning_route); + .and(warp::body::json()) + .and(facade2.clone()) + .and_then(http_api::routes::index::post_lightning_route_new); let herc20_erc20_halight_bitcoin = swaps .and(warp::path!( @@ -123,6 +126,45 @@ pub fn create( .and(warp::path::end()) .and_then(http_api::routes::index::post_lightning_route); + let get_halight_swap = swaps + .and(warp::get()) + .and(warp::path::param()) + .and(warp::path::end()) + .and(facade2.clone()) + .and_then(http_api::routes::get_han_halight_swap); + + let lighting_action_init = swaps + .and(warp::get()) + .and(warp::path::param::()) + .and(warp::path("init")) + .and(warp::path::end()) + .and(facade2.clone()) + .and_then(http_api::routes::action_init); + + let lighting_action_fund = swaps + .and(warp::get()) + .and(warp::path::param::()) + .and(warp::path("fund")) + .and(warp::path::end()) + .and(facade2.clone()) + .and_then(http_api::routes::action_fund); + + let lighting_action_redeem = swaps + .and(warp::get()) + .and(warp::path::param::()) + .and(warp::path("redeem")) + .and(warp::path::end()) + .and(facade2.clone()) + .and_then(http_api::routes::action_redeem); + + let lighting_action_refund = swaps + .and(warp::get()) + .and(warp::path::param::()) + .and(warp::path("refund")) + .and(warp::path::end()) + .and(facade2) + .and_then(http_api::routes::action_refund); + preflight_cors_route .or(rfc003_get_swap) .or(rfc003_post_swap) @@ -135,6 +177,11 @@ pub fn create( .or(herc20_erc20_halight_bitcoin) .or(halight_bitcoin_han_ether) .or(halight_bitcoin_herc20_erc20) + .or(get_halight_swap) + .or(lighting_action_init) + .or(lighting_action_fund) + .or(lighting_action_redeem) + .or(lighting_action_refund) .recover(http_api::unpack_problem) .with(warp::log("http")) .with(cors) diff --git a/cnd/src/http_api/routes.rs b/cnd/src/http_api/routes.rs index 9a3b1acf99..c33874071c 100644 --- a/cnd/src/http_api/routes.rs +++ b/cnd/src/http_api/routes.rs @@ -1,10 +1,549 @@ -use http_api_problem::HttpApiProblem; -use warp::Rejection; - pub mod index; pub mod peers; pub mod rfc003; +use crate::{ + asset, + ethereum::Bytes, + htlc_location, + http_api::{action::ActionResponseBody, problem}, + network::comit_ln, + swap_protocols::{ + actions::{ + ethereum, + lnd::{self, Chain}, + }, + halight::{self, data}, + ledger::ethereum::ChainId, + rfc003::LedgerState, + state::Get, + Facade2, FundAction, InitAction, NodeLocalSwapId, RedeemAction, RefundAction, Role, SwapId, + }, + transaction, +}; +use blockchain_contracts::ethereum::rfc003::ether_htlc::EtherHtlc; +use http_api_problem::HttpApiProblem; +use warp::{http, Rejection, Reply}; + pub fn into_rejection(problem: HttpApiProblem) -> Rejection { warp::reject::custom(problem) } + +#[allow(clippy::needless_pass_by_value)] +pub async fn get_han_halight_swap( + id: NodeLocalSwapId, + facade: Facade2, +) -> Result { + handle_get_han_halight_swap(facade, id) + .await + .map(|swap_resource| warp::reply::json(&swap_resource)) + .map_err(problem::from_anyhow) + .map_err(into_rejection) +} + +pub async fn handle_get_han_halight_swap( + facade: Facade2, + local_id: NodeLocalSwapId, +) -> anyhow::Result { + let swap_id = SwapId(local_id.0); + + // This is ok, we use a new create_watcher in han.rs and call it with local id. + let alpha_ledger_state: Option< + LedgerState, + > = facade.alpha_ledger_state.get(&swap_id).await?; + + // And again here, we munge the swap_id when calling create_watcher. + let beta_ledger_state = facade.beta_ledger_state.get(&swap_id).await?; + + let finalized_swap = facade.get_finalized_swap(local_id).await; + + let (alpha_ledger_state, beta_ledger_state, finalized_swap) = + match (alpha_ledger_state, beta_ledger_state, finalized_swap) { + (Some(alpha_ledger_state), Some(beta_ledger_state), Some(finalized_swap)) => { + (alpha_ledger_state, beta_ledger_state, finalized_swap) + } + _ => { + let empty_swap = make_swap_entity(swap_id, vec![]); + + tracing::debug!( + "returning empty siren document because states are not yet completed" + ); + + return Ok(empty_swap); + } + }; + + let entity = match finalized_swap.role { + Role::Alice => { + let state = AliceEthLnState { + alpha_ledger_state, + beta_ledger_state, + finalized_swap, + }; + + let maybe_action_names = vec![ + state.init_action().map(|_| "init"), + state.fund_action().map(|_| "fund"), + state.redeem_action().map(|_| "redeem"), + state.refund_action().map(|_| "refund"), + ]; + + make_swap_entity(swap_id, maybe_action_names) + } + Role::Bob => { + let state = BobEthLnState { + alpha_ledger_state, + beta_ledger_state, + finalized_swap, + }; + + // Bob cannot init and refund in this swap combination + let maybe_action_names = vec![ + state.fund_action().map(|_| "fund"), + state.redeem_action().map(|_| "redeem"), + ]; + + make_swap_entity(swap_id, maybe_action_names) + } + }; + + Ok(entity) +} + +fn make_swap_entity(swap_id: SwapId, maybe_action_names: Vec>) -> siren::Entity { + let swap = siren::Entity::default().with_class_member("swap"); + + maybe_action_names + .into_iter() + .filter_map(|action| action) + .fold(swap, |acc, action_name| { + let siren_action = make_siren_action(swap_id, action_name); + + acc.with_action(siren_action) + }) +} + +fn make_siren_action(swap_id: SwapId, action_name: &str) -> siren::Action { + siren::Action { + name: action_name.to_owned(), + class: vec![], + method: Some(http::Method::GET), + href: format!("/swaps/{}/{}", swap_id, action_name), + title: None, + _type: None, + fields: vec![], + } +} + +#[derive(Debug)] +pub struct AliceEthLnState { + pub alpha_ledger_state: + LedgerState, + pub beta_ledger_state: halight::State, + pub finalized_swap: comit_ln::FinalizedSwap, +} + +#[derive(Debug)] +pub struct BobEthLnState { + pub alpha_ledger_state: + LedgerState, + pub beta_ledger_state: halight::State, + pub finalized_swap: comit_ln::FinalizedSwap, +} + +impl InitAction for AliceEthLnState { + type Output = lnd::AddHoldInvoice; + + fn init_action(&self) -> Option { + match self.beta_ledger_state { + halight::State::Unknown => { + let amount = self.finalized_swap.beta_asset; + let secret_hash = self.finalized_swap.secret_hash; + let expiry = 3600; + let cltv_expiry = self.finalized_swap.beta_expiry.into(); + let chain = Chain::Bitcoin; + let network = bitcoin::Network::Regtest; + let self_public_key = self.finalized_swap.beta_ledger_redeem_identity; + + Some(lnd::AddHoldInvoice { + amount, + secret_hash, + expiry, + cltv_expiry, + chain, + network, + self_public_key, + }) + } + _ => None, + } + } +} + +impl FundAction for AliceEthLnState { + type Output = ethereum::DeployContract; + + fn fund_action(&self) -> Option { + match self.beta_ledger_state { + halight::State::Opened(_) => { + let eth_htlc = self.finalized_swap.han_params(); + let data = eth_htlc.into(); + let amount = self.finalized_swap.alpha_asset.clone(); + let gas_limit = EtherHtlc::deploy_tx_gas_limit(); + let chain_id = ChainId::regtest(); + + Some(ethereum::DeployContract { + data, + amount, + gas_limit, + chain_id, + }) + } + _ => None, + } + } +} + +impl RedeemAction for AliceEthLnState { + type Output = lnd::SettleInvoice; + + fn redeem_action(&self) -> Option { + match self.beta_ledger_state { + halight::State::Accepted(_) => { + let secret = self.finalized_swap.secret.unwrap(); // unwrap ok since only Alice calls this. + let chain = Chain::Bitcoin; + let network = bitcoin::Network::Regtest; + let self_public_key = self.finalized_swap.beta_ledger_redeem_identity; + + Some(lnd::SettleInvoice { + secret, + chain, + network, + self_public_key, + }) + } + _ => None, + } + } +} + +impl RefundAction for AliceEthLnState { + type Output = ethereum::CallContract; + + fn refund_action(&self) -> Option { + match (&self.alpha_ledger_state, &self.beta_ledger_state) { + (LedgerState::Funded { htlc_location, .. }, halight::State::Accepted(_)) => { + let to = *htlc_location; + let data = None; + let gas_limit = EtherHtlc::refund_tx_gas_limit(); + let chain_id = ChainId::regtest(); + let min_block_timestamp = Some(self.finalized_swap.alpha_expiry); + + Some(ethereum::CallContract { + to, + data, + gas_limit, + chain_id, + min_block_timestamp, + }) + } + _ => None, + } + } +} + +impl FundAction for BobEthLnState { + type Output = lnd::SendPayment; + + fn fund_action(&self) -> Option { + match (&self.alpha_ledger_state, &self.beta_ledger_state) { + (LedgerState::Funded { .. }, halight::State::Opened(_)) => { + let to_public_key = self.finalized_swap.beta_ledger_redeem_identity; + let amount = self.finalized_swap.beta_asset; + let secret_hash = self.finalized_swap.secret_hash; + let final_cltv_delta = self.finalized_swap.beta_expiry.into(); + let chain = Chain::Bitcoin; + let network = bitcoin::Network::Regtest; + let self_public_key = self.finalized_swap.beta_ledger_refund_identity; + + Some(lnd::SendPayment { + to_public_key, + amount, + secret_hash, + final_cltv_delta, + chain, + network, + self_public_key, + }) + } + _ => None, + } + } +} + +impl RedeemAction for BobEthLnState { + type Output = ethereum::CallContract; + + fn redeem_action(&self) -> Option { + match (&self.alpha_ledger_state, &self.beta_ledger_state) { + ( + LedgerState::Funded { htlc_location, .. }, + halight::State::Settled(data::Settled { secret }), + ) => { + let to = *htlc_location; + let data = Some(Bytes::from(secret.into_raw_secret().to_vec())); + let gas_limit = EtherHtlc::redeem_tx_gas_limit(); + let chain_id: ChainId = ChainId::regtest(); + let min_block_timestamp = None; + + Some(ethereum::CallContract { + to, + data, + gas_limit, + chain_id, + min_block_timestamp, + }) + } + _ => None, + } + } +} + +#[allow(clippy::needless_pass_by_value)] +pub async fn action_init(id: NodeLocalSwapId, facade: Facade2) -> Result { + handle_action_init(id, facade) + .await + .map(|body| warp::reply::json(&body)) + .map_err(problem::from_anyhow) + .map_err(into_rejection) +} + +#[allow(clippy::unit_arg, clippy::let_unit_value, clippy::cognitive_complexity)] +async fn handle_action_init( + local_id: NodeLocalSwapId, + facade: Facade2, +) -> anyhow::Result { + let id = SwapId(local_id.0); + + let alpha_ledger_state: LedgerState< + asset::Ether, + htlc_location::Ethereum, + transaction::Ethereum, + > = facade + .alpha_ledger_state + .get(&id) + .await? + .ok_or_else(|| anyhow::anyhow!("alpha ledger state not found for {}", id))?; + + let beta_ledger_state: halight::State = facade + .beta_ledger_state + .get(&id) + .await? + .ok_or_else(|| anyhow::anyhow!("beta ledger state not found for {}", id))?; + + let finalized_swap = facade + .get_finalized_swap(local_id) + .await + .ok_or_else(|| anyhow::anyhow!("swap with id {} not found", id))?; + + let maybe_response = match finalized_swap.role { + Role::Alice => { + let state = AliceEthLnState { + alpha_ledger_state, + beta_ledger_state, + finalized_swap, + }; + + state.init_action().map(ActionResponseBody::from) + } + Role::Bob => None, + }; + + let response = maybe_response.ok_or(LndActionError::NotFound)?; + + Ok(response) +} + +#[allow(clippy::needless_pass_by_value)] +pub async fn action_fund(id: NodeLocalSwapId, facade: Facade2) -> Result { + handle_action_fund(id, facade) + .await + .map(|body| warp::reply::json(&body)) + .map_err(problem::from_anyhow) + .map_err(into_rejection) +} + +#[allow(clippy::unit_arg, clippy::let_unit_value, clippy::cognitive_complexity)] +async fn handle_action_fund( + local_id: NodeLocalSwapId, + facade: Facade2, +) -> anyhow::Result { + let id = SwapId(local_id.0); + let alpha_ledger_state: LedgerState< + asset::Ether, + htlc_location::Ethereum, + transaction::Ethereum, + > = facade + .alpha_ledger_state + .get(&id) + .await? + .ok_or_else(|| anyhow::anyhow!("alpha ledger state not found for {}", id))?; + + let beta_ledger_state: halight::State = facade + .beta_ledger_state + .get(&id) + .await? + .ok_or_else(|| anyhow::anyhow!("beta ledger state not found for {}", id))?; + + let finalized_swap = facade + .get_finalized_swap(local_id) + .await + .ok_or_else(|| anyhow::anyhow!("swap with id {} not found", id))?; + + let maybe_response = match finalized_swap.role { + Role::Alice => { + let state = AliceEthLnState { + alpha_ledger_state, + beta_ledger_state, + finalized_swap, + }; + + state.fund_action().map(ActionResponseBody::from) + } + Role::Bob => { + let state = BobEthLnState { + alpha_ledger_state, + beta_ledger_state, + finalized_swap, + }; + + state.fund_action().map(ActionResponseBody::from) + } + }; + + let response = maybe_response.ok_or(LndActionError::NotFound)?; + + Ok(response) +} + +#[allow(clippy::needless_pass_by_value)] +pub async fn action_redeem(id: NodeLocalSwapId, facade: Facade2) -> Result { + handle_action_redeem(id, facade) + .await + .map(|body| warp::reply::json(&body)) + .map_err(problem::from_anyhow) + .map_err(into_rejection) +} + +#[allow(clippy::unit_arg, clippy::let_unit_value, clippy::cognitive_complexity)] +async fn handle_action_redeem( + local_id: NodeLocalSwapId, + facade: Facade2, +) -> anyhow::Result { + let id = SwapId(local_id.0); + let alpha_ledger_state: LedgerState< + asset::Ether, + htlc_location::Ethereum, + transaction::Ethereum, + > = facade + .alpha_ledger_state + .get(&id) + .await? + .ok_or_else(|| anyhow::anyhow!("alpha ledger state not found for {}", id))?; + + let beta_ledger_state: halight::State = facade + .beta_ledger_state + .get(&id) + .await? + .ok_or_else(|| anyhow::anyhow!("beta ledger state not found for {}", id))?; + + let finalized_swap = facade + .get_finalized_swap(local_id) + .await + .ok_or_else(|| anyhow::anyhow!("swap with id {} not found", id))?; + + let maybe_response = match finalized_swap.role { + Role::Alice => { + let state = AliceEthLnState { + alpha_ledger_state, + beta_ledger_state, + finalized_swap, + }; + + state.redeem_action().map(ActionResponseBody::from) + } + Role::Bob => { + let state = BobEthLnState { + alpha_ledger_state, + beta_ledger_state, + finalized_swap, + }; + + state.redeem_action().map(ActionResponseBody::from) + } + }; + + let response = maybe_response.ok_or(LndActionError::NotFound)?; + + Ok(response) +} + +#[allow(clippy::needless_pass_by_value)] +pub async fn action_refund(id: NodeLocalSwapId, facade: Facade2) -> Result { + handle_action_refund(id, facade) + .await + .map(|body| warp::reply::json(&body)) + .map_err(problem::from_anyhow) + .map_err(into_rejection) +} + +#[allow(clippy::unit_arg, clippy::let_unit_value, clippy::cognitive_complexity)] +async fn handle_action_refund( + local_id: NodeLocalSwapId, + facade: Facade2, +) -> anyhow::Result { + let id = SwapId(local_id.0); + let alpha_ledger_state: LedgerState< + asset::Ether, + htlc_location::Ethereum, + transaction::Ethereum, + > = facade + .alpha_ledger_state + .get(&id) + .await? + .ok_or_else(|| anyhow::anyhow!("alpha ledger state not found for {}", id))?; + + let beta_ledger_state: halight::State = facade + .beta_ledger_state + .get(&id) + .await? + .ok_or_else(|| anyhow::anyhow!("beta ledger state not found for {}", id))?; + + let finalized_swap = facade + .get_finalized_swap(local_id) + .await + .ok_or_else(|| anyhow::anyhow!("swap with id {} not found", id))?; + + let maybe_response = match finalized_swap.role { + Role::Alice => { + let state = AliceEthLnState { + alpha_ledger_state, + beta_ledger_state, + finalized_swap, + }; + + state.refund_action().map(ActionResponseBody::from) + } + _ => None, + }; + + let response = maybe_response.ok_or(LndActionError::NotFound)?; + + Ok(response) +} + +#[derive(Debug, Clone, Copy, thiserror::Error)] +pub enum LndActionError { + #[error("action not found")] + NotFound, +} diff --git a/cnd/src/http_api/routes/index.rs b/cnd/src/http_api/routes/index.rs index bd2e1a864a..ae85c8ad6a 100644 --- a/cnd/src/http_api/routes/index.rs +++ b/cnd/src/http_api/routes/index.rs @@ -2,13 +2,15 @@ mod handlers; use self::handlers::handle_get_swaps; use crate::{ + asset, http_api::{problem, routes::into_rejection, Http}, - network::ListenAddresses, - swap_protocols::Facade, + identity, + network::{DialInformation, ListenAddresses}, + swap_protocols::{CreateSwapParams, Facade, Facade2, NodeLocalSwapId, Role}, }; use http_api_problem::HttpApiProblem; use libp2p::{Multiaddr, PeerId}; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use warp::{http::StatusCode, Rejection, Reply}; #[derive(Serialize, Debug)] @@ -77,3 +79,66 @@ pub async fn post_lightning_route() -> Result { .set_detail("This route is not yet supported."), )) } + +#[allow(clippy::needless_pass_by_value)] +pub async fn post_lightning_route_new( + body: serde_json::Value, + facade: Facade2, +) -> Result { + let body = Body::deserialize(&body) + .map_err(anyhow::Error::new) + .map_err(problem::from_anyhow) + .map_err(warp::reject::custom)?; + + let reply = warp::reply::reply(); + + let id = NodeLocalSwapId::default(); + + facade.save(id, ()).await; + + facade.initiate_communication(id, body.into()).await; + + Ok(warp::reply::with_status( + warp::reply::with_header(reply, "Location", format!("/swaps/{}", id)), + StatusCode::CREATED, + )) +} + +#[derive(serde::Deserialize, Clone, Debug)] +pub struct Body { + pub alpha: HanEthereumEther, + pub beta: HalightLightningBitcoin, + pub peer: DialInformation, + pub role: Http, +} + +impl From for CreateSwapParams { + fn from(body: Body) -> Self { + Self { + role: body.role.0, + peer: body.peer, + ethereum_identity: body.alpha.identity.into(), + ethereum_absolute_expiry: body.alpha.absolute_expiry.into(), + ethereum_amount: body.alpha.amount, + lightning_identity: body.beta.identity, + lightning_cltv_expiry: body.beta.cltv_expiry.into(), + lightning_amount: body.beta.amount.0, + } + } +} + +#[derive(serde::Deserialize, Clone, Debug)] +pub struct HanEthereumEther { + pub amount: asset::Ether, + pub identity: identity::Ethereum, + pub chain_id: u32, + pub absolute_expiry: u32, +} + +#[derive(serde::Deserialize, Clone, Debug)] +pub struct HalightLightningBitcoin { + pub amount: Http, + pub identity: identity::Lightning, + pub network: String, + pub cltv_expiry: u32, +} diff --git a/cnd/src/lib.rs b/cnd/src/lib.rs index 41f51a2df2..4911759d07 100644 --- a/cnd/src/lib.rs +++ b/cnd/src/lib.rs @@ -38,6 +38,7 @@ pub mod ethereum; pub mod http_api; pub mod init_swap; pub mod lightning; +pub mod lnd; pub mod load_swaps; #[macro_use] pub mod network; diff --git a/cnd/src/lnd.rs b/cnd/src/lnd.rs new file mode 100644 index 0000000000..d9eb02be65 --- /dev/null +++ b/cnd/src/lnd.rs @@ -0,0 +1,448 @@ +use crate::swap_protocols::{ + halight::{data, Accepted, Cancelled, Opened, Params, Settled}, + rfc003::{Secret, SecretHash}, +}; +use anyhow::{Context, Error}; +use reqwest::{ + header::{HeaderMap, HeaderValue}, + StatusCode, Url, +}; +use serde::Deserialize; +use std::{ + convert::{TryFrom, TryInto}, + io::Read, + path::PathBuf, + time::Duration, +}; + +/// Invoice states. These mirror the invoice states used by lnd. +// ref: https://api.lightning.community/#invoicestate +#[derive(Clone, Copy, Debug, Deserialize, PartialEq, strum_macros::Display)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +enum InvoiceState { + Open, + Settled, + Cancelled, + Accepted, +} + +/// Payment status. These mirror the payment status' used by lnd. +// ref: https://api.lightning.community/#paymentstatus +#[derive(Copy, Clone, Debug, Deserialize, PartialEq)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +enum PaymentStatus { + Unknown, + InFlight, + Succeeded, + Failed, +} + +#[derive(Debug, Deserialize)] +struct Invoice { + pub value: String, + pub value_msat: String, + pub amt_paid_sat: String, + pub amt_paid_msat: String, + pub expiry: String, + pub cltv_expiry: String, + pub state: InvoiceState, + pub r_preimage: Option, +} + +#[derive(Clone, Debug, Deserialize)] +struct PaymentsResponse { + payments: Option>, +} + +#[derive(Clone, Debug, Deserialize)] +struct Payment { + pub value_msat: Option, + pub payment_preimage: Option, + pub status: PaymentStatus, + pub payment_hash: SecretHash, +} + +#[derive(Clone, Debug)] +pub struct LndConnectorParams { + pub lnd_url: Url, + pub retry_interval_ms: u64, + pub certificate_path: PathBuf, + pub macaroon_path: PathBuf, +} + +#[derive(Clone, Debug)] +enum LazyFile { + Path(PathBuf), + Inner(T), +} + +impl LazyFile +where + T: TryFrom, Error = Error>, +{ + pub fn new(path: PathBuf) -> Self { + Self::Path(path) + } + + pub fn read(self) -> Result { + match self { + LazyFile::Inner(_) => Ok(self), + LazyFile::Path(path) => { + let mut buf = Vec::new(); + std::fs::File::open(path)?.read_to_end(&mut buf)?; + let inner = buf.try_into()?; + Ok(LazyFile::Inner(inner)) + } + } + } + + pub fn inner(&self) -> Result<&T, Error> { + match self { + LazyFile::Path(_) => Err(anyhow::anyhow!("File was not read.")), + LazyFile::Inner(inner) => Ok(inner), + } + } +} + +#[derive(Clone, Debug)] +struct Certificate(reqwest::Certificate); + +impl TryFrom> for Certificate { + type Error = Error; + fn try_from(buf: Vec) -> Result { + Ok(Certificate(reqwest::Certificate::from_pem(&buf)?)) + } +} + +#[derive(Clone, Debug)] +/// The string is hex encoded +struct Macaroon(String); + +impl TryFrom> for Macaroon { + type Error = Error; + fn try_from(buf: Vec) -> Result { + Ok(Macaroon(hex::encode(buf))) + } +} + +/// LND connector for connecting to an LND node when sending a lightning +/// payment. +/// +/// When connecting to LND as the sender all state decisions must be made based +/// on the payment status. This is because only the receiver has the invoice, +/// the sender makes payments using the swap parameters. +#[derive(Clone, Debug)] +pub struct LndConnectorAsSender { + lnd_url: Url, + retry_interval_ms: u64, + certificate: LazyFile, + macaroon: LazyFile, +} + +impl From for LndConnectorAsSender { + fn from(params: LndConnectorParams) -> Self { + Self { + lnd_url: params.lnd_url, + retry_interval_ms: params.retry_interval_ms, + certificate: LazyFile::::new(params.certificate_path), + macaroon: LazyFile::::new(params.macaroon_path), + } + } +} + +impl LndConnectorAsSender { + pub fn read_certificate(self) -> Result { + Ok(Self { + certificate: self.certificate.read()?, + ..self + }) + } + + pub fn read_macaroon(self) -> Result { + Ok(Self { + macaroon: self.macaroon.read()?, + ..self + }) + } + + fn payment_url(&self) -> Url { + self.lnd_url + .join("/v1/payments?include_incomplete=true") + .expect("append valid string to url") + } + + async fn find_payment( + &self, + secret_hash: SecretHash, + status: PaymentStatus, + ) -> Result, Error> { + let response = client(self.certificate.inner()?, self.macaroon.inner()?)? + .get(self.payment_url()) + .send() + .await? + .json::() + .await?; + let payment = response + .payments + .unwrap_or_default() + .into_iter() + .find(|payment| payment.payment_hash == secret_hash && payment.status == status); + + Ok(payment) + } +} + +#[async_trait::async_trait] +impl Opened for LndConnectorAsSender { + async fn opened(&self, _params: Params) -> Result { + // At this stage there is no way for the sender to know when the invoice is + // added on receiver's side. + Ok(data::Opened) + } +} + +#[async_trait::async_trait] +impl Accepted for LndConnectorAsSender { + async fn accepted(&self, params: Params) -> Result { + // No validation of the parameters because once the payment has been + // sent the sender cannot cancel it. + while self + .find_payment(params.secret_hash, PaymentStatus::InFlight) + .await? + .is_none() + { + tokio::time::delay_for(Duration::from_millis(self.retry_interval_ms)).await; + } + + Ok(data::Accepted) + } +} + +#[async_trait::async_trait] +impl Settled for LndConnectorAsSender { + async fn settled(&self, params: Params) -> Result { + let payment = loop { + match self + .find_payment(params.secret_hash, PaymentStatus::Succeeded) + .await? + { + Some(payment) => break payment, + None => { + tokio::time::delay_for(Duration::from_millis(self.retry_interval_ms)).await; + } + } + }; + + let secret = match payment.payment_preimage { + Some(secret) => Ok(secret), + None => Err(anyhow::anyhow!( + "Pre-image is not present on lnd response for a successful payment: {}", + params.secret_hash + )), + }?; + Ok(data::Settled { secret }) + } +} + +#[async_trait::async_trait] +impl Cancelled for LndConnectorAsSender { + async fn cancelled(&self, params: Params) -> Result { + while self + .find_payment(params.secret_hash, PaymentStatus::Failed) + .await? + .is_none() + { + tokio::time::delay_for(Duration::from_millis(self.retry_interval_ms)).await; + } + + Ok(data::Cancelled) + } +} + +/// LND connector for connecting to an LND node when receiving a lightning +/// payment. +/// +/// When connecting to LND as the receiver all state decisions can be made based +/// on the invoice state. Since as the receiver, we add the invoice we have +/// access to its state. +#[derive(Clone, Debug)] +pub struct LndConnectorAsReceiver { + lnd_url: Url, + retry_interval_ms: u64, + certificate: LazyFile, + macaroon: LazyFile, +} + +impl From for LndConnectorAsReceiver { + fn from(params: LndConnectorParams) -> Self { + Self { + lnd_url: params.lnd_url, + retry_interval_ms: params.retry_interval_ms, + certificate: LazyFile::::new(params.certificate_path), + macaroon: LazyFile::::new(params.macaroon_path), + } + } +} + +impl LndConnectorAsReceiver { + pub fn read_certificate(self) -> Result { + Ok(Self { + certificate: self.certificate.read()?, + ..self + }) + } + + pub fn read_macaroon(self) -> Result { + Ok(Self { + macaroon: self.macaroon.read()?, + ..self + }) + } + + fn invoice_url(&self, secret_hash: SecretHash) -> Result { + Ok(self + .lnd_url + .join("/v1/invoice/") + .expect("append valid string to url") + .join(format!("{:x}", secret_hash).as_str())?) + } + + #[tracing::instrument(level = "debug", skip(self))] + async fn find_invoice( + &self, + secret_hash: SecretHash, + expected_state: InvoiceState, + ) -> Result, Error> { + let response = client(self.certificate.inner()?, self.macaroon.inner()?)? + .get(self.invoice_url(secret_hash)?) + .send() + .await?; + + if response.status() == StatusCode::NOT_FOUND { + tracing::debug!("invoice not found"); + return Ok(None); + } + + // Need to shortcut here until https://github.com/hyperium/hyper/issues/2171 or https://github.com/lightningnetwork/lnd/issues/4135 is resolved + if response.status() == StatusCode::INTERNAL_SERVER_ERROR { + return Ok(None); + } + + if !response.status().is_success() { + let status_code = response.status(); + let lnd_error = response + .json::() + .await + // yes we can fail while we already encoundered an error ... + .with_context(|| format!("encountered {} while fetching invoice but couldn't deserialize error response 🙄", status_code))?; + + return Err(lnd_error.into()); + } + + let invoice = response + .json::() + .await + .context("failed to deserialize response as invoice")?; + + if invoice.state == expected_state { + Ok(Some(invoice)) + } else { + tracing::debug!("invoice exists but is in state {}", invoice.state); + Ok(None) + } + } +} + +#[derive(Deserialize, Debug, thiserror::Error)] +#[error("{message}")] +struct LndError { + error: String, + message: String, + code: u32, +} + +#[async_trait::async_trait] +impl Opened for LndConnectorAsReceiver { + async fn opened(&self, params: Params) -> Result { + // Do we want to validate that the user used the correct swap parameters + // when adding the invoice? + while self + .find_invoice(params.secret_hash, InvoiceState::Open) + .await? + .is_none() + { + tokio::time::delay_for(Duration::from_millis(self.retry_interval_ms)).await; + } + + Ok(data::Opened) + } +} + +#[async_trait::async_trait] +impl Accepted for LndConnectorAsReceiver { + async fn accepted(&self, params: Params) -> Result { + // Validation that sender payed the correct invoice is provided by LND. + // Since the sender uses the params to make the payment (as apposed to + // the invoice) LND guarantees that the params match the invoice when + // updating the invoice status. + while self + .find_invoice(params.secret_hash, InvoiceState::Accepted) + .await? + .is_none() + { + tokio::time::delay_for(Duration::from_millis(self.retry_interval_ms)).await; + } + Ok(data::Accepted) + } +} + +#[async_trait::async_trait] +impl Settled for LndConnectorAsReceiver { + async fn settled(&self, params: Params) -> Result { + let invoice = loop { + match self + .find_invoice(params.secret_hash, InvoiceState::Settled) + .await? + { + Some(invoice) => break invoice, + None => tokio::time::delay_for(Duration::from_millis(self.retry_interval_ms)).await, + } + }; + + let preimage = invoice + .r_preimage + .ok_or_else(|| anyhow::anyhow!("settled invoice does not contain preimage?!"))?; + + Ok(data::Settled { + secret: Secret::from_vec(base64::decode(preimage.as_bytes())?.as_slice())?, + }) + } +} + +#[async_trait::async_trait] +impl Cancelled for LndConnectorAsReceiver { + async fn cancelled(&self, params: Params) -> Result { + while self + .find_invoice(params.secret_hash, InvoiceState::Cancelled) + .await? + .is_none() + { + tokio::time::delay_for(Duration::from_millis(self.retry_interval_ms)).await; + } + Ok(data::Cancelled) + } +} + +fn client(certificate: &Certificate, macaroon: &Macaroon) -> Result { + let cert = certificate.0.clone(); + let mut default_headers = HeaderMap::with_capacity(1); + default_headers.insert( + "Grpc-Metadata-macaroon", + HeaderValue::from_str(&macaroon.0)?, + ); + + Ok(reqwest::Client::builder() + .add_root_certificate(cert) + .default_headers(default_headers) + .build()?) +} diff --git a/cnd/src/main.rs b/cnd/src/main.rs index d27482284e..775ee4be6b 100644 --- a/cnd/src/main.rs +++ b/cnd/src/main.rs @@ -23,10 +23,15 @@ use cnd::{ db::Sqlite, file_lock::TryLockExclusive, http_api::route_factory, - jsonrpc, load_swaps, + jsonrpc, + lnd::LndConnectorParams, + load_swaps, network::Swarm, seed::RootSeed, - swap_protocols::{Facade, LedgerStates, SwapCommunicationStates, SwapErrorStates}, + swap_protocols::{ + halight::InvoiceStates, Facade, Facade2, LedgerStates, SwapCommunicationStates, + SwapErrorStates, + }, }; use rand::rngs::OsRng; @@ -110,11 +115,21 @@ fn main() -> anyhow::Result<()> { )) }; + let lnd_connector_params = LndConnectorParams { + lnd_url: settings.lightning.lnd.rest_api_url.clone(), + retry_interval_ms: 100, + certificate_path: settings.lightning.lnd.cert_path.clone(), + macaroon_path: settings.lightning.lnd.readonly_macaroon_path.clone(), + }; + + // Han protocol let alpha_ledger_state = Arc::new(LedgerStates::default()); let beta_ledger_state = Arc::new(LedgerStates::default()); - let swap_communication_states = Arc::new(SwapCommunicationStates::default()); + // HALight + let invoice_states = Arc::new(InvoiceStates::default()); + let swap_error_states = Arc::new(SwapErrorStates::default()); let swarm = Swarm::new( @@ -123,12 +138,20 @@ fn main() -> anyhow::Result<()> { &mut runtime, Arc::clone(&bitcoin_connector), Arc::clone(ðereum_connector), + lnd_connector_params, Arc::clone(&swap_communication_states), Arc::clone(&alpha_ledger_state), Arc::clone(&beta_ledger_state), + Arc::clone(&invoice_states), &database, )?; + let facade2 = Facade2 { + swarm: swarm.clone(), + alpha_ledger_state: Arc::clone(&alpha_ledger_state), + beta_ledger_state: Arc::clone(&invoice_states), + }; + let deps = Facade { bitcoin_connector, ethereum_connector, @@ -137,12 +160,12 @@ fn main() -> anyhow::Result<()> { swap_communication_states, swap_error_states, seed, - swarm, db: database, + swarm, }; runtime.block_on(load_swaps::load_swaps_from_database(deps.clone()))?; - runtime.spawn(spawn_warp_instance(settings, deps)); + runtime.spawn(spawn_warp_instance(settings, deps, facade2)); // Block the current thread. ::std::thread::park(); @@ -160,8 +183,12 @@ fn version() { println!("{} {} ({})", name, version, short); } -async fn spawn_warp_instance(settings: Settings, dependencies: Facade) { - let routes = route_factory::create(dependencies, &settings.http_api.cors.allowed_origins); +async fn spawn_warp_instance(settings: Settings, dependencies: Facade, facade2: Facade2) { + let routes = route_factory::create( + dependencies, + facade2, + &settings.http_api.cors.allowed_origins, + ); let listen_addr = settings.http_api.socket; diff --git a/cnd/src/network.rs b/cnd/src/network.rs index eceb5cb509..3d7882b868 100644 --- a/cnd/src/network.rs +++ b/cnd/src/network.rs @@ -1,3 +1,4 @@ +pub mod comit_ln; pub mod oneshot_behaviour; pub mod oneshot_protocol; pub mod protocols; @@ -16,8 +17,11 @@ use crate::{ db::{Save, Sqlite, Swap}, htlc_location, libp2p_comit_ext::{FromHeader, ToHeader}, + lnd::LndConnectorParams, + network::comit_ln::ComitLN, seed::RootSeed, swap_protocols::{ + halight::InvoiceStates, ledger, rfc003::{ self, @@ -25,7 +29,8 @@ use crate::{ LedgerState, SwapCommunication, }, state::Insert, - HashFunction, LedgerStates, Role, SwapCommunicationStates, SwapId, SwapProtocol, + CreateSwapParams, HashFunction, LedgerStates, NodeLocalSwapId, Role, + SwapCommunicationStates, SwapId, SwapProtocol, }, transaction, }; @@ -36,18 +41,13 @@ use futures::{ Future, }; use libp2p::{ - core::either::EitherOutput, identity::{ed25519, Keypair}, mdns::Mdns, - swarm::{ - protocols_handler::DummyProtocolsHandler, IntoProtocolsHandlerSelect, - NetworkBehaviourEventProcess, SwarmBuilder, - }, + swarm::SwarmBuilder, Multiaddr, NetworkBehaviour, PeerId, }; use libp2p_comit::{ frame::{OutboundRequest, Response, ValidatedInboundRequest}, - handler::{ComitHandler, ProtocolInEvent, ProtocolOutEvent}, BehaviourOutEvent, Comit, PendingInboundRequest, }; use serde::{de::DeserializeOwned, Deserialize, Serialize}; @@ -65,19 +65,12 @@ use tokio::{ sync::Mutex, }; -type ExpandedSwarm = libp2p::swarm::ExpandedSwarm< - ComitNode, - EitherOutput, - EitherOutput, - IntoProtocolsHandlerSelect, ->; - #[derive(Clone, derivative::Derivative)] #[derivative(Debug)] #[allow(clippy::type_complexity)] pub struct Swarm { #[derivative(Debug = "ignore")] - swarm: Arc>, + pub swarm: Arc>>, local_peer_id: PeerId, } @@ -89,9 +82,11 @@ impl Swarm { runtime: &mut Runtime, bitcoin_connector: Arc>, ethereum_connector: Arc>, + lnd_connector_params: LndConnectorParams, swap_communication_states: Arc, alpha_ledger_state: Arc, beta_ledger_state: Arc, + invoice_states: Arc, database: &Sqlite, ) -> anyhow::Result { let local_key_pair = derive_key_pair(&seed); @@ -102,9 +97,11 @@ impl Swarm { let behaviour = ComitNode::new( bitcoin_connector, ethereum_connector, + lnd_connector_params, swap_communication_states, alpha_ledger_state, beta_ledger_state, + invoice_states, seed, database.clone(), runtime.handle().clone(), @@ -153,6 +150,18 @@ impl Swarm { unimplemented!() } + pub async fn initiate_communication(&self, id: NodeLocalSwapId, swap_params: CreateSwapParams) { + let mut guard = self.swarm.lock().await; + + guard.initiate_communication(id, swap_params) + } + + pub async fn get_finalized_swap(&self, id: NodeLocalSwapId) -> Option { + let mut guard = self.swarm.lock().await; + + guard.get_finalized_swap(id) + } + // On Bob's side, when an announce message is received execute the required // communication protocols and write the finalized swap to the database. Then // spawn the same as is done for Alice. @@ -169,7 +178,7 @@ impl libp2p::core::Executor for TokioExecutor { } struct SwarmWorker { - swarm: Arc>, + swarm: Arc>>, } impl futures::Future for SwarmWorker { @@ -197,6 +206,7 @@ fn derive_key_pair(seed: &RootSeed) -> Keypair { #[allow(missing_debug_implementations)] pub struct ComitNode { comit: Comit, + comit_ln: ComitLN, mdns: Mdns, #[behaviour(ignore)] @@ -256,9 +266,11 @@ impl ComitNode { pub fn new( bitcoin_connector: Arc>, ethereum_connector: Arc>, + lnd_connector_params: LndConnectorParams, swap_communication_states: Arc, alpha_ledger_state: Arc, beta_ledger_state: Arc, + invoice_states: Arc, seed: RootSeed, db: Sqlite, task_executor: Handle, @@ -277,6 +289,13 @@ impl ComitNode { Ok(Self { comit: Comit::new(known_headers), mdns: Mdns::new()?, + comit_ln: ComitLN::new( + lnd_connector_params, + ethereum_connector.clone(), + alpha_ledger_state.clone(), + invoice_states, + seed, + ), bitcoin_connector, ethereum_connector, alpha_ledger_state, @@ -297,6 +316,14 @@ impl ComitNode { self.comit .send_request((peer_id.peer_id, peer_id.address_hint), request) } + + pub fn initiate_communication(&mut self, id: NodeLocalSwapId, swap_params: CreateSwapParams) { + self.comit_ln.initiate_communication(id, swap_params) + } + + pub fn get_finalized_swap(&mut self, id: NodeLocalSwapId) -> Option { + self.comit_ln.get_finalized_swap(id) + } } // This is due to the introduction of a struct per Bitcoin network and can be @@ -1059,7 +1086,7 @@ impl SendRequest for Swarm { } } -impl NetworkBehaviourEventProcess for ComitNode { +impl libp2p::swarm::NetworkBehaviourEventProcess for ComitNode { fn inject_event(&mut self, event: BehaviourOutEvent) { match event { BehaviourOutEvent::PendingInboundRequest { request, peer_id } => { @@ -1096,10 +1123,14 @@ impl NetworkBehaviourEventProcess for ComitNode { } } -impl NetworkBehaviourEventProcess for ComitNode { +impl libp2p::swarm::NetworkBehaviourEventProcess for ComitNode { fn inject_event(&mut self, _event: libp2p::mdns::MdnsEvent) {} } +impl libp2p::swarm::NetworkBehaviourEventProcess<()> for ComitNode { + fn inject_event(&mut self, _event: ()) {} +} + impl TryFrom> for OutboundRequest where RequestBody: From> + Serialize, diff --git a/cnd/src/network/comit_ln.rs b/cnd/src/network/comit_ln.rs new file mode 100644 index 0000000000..1b37047db9 --- /dev/null +++ b/cnd/src/network/comit_ln.rs @@ -0,0 +1,723 @@ +use crate::{ + asset, + btsieve::ethereum::{Cache, Web3Connector}, + htlc_location, identity, + lnd::{LndConnectorAsReceiver, LndConnectorAsSender, LndConnectorParams}, + network::{ + oneshot_behaviour, + protocols::{ + announce, + announce::{ + behaviour::{Announce, BehaviourOutEvent}, + SwapDigest, + }, + ethereum_identity, finalize, lightning_identity, secret_hash, + }, + }, + seed::{DeriveSwapSeedFromNodeLocal, RootSeed}, + swap_protocols::{ + halight::{self, InvoiceStates}, + han, ledger, + ledger::{ethereum::ChainId, lightning, Ethereum}, + rfc003::{create_swap::HtlcParams, DeriveSecret, Secret, SecretHash}, + state::Update, + CreateSwapParams, LedgerStates, NodeLocalSwapId, Role, SwapId, + }, + timestamp::Timestamp, + transaction, +}; +use blockchain_contracts::ethereum::rfc003::ether_htlc::EtherHtlc; +use chrono::Utc; +use digest::Digest; +use futures::{AsyncWriteExt, TryStreamExt}; +use libp2p::{ + swarm::{NetworkBehaviour, NetworkBehaviourEventProcess}, + NetworkBehaviour, +}; +use std::{collections::HashMap, sync::Arc}; +use tracing_futures::Instrument; + +#[derive(NetworkBehaviour, Debug)] +pub struct ComitLN { + announce: Announce, + secret_hash: oneshot_behaviour::Behaviour, + ethereum_identity: oneshot_behaviour::Behaviour, + lightning_identity: oneshot_behaviour::Behaviour, + finalize: oneshot_behaviour::Behaviour, + + #[behaviour(ignore)] + swaps_waiting_for_announcement: HashMap, + #[behaviour(ignore)] + swaps: HashMap, + #[behaviour(ignore)] + swap_ids: HashMap, + #[behaviour(ignore)] + ethereum_identities: HashMap, + #[behaviour(ignore)] + lightning_identities: HashMap, + #[behaviour(ignore)] + communication_state: HashMap, + #[behaviour(ignore)] + secret_hashes: HashMap, + #[behaviour(ignore)] + lnd_connector_as_sender: Arc, + #[behaviour(ignore)] + lnd_connector_as_receiver: Arc, + + #[behaviour(ignore)] + ethereum_connector: Arc>, + #[behaviour(ignore)] + ethereum_ledger_state: Arc, + #[behaviour(ignore)] + invoices_states: Arc, + + #[behaviour(ignore)] + pub seed: RootSeed, +} + +#[derive(Debug, Default)] +struct CommunicationState { + ethereum_identity_sent: bool, + lightning_identity_sent: bool, + received_finalized: bool, + sent_finalized: bool, + secret_hash_sent_or_received: bool, +} + +impl ComitLN { + pub fn new( + lnd_connector_params: LndConnectorParams, + ethereum_connector: Arc>, + ethereum_ledger_state: Arc, + invoices_state: Arc, + seed: RootSeed, + ) -> Self { + ComitLN { + announce: Default::default(), + secret_hash: Default::default(), + ethereum_identity: Default::default(), + lightning_identity: Default::default(), + finalize: Default::default(), + swaps_waiting_for_announcement: Default::default(), + swaps: Default::default(), + swap_ids: Default::default(), + ethereum_identities: Default::default(), + lightning_identities: Default::default(), + communication_state: Default::default(), + secret_hashes: Default::default(), + lnd_connector_as_sender: Arc::new(lnd_connector_params.clone().into()), + lnd_connector_as_receiver: Arc::new(lnd_connector_params.into()), + ethereum_connector, + ethereum_ledger_state, + invoices_states: invoices_state, + seed, + } + } + + pub fn initiate_communication( + &mut self, + id: NodeLocalSwapId, + create_swap_params: CreateSwapParams, + ) { + let digest = create_swap_params.clone().digest(); + + self.swaps.insert(id, create_swap_params.clone()); + + match create_swap_params.role { + Role::Alice => { + if self.swaps_waiting_for_announcement.contains_key(&digest) { + // To fix this panic, we should either pass the local swap id to the + // announce behaviour or get a unique token from the behaviour that + // we can use to track the progress of the announcement + panic!("cannot send two swaps with the same digest at the same time!") + } + + self.announce + .start_announce_protocol(digest.clone(), create_swap_params.peer); + + self.swaps_waiting_for_announcement.insert(digest, id); + } + Role::Bob => { + tracing::info!("Swap waiting for announcement: {}", digest); + self.swaps_waiting_for_announcement.insert(digest, id); + } + } + } + + pub fn get_finalized_swap(&self, local_id: NodeLocalSwapId) -> Option { + let create_swap_params = match self.swaps.get(&local_id) { + Some(body) => body, + None => return None, + }; + + let secret = match create_swap_params.role { + Role::Alice => Some( + self.seed + .derive_swap_seed_from_node_local(local_id) + .derive_secret(), + ), + Role::Bob => None, + }; + + let id = match self.swap_ids.get(&local_id).copied() { + Some(id) => id, + None => return None, + }; + + let alpha_ledger_redeem_identity = match create_swap_params.role { + Role::Alice => match self.ethereum_identities.get(&id).copied() { + Some(identity) => identity, + None => return None, + }, + Role::Bob => create_swap_params.ethereum_identity.into(), + }; + let alpha_ledger_refund_identity = match create_swap_params.role { + Role::Alice => create_swap_params.ethereum_identity.into(), + Role::Bob => match self.ethereum_identities.get(&id).copied() { + Some(identity) => identity, + None => return None, + }, + }; + let beta_ledger_redeem_identity = match create_swap_params.role { + Role::Alice => create_swap_params.lightning_identity, + Role::Bob => match self.lightning_identities.get(&id).copied() { + Some(identity) => identity, + None => return None, + }, + }; + let beta_ledger_refund_identity = match create_swap_params.role { + Role::Alice => match self.lightning_identities.get(&id).copied() { + Some(identity) => identity, + None => return None, + }, + Role::Bob => create_swap_params.lightning_identity, + }; + + Some(FinalizedSwap { + alpha_ledger: Ethereum::new(ChainId::regtest()), + beta_ledger: lightning::Regtest, + alpha_asset: create_swap_params.ethereum_amount.clone(), + beta_asset: create_swap_params.lightning_amount, + alpha_ledger_redeem_identity, + alpha_ledger_refund_identity, + beta_ledger_redeem_identity, + beta_ledger_refund_identity, + alpha_expiry: create_swap_params.ethereum_absolute_expiry, + beta_expiry: create_swap_params.lightning_cltv_expiry, + local_id, + secret, + secret_hash: match self.secret_hashes.get(&id).copied() { + Some(secret_hash) => secret_hash, + None => return None, + }, + role: create_swap_params.role, + }) + } +} + +#[derive(Debug)] +pub struct FinalizedSwap { + pub alpha_ledger: Ethereum, + pub beta_ledger: lightning::Regtest, + pub alpha_asset: asset::Ether, + pub beta_asset: asset::Lightning, + pub alpha_ledger_refund_identity: identity::Ethereum, + pub alpha_ledger_redeem_identity: identity::Ethereum, + pub beta_ledger_refund_identity: identity::Lightning, + pub beta_ledger_redeem_identity: identity::Lightning, + pub alpha_expiry: Timestamp, + pub beta_expiry: Timestamp, + pub local_id: NodeLocalSwapId, + pub secret_hash: SecretHash, + pub secret: Option, + pub role: Role, +} + +impl FinalizedSwap { + pub fn han_params(&self) -> EtherHtlc { + HtlcParams { + asset: self.alpha_asset.clone(), + ledger: Ethereum::new(ChainId::regtest()), + redeem_identity: self.alpha_ledger_redeem_identity, + refund_identity: self.alpha_ledger_refund_identity, + expiry: self.alpha_expiry, + secret_hash: self.secret_hash, + } + .into() + } +} + +impl NetworkBehaviourEventProcess> for ComitLN { + fn inject_event(&mut self, event: oneshot_behaviour::OutEvent) { + let (peer, swap_id) = match event { + oneshot_behaviour::OutEvent::Received { + peer, + message: + secret_hash::Message { + swap_id, + secret_hash, + }, + } => { + self.secret_hashes + .insert(swap_id, SecretHash::from(secret_hash)); + + let state = self + .communication_state + .get_mut(&swap_id) + .expect("must exist"); + + state.secret_hash_sent_or_received = true; + + (peer, swap_id) + } + oneshot_behaviour::OutEvent::Sent { + peer, + message: + secret_hash::Message { + swap_id, + secret_hash, + }, + } => { + self.secret_hashes + .insert(swap_id, SecretHash::from(secret_hash)); + + let state = self + .communication_state + .get_mut(&swap_id) + .expect("should exist"); + + state.secret_hash_sent_or_received = true; + + (peer, swap_id) + } + }; + + let state = self.communication_state.get(&swap_id).unwrap(); + + // check if we are done + if self.ethereum_identities.contains_key(&swap_id) + && self.lightning_identities.contains_key(&swap_id) + && state.lightning_identity_sent + && state.ethereum_identity_sent + && state.secret_hash_sent_or_received + { + self.finalize.send(peer, finalize::Message::new(swap_id)); + } + } +} + +impl NetworkBehaviourEventProcess for ComitLN { + fn inject_event(&mut self, event: BehaviourOutEvent) { + match event { + BehaviourOutEvent::ReceivedAnnouncement { peer, mut io } => { + if let Some(local_id) = self.swaps_waiting_for_announcement.remove(&io.swap_digest) + { + let id = SwapId::default(); + + self.swap_ids.insert(local_id.clone(), id.clone()); + + tokio::task::spawn(io.send(id)); + + let create_swap_params = self.swaps.get(&local_id).unwrap(); + + let addresses = self.announce.addresses_of_peer(&peer); + self.secret_hash + .register_addresses(peer.clone(), addresses.clone()); + self.ethereum_identity + .register_addresses(peer.clone(), addresses.clone()); + self.lightning_identity + .register_addresses(peer.clone(), addresses.clone()); + self.finalize.register_addresses(peer.clone(), addresses); + + self.ethereum_identity.send( + peer.clone(), + ethereum_identity::Message::new( + id, + create_swap_params.ethereum_identity.into(), + ), + ); + self.lightning_identity.send( + peer, + lightning_identity::Message::new(id, create_swap_params.lightning_identity), + ); + + self.communication_state + .insert(id, CommunicationState::default()); + } else { + tracing::warn!( + "Peer {} announced a swap ({}) we don't know about", + peer, + io.swap_digest + ); + + tokio::task::spawn(async move { + let _ = io.io.close().await; + }); + } + } + BehaviourOutEvent::ReceivedConfirmation { + peer, + swap_digest, + swap_id, + } => { + let local_swap_id = self + .swaps_waiting_for_announcement + .remove(&swap_digest) + .expect("we must know about this digest"); + + self.swap_ids.insert(local_swap_id, swap_id); + + let addresses = self.announce.addresses_of_peer(&peer); + self.secret_hash + .register_addresses(peer.clone(), addresses.clone()); + self.ethereum_identity + .register_addresses(peer.clone(), addresses.clone()); + self.lightning_identity + .register_addresses(peer.clone(), addresses.clone()); + self.finalize.register_addresses(peer.clone(), addresses); + + let create_swap_params = self.swaps.get(&local_swap_id).unwrap(); + + self.ethereum_identity.send( + peer.clone(), + ethereum_identity::Message::new( + swap_id, + create_swap_params.ethereum_identity.into(), + ), + ); + self.lightning_identity.send( + peer.clone(), + lightning_identity::Message::new( + swap_id, + create_swap_params.lightning_identity, + ), + ); + + let seed = self.seed.derive_swap_seed_from_node_local(local_swap_id); + let secret_hash = seed.derive_secret().hash(); + + self.secret_hashes.insert(swap_id, secret_hash); + self.secret_hash + .send(peer, secret_hash::Message::new(swap_id, secret_hash)); + + self.communication_state + .insert(swap_id, CommunicationState::default()); + } + BehaviourOutEvent::Error { peer, error } => { + tracing::warn!( + "failed to complete announce protocol with {} because {:?}", + peer, + error + ); + } + } + } +} + +impl NetworkBehaviourEventProcess> + for ComitLN +{ + fn inject_event(&mut self, event: oneshot_behaviour::OutEvent) { + let (peer, swap_id) = match event { + oneshot_behaviour::OutEvent::Received { + peer, + message: ethereum_identity::Message { swap_id, address }, + } => { + self.ethereum_identities + .insert(swap_id, identity::Ethereum::from(address)); + + (peer, swap_id) + } + oneshot_behaviour::OutEvent::Sent { + peer, + message: ethereum_identity::Message { swap_id, .. }, + } => { + let state = self + .communication_state + .get_mut(&swap_id) + .expect("this should exist"); + + state.ethereum_identity_sent = true; + + (peer, swap_id) + } + }; + + let state = self.communication_state.get(&swap_id).unwrap(); + + // check if we are done + if self.ethereum_identities.contains_key(&swap_id) + && self.lightning_identities.contains_key(&swap_id) + && state.lightning_identity_sent + && state.ethereum_identity_sent + && state.secret_hash_sent_or_received + { + self.finalize.send(peer, finalize::Message::new(swap_id)); + } + } +} + +impl NetworkBehaviourEventProcess> + for ComitLN +{ + fn inject_event(&mut self, event: oneshot_behaviour::OutEvent) { + let (peer, swap_id) = match event { + oneshot_behaviour::OutEvent::Received { + peer, + message: lightning_identity::Message { swap_id, pubkey }, + } => { + self.lightning_identities.insert( + swap_id, + bitcoin::PublicKey::from_slice(&pubkey).unwrap().into(), + ); + + (peer, swap_id) + } + oneshot_behaviour::OutEvent::Sent { + peer, + message: lightning_identity::Message { swap_id, .. }, + } => { + let state = self + .communication_state + .get_mut(&swap_id) + .expect("this should exist"); + + state.lightning_identity_sent = true; + + (peer, swap_id) + } + }; + + let state = self.communication_state.get(&swap_id).unwrap(); + + // check if we are done + if self.ethereum_identities.contains_key(&swap_id) + && self.lightning_identities.contains_key(&swap_id) + && state.lightning_identity_sent + && state.ethereum_identity_sent + && state.secret_hash_sent_or_received + { + self.finalize.send(peer, finalize::Message::new(swap_id)); + } + } +} + +impl NetworkBehaviourEventProcess> for ComitLN { + fn inject_event(&mut self, event: oneshot_behaviour::OutEvent) { + let (_, swap_id) = match event { + oneshot_behaviour::OutEvent::Received { + peer, + message: finalize::Message { swap_id }, + } => { + let state = self + .communication_state + .get_mut(&swap_id) + .expect("this should exist"); + + state.received_finalized = true; + + (peer, swap_id) + } + oneshot_behaviour::OutEvent::Sent { + peer, + message: finalize::Message { swap_id }, + } => { + let state = self + .communication_state + .get_mut(&swap_id) + .expect("this should exist"); + + state.sent_finalized = true; + + (peer, swap_id) + } + }; + + let state = self + .communication_state + .get_mut(&swap_id) + .expect("this should exist"); + + if state.sent_finalized && state.received_finalized { + let local_swap_id = self + .swap_ids + .iter() + .find_map( + |(key, value)| { + if *value == swap_id { + Some(key) + } else { + None + } + }, + ) + .copied() + .unwrap(); + + let create_swap_params = self + .swaps + .get(&local_swap_id) + .cloned() + .expect("create swap params exist"); + + let secret_hash = self + .secret_hashes + .get(&swap_id) + .copied() + .expect("must exist"); + + let invoice_states = self.invoices_states.clone(); + + let role = create_swap_params.role; + + if role == Role::Alice { + tokio::task::spawn({ + let lnd_connector = (*self.lnd_connector_as_receiver) + .clone() + .read_certificate() + .expect("Failure reading tls certificate") + .read_macaroon() + .expect("Failure reading macaroon"); + + new_halight_swap( + local_swap_id, + secret_hash, + invoice_states, + lnd_connector, + ) + .instrument( + tracing::error_span!("beta_ledger", swap_id = %local_swap_id, role = %role), + ) + }); + } else { + // This is Bob + tokio::task::spawn({ + let lnd_connector = (*self.lnd_connector_as_sender) + .clone() + .read_certificate() + .expect("Failure reading tls certificate") + .read_macaroon() + .expect("Failure reading macaroon"); + + new_halight_swap( + local_swap_id, + secret_hash, + invoice_states, + lnd_connector, + ) + .instrument( + tracing::error_span!("beta_ledger", swap_id = %local_swap_id, role = %role), + ) + }); + } + + if role == Role::Alice { + tokio::task::spawn({ + let connector = self.ethereum_connector.clone(); + let alice_ethereum_identity = create_swap_params.ethereum_identity; + let bob_ethereum_identity = + self.ethereum_identities.get(&swap_id).copied().unwrap(); + + let asset = create_swap_params.ethereum_amount.clone(); + let ledger = ledger::Ethereum::default(); + let expiry = create_swap_params.ethereum_absolute_expiry; + let secret_hash = self + .secret_hashes + .get(&swap_id) + .copied() + .expect("must exist"); + + new_han_ethereum_ether_swap( + local_swap_id, + connector, + self.ethereum_ledger_state.clone(), + HtlcParams { + asset, + ledger, + redeem_identity: bob_ethereum_identity, + refund_identity: alice_ethereum_identity.into(), + expiry, + secret_hash, + }, + role, + ) + }); + } else { + tokio::task::spawn({ + // This is Bob + let connector = self.ethereum_connector.clone(); + let alice_ethereum_identity = + self.ethereum_identities.get(&swap_id).copied().unwrap(); + let bob_ethereum_identity = create_swap_params.ethereum_identity; + + let asset = create_swap_params.ethereum_amount.clone(); + let ledger = ledger::Ethereum::default(); + let expiry = create_swap_params.ethereum_absolute_expiry; + let secret_hash = self.secret_hashes.get(&swap_id).copied().unwrap(); + + new_han_ethereum_ether_swap( + local_swap_id, + connector, + self.ethereum_ledger_state.clone(), + HtlcParams { + asset, + ledger, + redeem_identity: bob_ethereum_identity.into(), + refund_identity: alice_ethereum_identity, + expiry, + secret_hash, + }, + role, + ) + }); + } + } + } +} + +/// Creates a new instance of the halight protocol. +/// +/// This function delegates to the `halight` module for the actual protocol +/// implementation. It's main purpose is to annotate the protocol instance with +/// logging information and store the events yielded by the protocol in +/// `InvoiceStates`. +async fn new_halight_swap( + local_swap_id: NodeLocalSwapId, + secret_hash: SecretHash, + invoice_states: Arc, + lnd_connector: C, +) where + C: halight::Opened + halight::Accepted + halight::Settled + halight::Cancelled, +{ + let mut events = halight::new( + &lnd_connector, + halight::Params { secret_hash }, + Utc::now().naive_local(), + ) + .inspect_ok(|event| tracing::info!("yielded event {}", event)) + .inspect_err(|error| tracing::error!("swap failed with {:?}", error)); + + while let Ok(Some(event)) = events.try_next().await { + invoice_states.update(&SwapId(local_swap_id.0), event).await; + } + + tracing::info!("swap finished"); +} + +async fn new_han_ethereum_ether_swap( + local_swap_id: NodeLocalSwapId, + connector: Arc>, + ethereum_ledger_state: Arc, + htlc_params: HtlcParams, + role: Role, +) { + han::create_watcher::<_, _, _, _, htlc_location::Ethereum, _, transaction::Ethereum>( + connector.as_ref(), + ethereum_ledger_state, + local_swap_id, + htlc_params, + Utc::now().naive_local(), + ) + .instrument(tracing::error_span!("alpha_ledger", swap_id = %local_swap_id, role = %role)) + .await +} diff --git a/cnd/src/network/protocols/announce.rs b/cnd/src/network/protocols/announce.rs index 5b525c6452..76144bb906 100644 --- a/cnd/src/network/protocols/announce.rs +++ b/cnd/src/network/protocols/announce.rs @@ -2,7 +2,8 @@ pub mod behaviour; pub mod handler; pub mod protocol; -use multihash::{self, Multihash}; +use digest::IntoDigestInput; +use libp2p::multihash::{self, Multihash}; use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; use std::fmt; @@ -15,6 +16,18 @@ impl SwapDigest { } } +impl IntoDigestInput for SwapDigest { + fn into_digest_input(self) -> Vec { + self.0.into_bytes() + } +} + +impl digest::Hash for SwapDigest { + fn hash(bytes: &[u8]) -> Self { + Self(multihash::Sha3_256::digest(bytes)) + } +} + impl fmt::Display for SwapDigest { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", hex::encode(self.0.as_bytes())) diff --git a/cnd/src/seed.rs b/cnd/src/seed.rs index 01e66380cf..c7c7041265 100644 --- a/cnd/src/seed.rs +++ b/cnd/src/seed.rs @@ -1,4 +1,4 @@ -use crate::swap_protocols::SwapId; +use crate::swap_protocols::{NodeLocalSwapId, SwapId}; use pem::{encode, Pem}; use rand::Rng; use sha2::{Digest, Sha256}; @@ -17,6 +17,7 @@ use thiserror; /// `RootSeed` and `SwapSeed` are the same underlying type (`Seed`), they exist /// solely to allow the compiler to provide us with type safety. +// This will go away once rfc003 is gone. #[ambassador::delegatable_trait] pub trait DeriveSwapSeed { fn derive_swap_seed(&self, id: SwapId) -> SwapSeed; @@ -29,6 +30,20 @@ impl DeriveSwapSeed for RootSeed { } } +// This exists because its safer than the above trait now that the swap_id comes +// from Bob. We do not want to derive the seed using information from Bob. +#[ambassador::delegatable_trait] +pub trait DeriveSwapSeedFromNodeLocal { + fn derive_swap_seed_from_node_local(&self, id: NodeLocalSwapId) -> SwapSeed; +} + +impl DeriveSwapSeedFromNodeLocal for RootSeed { + fn derive_swap_seed_from_node_local(&self, id: NodeLocalSwapId) -> SwapSeed { + let data = self.sha256_with_seed(&[b"SWAP", id.0.as_bytes()]); + SwapSeed(Seed(data)) + } +} + const SEED_LENGTH: usize = 32; #[derive(Clone, Copy, PartialEq)] diff --git a/cnd/src/swap_protocols.rs b/cnd/src/swap_protocols.rs index 8241b145bd..bdd26fd4aa 100644 --- a/cnd/src/swap_protocols.rs +++ b/cnd/src/swap_protocols.rs @@ -1,5 +1,8 @@ pub mod actions; mod facade; +mod facade2; +pub mod halight; +pub mod han; pub mod ledger; pub mod ledger_states; pub mod rfc003; @@ -9,7 +12,8 @@ mod swap_error_states; mod swap_id; pub use self::{ - facade::*, ledger_states::*, swap_communication_states::*, swap_error_states::*, swap_id::*, + facade::*, facade2::*, ledger_states::*, swap_communication_states::*, swap_error_states::*, + swap_id::*, }; use serde::{Deserialize, Serialize}; @@ -43,3 +47,43 @@ pub enum Role { Alice, Bob, } + +/// These are the traits that represent the steps involved in a COMIT atomic +/// swap. Different protocols have different requirements/functionality for +/// each trait method but the abstractions are the same for all protocols. + +/// Describes how to get the `init` action from the current state. +/// +/// If `init` is not feasible in the current state, this should return `None`. +pub trait InitAction { + type Output; + + fn init_action(&self) -> Option; +} + +/// Describes how to get the `fund` action from the current state. +/// +/// If `fund` is not feasible in the current state, this should return `None`. +pub trait FundAction { + type Output; + + fn fund_action(&self) -> Option; +} + +/// Describes how to get the `redeem` action from the current state. +/// +/// If `redeem` is not feasible in the current state, this should return `None`. +pub trait RedeemAction { + type Output; + + fn redeem_action(&self) -> Option; +} + +/// Describes how to get the `refund` action from the current state. +/// +/// If `refund` is not feasible in the current state, this should return `None`. +pub trait RefundAction { + type Output; + + fn refund_action(&self) -> Option; +} diff --git a/cnd/src/swap_protocols/actions.rs b/cnd/src/swap_protocols/actions.rs index 15abe5d275..b6e82bf67e 100644 --- a/cnd/src/swap_protocols/actions.rs +++ b/cnd/src/swap_protocols/actions.rs @@ -41,9 +41,7 @@ pub mod bitcoin { pub mod ethereum { use crate::{ - asset, - ethereum::{Address, Bytes, U256}, - swap_protocols::ledger::ethereum::ChainId, + asset, ethereum::Bytes, identity, swap_protocols::ledger::ethereum::ChainId, timestamp::Timestamp, }; @@ -51,16 +49,67 @@ pub mod ethereum { pub struct DeployContract { pub data: Bytes, pub amount: asset::Ether, - pub gas_limit: U256, + pub gas_limit: u64, pub chain_id: ChainId, } #[derive(Debug, Clone, PartialEq)] pub struct CallContract { - pub to: Address, + pub to: identity::Ethereum, pub data: Option, - pub gas_limit: U256, + pub gas_limit: u64, pub chain_id: ChainId, pub min_block_timestamp: Option, } } + +pub mod lnd { + use crate::{ + asset, identity, + swap_protocols::rfc003::{Secret, SecretHash}, + }; + + #[derive(Debug, Clone, Copy, PartialEq)] + pub struct AddHoldInvoice { + pub amount: asset::Lightning, // The number of satoshis to send. + pub secret_hash: SecretHash, // The hash to use within the payment's HTLC. + pub expiry: u32, + pub cltv_expiry: u32, + pub chain: Chain, + pub network: bitcoin::Network, + pub self_public_key: identity::Lightning, + } + + #[derive(Debug, Clone, Copy, PartialEq)] + pub struct SettleInvoice { + pub secret: Secret, + pub chain: Chain, + pub network: bitcoin::Network, + pub self_public_key: identity::Lightning, + } + + #[derive(Debug, Clone, Copy, PartialEq)] + pub struct CancelInvoice { + pub secret_hash: SecretHash, // The hash of the preimage used when adding the invoice. + pub chain: Chain, + pub network: bitcoin::Network, + pub self_public_key: identity::Lightning, + } + + #[derive(Debug, Clone, Copy, PartialEq)] + pub struct SendPayment { + pub to_public_key: identity::Lightning, + pub amount: asset::Lightning, // The number of satoshis to send. + pub secret_hash: SecretHash, // The hash to use within the payment's HTLC. + pub final_cltv_delta: u32, + pub chain: Chain, + pub network: bitcoin::Network, + pub self_public_key: identity::Lightning, + } + + /// The underlying chain i.e., layer 1, targeted by LND. + #[derive(Debug, Clone, Copy, PartialEq)] + pub enum Chain { + Bitcoin, + } +} diff --git a/cnd/src/swap_protocols/facade2.rs b/cnd/src/swap_protocols/facade2.rs new file mode 100644 index 0000000000..b4f9166a60 --- /dev/null +++ b/cnd/src/swap_protocols/facade2.rs @@ -0,0 +1,112 @@ +use crate::{ + asset, identity, + network::{comit_ln, protocols::announce::SwapDigest, DialInformation, Swarm}, + swap_protocols::{halight::InvoiceStates, LedgerStates, NodeLocalSwapId, Role}, + timestamp::Timestamp, +}; +use digest::{Digest, IntoDigestInput}; +use std::sync::Arc; + +/// This represent the information available on a swap +/// before communication with the other node has started +#[derive(Clone, Digest, Debug)] +#[digest(hash = "SwapDigest")] +pub struct CreateSwapParams { + #[digest(prefix = "")] + pub role: Role, + #[digest(prefix = "")] + pub peer: DialInformation, + #[digest(prefix = "")] + pub ethereum_identity: EthereumIdentity, + #[digest(prefix = "2001")] + pub ethereum_absolute_expiry: Timestamp, + #[digest(prefix = "2002")] + pub ethereum_amount: asset::Ether, + #[digest(prefix = "")] + pub lightning_identity: identity::Lightning, + #[digest(prefix = "3001")] + pub lightning_cltv_expiry: Timestamp, + #[digest(prefix = "3002")] + pub lightning_amount: asset::Lightning, +} + +impl IntoDigestInput for asset::Lightning { + fn into_digest_input(self) -> Vec { + self.to_le_bytes().to_vec() + } +} + +impl IntoDigestInput for identity::Lightning { + fn into_digest_input(self) -> Vec { + vec![] + } +} + +impl IntoDigestInput for asset::Ether { + fn into_digest_input(self) -> Vec { + self.to_bytes() + } +} + +#[derive(Clone, Copy, Debug)] +pub struct EthereumIdentity(identity::Ethereum); + +impl IntoDigestInput for EthereumIdentity { + fn into_digest_input(self) -> Vec { + vec![] + } +} + +impl From for EthereumIdentity { + fn from(inner: identity::Ethereum) -> Self { + EthereumIdentity(inner) + } +} + +impl From for identity::Ethereum { + fn from(outer: EthereumIdentity) -> Self { + outer.0 + } +} + +impl IntoDigestInput for Role { + fn into_digest_input(self) -> Vec { + vec![] + } +} + +impl IntoDigestInput for DialInformation { + fn into_digest_input(self) -> Vec { + vec![] + } +} + +impl IntoDigestInput for Timestamp { + fn into_digest_input(self) -> Vec { + self.to_bytes().to_vec() + } +} + +/// This is a facade that implements all the required traits and forwards them +/// to another implementation. This allows us to keep the number of arguments to +/// HTTP API controllers small and still access all the functionality we need. +#[derive(Clone, Debug)] +pub struct Facade2 { + pub swarm: Swarm, + pub alpha_ledger_state: Arc, /* We currently only support Han-HALight, this is + * Ethereum. */ + pub beta_ledger_state: Arc, /* We currently only support Han-HALight, this is + * Lightning. */ +} + +impl Facade2 { + pub async fn save(&self, _id: NodeLocalSwapId, _swap_params: ()) {} + + pub async fn initiate_communication(&self, id: NodeLocalSwapId, swap_params: CreateSwapParams) { + self.swarm.initiate_communication(id, swap_params).await; + } + + pub async fn get_finalized_swap(&self, id: NodeLocalSwapId) -> Option { + self.swarm.get_finalized_swap(id).await + } +} diff --git a/cnd/src/swap_protocols/halight.rs b/cnd/src/swap_protocols/halight.rs new file mode 100644 index 0000000000..096a9d56fd --- /dev/null +++ b/cnd/src/swap_protocols/halight.rs @@ -0,0 +1,226 @@ +use crate::swap_protocols::{ + rfc003::{Secret, SecretHash}, + state, SwapId, +}; +use chrono::NaiveDateTime; +use futures::{ + future::{self, Either}, + Stream, TryFutureExt, +}; +use genawaiter::sync::Gen; +use std::collections::{hash_map::Entry, HashMap}; +use tokio::sync::Mutex; + +/// Resolves when said event has occured. +#[async_trait::async_trait] +pub trait Opened { + async fn opened(&self, params: Params) -> anyhow::Result; +} + +#[async_trait::async_trait] +pub trait Accepted { + async fn accepted(&self, params: Params) -> anyhow::Result; +} + +#[async_trait::async_trait] +pub trait Settled { + async fn settled(&self, params: Params) -> anyhow::Result; +} + +#[async_trait::async_trait] +pub trait Cancelled { + async fn cancelled(&self, params: Params) -> anyhow::Result; +} + +/// Represents states that an invoice can be in. +#[derive(Debug, Clone, Copy)] +pub enum State { + Unknown, + Opened(data::Opened), + Accepted(data::Accepted), + Settled(data::Settled), + Cancelled(data::Cancelled), +} + +/// Represents the events in the halight protocol. +#[derive(Debug, Clone, Copy, PartialEq, strum_macros::Display)] +pub enum Event { + /// The halight protocol was started. + Started, + + /// The invoice was opened and is ready to accept a payment. + /// + /// On the recipient side, this means the hold invoice has been added to + /// lnd. On the (payment) sender side, we cannot (yet) know about this + /// so we just have to assume that this happens. + Opened(data::Opened), + + /// The payment to the invoice was accepted but the preimage has not yet + /// been revealed. + /// + /// On the recipient side, this means the hold invoice moved to the + /// `Accepted` state. On the (payment) sender side, we assume that once + /// the payment is `InFlight`, it also reached the recipient. + Accepted(data::Accepted), + + /// The payment is settled and therefore the preimage was revealed. + Settled(data::Settled), + + /// The payment was cancelled. + Cancelled(data::Cancelled), +} + +/// Represents the data available at said state. +pub mod data { + // These empty types are useful because they give us additional type safety. + use super::*; + + #[derive(Debug, Clone, Copy, PartialEq)] + pub struct Opened; + + #[derive(Debug, Clone, Copy, PartialEq)] + pub struct Accepted; + + #[derive(Debug, Clone, Copy, PartialEq)] + pub struct Settled { + pub secret: Secret, + } + + #[derive(Debug, Clone, Copy, PartialEq)] + pub struct Cancelled; +} + +#[derive(Default, Debug)] +pub struct InvoiceStates { + states: Mutex>, +} + +impl State { + pub fn transition_to_opened(&mut self, opened: data::Opened) { + match std::mem::replace(self, State::Unknown) { + State::Unknown => *self = State::Opened(opened), + other => panic!("expected state Unknown, got {:?}", other), + } + } + + pub fn transition_to_accepted(&mut self, accepted: data::Accepted) { + match std::mem::replace(self, State::Unknown) { + State::Opened(_) => *self = State::Accepted(accepted), + other => panic!("expected state Opened, got {:?}", other), + } + } + + pub fn transition_to_settled(&mut self, settled: data::Settled) { + match std::mem::replace(self, State::Unknown) { + State::Accepted(_) => *self = State::Settled(settled), + other => panic!("expected state Accepted, got {:?}", other), + } + } + + pub fn transition_to_cancelled(&mut self, cancelled: data::Cancelled) { + match std::mem::replace(self, State::Unknown) { + // Alice cancels invoice before Bob has accepted it. + State::Opened(_) => *self = State::Cancelled(cancelled), + // Alice cancels invoice after Bob has accepted it. + State::Accepted(_) => *self = State::Cancelled(cancelled), + other => panic!("expected state Opened or Accepted, got {:?}", other), + } + } +} + +#[async_trait::async_trait] +impl state::Get for InvoiceStates { + async fn get(&self, key: &SwapId) -> anyhow::Result> { + let states = self.states.lock().await; + let state = states.get(key).copied(); + + Ok(state) + } +} + +#[async_trait::async_trait] +impl state::Update for InvoiceStates { + async fn update(&self, key: &SwapId, event: Event) { + let mut states = self.states.lock().await; + let entry = states.entry(*key); + + match (event, entry) { + (Event::Started, Entry::Vacant(vacant)) => { + vacant.insert(State::Unknown); + } + (Event::Opened(opened), Entry::Occupied(mut state)) => { + state.get_mut().transition_to_opened(opened) + } + (Event::Accepted(accepted), Entry::Occupied(mut state)) => { + state.get_mut().transition_to_accepted(accepted) + } + (Event::Settled(settled), Entry::Occupied(mut state)) => { + state.get_mut().transition_to_settled(settled) + } + (Event::Cancelled(cancelled), Entry::Occupied(mut state)) => { + state.get_mut().transition_to_cancelled(cancelled) + } + (Event::Started, Entry::Occupied(_)) => { + tracing::warn!( + "Received Started event for {} although state is already present", + key + ); + } + (_, Entry::Vacant(_)) => { + tracing::warn!("State not found for {}", key); + } + } + } +} + +/// Creates a new instance of the halight protocol. +/// +/// Returns a stream of events happening during the execution. +pub fn new<'a, C>( + lnd_connector: &'a C, + params: Params, + _finalized_at: NaiveDateTime, +) -> impl Stream> + 'a +where + C: Opened + Accepted + Settled + Cancelled, +{ + Gen::new({ + |co| async move { + co.yield_(Ok(Event::Started)).await; + + let opened_or_error = lnd_connector + .opened(params.clone()) + .map_ok(Event::Opened) + .await; + co.yield_(opened_or_error).await; + + let accepted_or_error = lnd_connector + .accepted(params.clone()) + .map_ok(Event::Accepted) + .await; + co.yield_(accepted_or_error).await; + + let settled = lnd_connector.settled(params.clone()); + let cancelled = lnd_connector.cancelled(params); + + match future::try_select(settled, cancelled).await { + Ok(Either::Left((settled, _))) => { + co.yield_(Ok(Event::Settled(settled))).await; + } + Ok(Either::Right((cancelled, _))) => { + co.yield_(Ok(Event::Cancelled(cancelled))).await; + } + Err(either) => { + let (error, _other_future) = either.factor_first(); + + co.yield_(Err(error)).await; + } + } + } + }) +} + +#[derive(Clone, Copy, Debug)] +pub struct Params { + pub secret_hash: SecretHash, +} diff --git a/cnd/src/swap_protocols/han.rs b/cnd/src/swap_protocols/han.rs new file mode 100644 index 0000000000..d8accdb9cf --- /dev/null +++ b/cnd/src/swap_protocols/han.rs @@ -0,0 +1,131 @@ +use crate::swap_protocols::{ + rfc003::{ + create_swap::{HtlcParams, SwapEvent}, + events::{ + Deployed, HtlcDeployed, HtlcFunded, HtlcRedeemed, HtlcRefunded, Redeemed, Refunded, + }, + LedgerState, + }, + state, NodeLocalSwapId, SwapId, +}; +use chrono::NaiveDateTime; +use futures::future::{self, Either}; +use genawaiter::{ + sync::{Co, Gen}, + GeneratorState, +}; +use std::sync::Arc; + +/// Returns a future that tracks the swap negotiated from the given request and +/// accept response on a ledger. +/// +/// The current implementation is naive in the sense that it does not take into +/// account situations where it is clear that no more events will happen even +/// though in theory, there could. For example: +/// - funded +/// - refunded +/// +/// It is highly unlikely for Bob to fund the HTLC now, yet the current +/// implementation is still waiting for that. +pub async fn create_watcher( + ethereum_connector: &C, + ledger_state: Arc, + local_id: NodeLocalSwapId, + htlc_params: HtlcParams, + accepted_at: NaiveDateTime, +) where + C: HtlcFunded + + HtlcDeployed + + HtlcRedeemed + + HtlcRefunded, + S: state::Update> + state::Insert>, + L: Clone, + A: Ord + Clone, + H: Clone, + I: Clone, + T: Clone, +{ + let id = SwapId(local_id.0); + + ledger_state + .insert(id, LedgerState::::NotDeployed) + .await; + + // construct a generator that watches alpha and beta ledger concurrently + let mut generator = Gen::new({ + |co| async { + watch_ledger::(ðereum_connector, co, htlc_params, accepted_at) + .await + } + }); + + loop { + // wait for events to be emitted as the generator executes + match generator.async_resume().await { + // every event that is yielded is passed on + GeneratorState::Yielded(event) => { + tracing::info!("swap {} yielded event {}", id, event); + ledger_state.update(&id, event).await; + } + // the generator stopped executing, this means there are no more events that can be + // watched. + GeneratorState::Complete(Ok(_)) => { + tracing::info!("swap {} finished", id); + return; + } + GeneratorState::Complete(Err(e)) => { + tracing::error!("swap {} failed with {:?}", id, e); + return; + } + } + } +} + +/// Returns a future that waits for events to happen on a ledger. +/// +/// Each event is yielded through the controller handle (co) of the coroutine. +async fn watch_ledger( + ethereum_connector: &C, + co: Co>, + htlc_params: HtlcParams, + start_of_swap: NaiveDateTime, +) -> anyhow::Result<()> +where + C: HtlcFunded + + HtlcDeployed + + HtlcRedeemed + + HtlcRefunded, + Deployed: Clone, + Redeemed: Clone, + Refunded: Clone, +{ + let deployed = ethereum_connector + .htlc_deployed(&htlc_params, start_of_swap) + .await?; + co.yield_(SwapEvent::Deployed(deployed.clone())).await; + + let funded = ethereum_connector + .htlc_funded(&htlc_params, &deployed, start_of_swap) + .await?; + co.yield_(SwapEvent::Funded(funded)).await; + + let redeemed = ethereum_connector.htlc_redeemed(&htlc_params, &deployed, start_of_swap); + + let refunded = ethereum_connector.htlc_refunded(&htlc_params, &deployed, start_of_swap); + + match future::try_select(redeemed, refunded).await { + Ok(Either::Left((redeemed, _))) => { + co.yield_(SwapEvent::Redeemed(redeemed.clone())).await; + } + Ok(Either::Right((refunded, _))) => { + co.yield_(SwapEvent::Refunded(refunded.clone())).await; + } + Err(either) => { + let (error, _other_future) = either.factor_first(); + + return Err(error); + } + } + + Ok(()) +} diff --git a/cnd/src/swap_protocols/ledger.rs b/cnd/src/swap_protocols/ledger.rs index ddec602951..05b8cf4c91 100644 --- a/cnd/src/swap_protocols/ledger.rs +++ b/cnd/src/swap_protocols/ledger.rs @@ -1,4 +1,5 @@ pub mod bitcoin; pub mod ethereum; +pub mod lightning; pub use self::{bitcoin::Bitcoin, ethereum::Ethereum}; diff --git a/cnd/src/swap_protocols/ledger/lightning.rs b/cnd/src/swap_protocols/ledger/lightning.rs new file mode 100644 index 0000000000..80eb4d5765 --- /dev/null +++ b/cnd/src/swap_protocols/ledger/lightning.rs @@ -0,0 +1,8 @@ +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct Mainnet; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct Testnet; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct Regtest; diff --git a/cnd/src/swap_protocols/rfc003/actions.rs b/cnd/src/swap_protocols/rfc003/actions.rs index a14a23892f..5a3fdc2768 100644 --- a/cnd/src/swap_protocols/rfc003/actions.rs +++ b/cnd/src/swap_protocols/rfc003/actions.rs @@ -21,20 +21,20 @@ pub enum Action { Refund(Refund), } -pub trait FundAction { +pub trait MakeFundAction { type HtlcParams; type Output; - fn fund_action(htlc_params: Self::HtlcParams) -> Self::Output; + fn make_fund_action(htlc_params: Self::HtlcParams) -> Self::Output; } -pub trait RefundAction { +pub trait MakeRefundAction { type HtlcParams; type HtlcLocation; type FundTransaction; type Output; - fn refund_action( + fn make_refund_action( htlc_params: Self::HtlcParams, htlc_location: Self::HtlcLocation, secret_source: &dyn DeriveIdentities, @@ -42,12 +42,12 @@ pub trait RefundAction { ) -> Self::Output; } -pub trait RedeemAction { +pub trait MakeRedeemAction { type HtlcParams; type HtlcLocation; type Output; - fn redeem_action( + fn make_redeem_action( htlc_params: Self::HtlcParams, htlc_location: Self::HtlcLocation, secret_source: &dyn DeriveIdentities, diff --git a/cnd/src/swap_protocols/rfc003/actions/bitcoin.rs b/cnd/src/swap_protocols/rfc003/actions/bitcoin.rs index a2859065b0..db9d8ae03c 100644 --- a/cnd/src/swap_protocols/rfc003/actions/bitcoin.rs +++ b/cnd/src/swap_protocols/rfc003/actions/bitcoin.rs @@ -4,7 +4,7 @@ use crate::{ actions::bitcoin::{SendToAddress, SpendOutput}, ledger, rfc003::{ - actions::{FundAction, RedeemAction, RefundAction}, + actions::{MakeFundAction, MakeRedeemAction, MakeRefundAction}, create_swap::HtlcParams, DeriveIdentities, Secret, }, @@ -13,14 +13,14 @@ use crate::{ use ::bitcoin::{Amount, OutPoint, Transaction}; use blockchain_contracts::bitcoin::{rfc003::bitcoin_htlc::BitcoinHtlc, witness::PrimedInput}; -impl FundAction for (B, asset::Bitcoin) +impl MakeFundAction for (B, asset::Bitcoin) where B: ledger::Bitcoin + ledger::bitcoin::Network, { type HtlcParams = HtlcParams; type Output = SendToAddress; - fn fund_action(htlc_params: Self::HtlcParams) -> Self::Output { + fn make_fund_action(htlc_params: Self::HtlcParams) -> Self::Output { let to = htlc_params.compute_address(); SendToAddress { @@ -31,7 +31,7 @@ where } } -impl RefundAction for (B, asset::Bitcoin) +impl MakeRefundAction for (B, asset::Bitcoin) where B: ledger::Bitcoin + ledger::bitcoin::Network, { @@ -40,7 +40,7 @@ where type FundTransaction = Transaction; type Output = SpendOutput; - fn refund_action( + fn make_refund_action( htlc_params: Self::HtlcParams, htlc_location: Self::HtlcLocation, secret_source: &dyn DeriveIdentities, @@ -59,7 +59,7 @@ where } } -impl RedeemAction for (B, asset::Bitcoin) +impl MakeRedeemAction for (B, asset::Bitcoin) where B: ledger::Bitcoin + ledger::bitcoin::Network, { @@ -67,7 +67,7 @@ where type HtlcLocation = OutPoint; type Output = SpendOutput; - fn redeem_action( + fn make_redeem_action( htlc_params: Self::HtlcParams, htlc_location: Self::HtlcLocation, secret_source: &dyn DeriveIdentities, diff --git a/cnd/src/swap_protocols/rfc003/actions/erc20.rs b/cnd/src/swap_protocols/rfc003/actions/erc20.rs index 8d8cdfd4a3..7276da3031 100644 --- a/cnd/src/swap_protocols/rfc003/actions/erc20.rs +++ b/cnd/src/swap_protocols/rfc003/actions/erc20.rs @@ -21,7 +21,7 @@ pub fn deploy_action( DeployContract { data: htlc.into(), amount: asset::Ether::zero(), - gas_limit: gas_limit.into(), + gas_limit, chain_id, } } @@ -41,7 +41,7 @@ pub fn fund_action( CallContract { to: to_erc20_contract, data: Some(Bytes(data)), - gas_limit: gas_limit.into(), + gas_limit, chain_id, min_block_timestamp: None, } @@ -58,7 +58,7 @@ pub fn refund_action( CallContract { to: beta_htlc_location, data: Some(data), - gas_limit: gas_limit.into(), + gas_limit, chain_id, min_block_timestamp: Some(expiry), } @@ -75,7 +75,7 @@ pub fn redeem_action( CallContract { to: alpha_htlc_location, data: Some(data), - gas_limit: gas_limit.into(), + gas_limit, chain_id, min_block_timestamp: None, } diff --git a/cnd/src/swap_protocols/rfc003/actions/ether.rs b/cnd/src/swap_protocols/rfc003/actions/ether.rs index a19e80a69b..5531760cb3 100644 --- a/cnd/src/swap_protocols/rfc003/actions/ether.rs +++ b/cnd/src/swap_protocols/rfc003/actions/ether.rs @@ -6,7 +6,7 @@ use crate::{ actions::ethereum::{CallContract, DeployContract}, ledger::Ethereum, rfc003::{ - actions::{FundAction, RedeemAction, RefundAction}, + actions::{MakeFundAction, MakeRedeemAction, MakeRefundAction}, create_swap::HtlcParams, DeriveIdentities, Secret, }, @@ -14,30 +14,30 @@ use crate::{ }; use blockchain_contracts::ethereum::rfc003::ether_htlc::EtherHtlc; -impl FundAction for (Ethereum, asset::Ether) { +impl MakeFundAction for (Ethereum, asset::Ether) { type HtlcParams = HtlcParams; type Output = DeployContract; - fn fund_action(htlc_params: Self::HtlcParams) -> Self::Output { + fn make_fund_action(htlc_params: Self::HtlcParams) -> Self::Output { let htlc = EtherHtlc::from(htlc_params.clone()); let gas_limit = EtherHtlc::deploy_tx_gas_limit(); DeployContract { data: htlc.into(), amount: htlc_params.asset.clone(), - gas_limit: gas_limit.into(), + gas_limit, chain_id: htlc_params.ledger.chain_id, } } } -impl RefundAction for (Ethereum, asset::Ether) { +impl MakeRefundAction for (Ethereum, asset::Ether) { type HtlcParams = HtlcParams; type HtlcLocation = htlc_location::Ethereum; type FundTransaction = Transaction; type Output = CallContract; - fn refund_action( + fn make_refund_action( htlc_params: Self::HtlcParams, htlc_location: Self::HtlcLocation, _secret_source: &dyn DeriveIdentities, @@ -48,19 +48,19 @@ impl RefundAction for (Ethereum, asset::Ether) { CallContract { to: htlc_location, data: None, - gas_limit: gas_limit.into(), + gas_limit, chain_id: htlc_params.ledger.chain_id, min_block_timestamp: Some(htlc_params.expiry), } } } -impl RedeemAction for (Ethereum, asset::Ether) { +impl MakeRedeemAction for (Ethereum, asset::Ether) { type HtlcParams = HtlcParams; type HtlcLocation = htlc_location::Ethereum; type Output = CallContract; - fn redeem_action( + fn make_redeem_action( htlc_params: Self::HtlcParams, htlc_location: Self::HtlcLocation, _secret_source: &dyn DeriveIdentities, @@ -72,7 +72,7 @@ impl RedeemAction for (Ethereum, asset::Ether) { CallContract { to: htlc_location, data: Some(data), - gas_limit: gas_limit.into(), + gas_limit, chain_id: htlc_params.ledger.chain_id, min_block_timestamp: None, } diff --git a/cnd/src/swap_protocols/rfc003/alice/actions/erc20.rs b/cnd/src/swap_protocols/rfc003/alice/actions/erc20.rs index 844e1cb1a3..f49865074b 100644 --- a/cnd/src/swap_protocols/rfc003/alice/actions/erc20.rs +++ b/cnd/src/swap_protocols/rfc003/alice/actions/erc20.rs @@ -5,7 +5,9 @@ use crate::{ actions::{ethereum, Actions}, ledger::Ethereum, rfc003::{ - actions::{erc20, Accept, Action, Decline, FundAction, RedeemAction, RefundAction}, + actions::{ + erc20, Accept, Action, Decline, MakeFundAction, MakeRedeemAction, MakeRefundAction, + }, alice, create_swap::HtlcParams, DeriveSecret, LedgerState, SwapCommunication, @@ -34,7 +36,7 @@ where BH: Clone, BI: Clone, BT: Clone, - (BL, BA): RedeemAction, HtlcLocation = BH>, + (BL, BA): MakeRedeemAction, HtlcLocation = BH>, { #[allow(clippy::type_complexity)] type ActionKind = Action< @@ -42,7 +44,7 @@ where Decline, ethereum::DeployContract, ethereum::CallContract, - <(BL, BA) as RedeemAction>::Output, + <(BL, BA) as MakeRedeemAction>::Output, ethereum::CallContract, >; @@ -77,7 +79,7 @@ where }; if let Funded { htlc_location, .. } = beta_state { - actions.push(Action::Redeem(<(BL, BA)>::redeem_action( + actions.push(Action::Redeem(<(BL, BA)>::make_redeem_action( HtlcParams::new_beta_params(request, response), htlc_location.clone(), &self.secret_source, // Derive identities with this. @@ -107,17 +109,21 @@ where AH: Copy, AI: Clone, AT: Clone, - (AL, AA): FundAction> - + RefundAction, HtlcLocation = AH, FundTransaction = AT>, + (AL, AA): MakeFundAction> + + MakeRefundAction< + HtlcParams = HtlcParams, + HtlcLocation = AH, + FundTransaction = AT, + >, { #[allow(clippy::type_complexity)] type ActionKind = Action< Accept, Decline, Infallible, - <(AL, AA) as FundAction>::Output, + <(AL, AA) as MakeFundAction>::Output, ethereum::CallContract, - <(AL, AA) as RefundAction>::Output, + <(AL, AA) as MakeRefundAction>::Output, >; fn actions(&self) -> Vec { @@ -134,14 +140,14 @@ where use self::LedgerState::*; let mut actions = match alpha_state { - NotDeployed => vec![Action::Fund(<(AL, AA)>::fund_action( + NotDeployed => vec![Action::Fund(<(AL, AA)>::make_fund_action( HtlcParams::new_alpha_params(request, response), ))], Funded { htlc_location, fund_transaction, .. - } => vec![Action::Refund(<(AL, AA)>::refund_action( + } => vec![Action::Refund(<(AL, AA)>::make_refund_action( HtlcParams::new_alpha_params(request, response), *htlc_location, &self.secret_source, diff --git a/cnd/src/swap_protocols/rfc003/alice/actions/generic_impl.rs b/cnd/src/swap_protocols/rfc003/alice/actions/generic_impl.rs index 57f959f287..39d4b0e4e8 100644 --- a/cnd/src/swap_protocols/rfc003/alice/actions/generic_impl.rs +++ b/cnd/src/swap_protocols/rfc003/alice/actions/generic_impl.rs @@ -1,7 +1,7 @@ use crate::swap_protocols::{ actions::Actions, rfc003::{ - actions::{Accept, Action, Decline, FundAction, RedeemAction, RefundAction}, + actions::{Accept, Action, Decline, MakeFundAction, MakeRedeemAction, MakeRefundAction}, alice, create_swap::HtlcParams, DeriveSecret, LedgerState, SwapCommunication, @@ -22,18 +22,22 @@ where BI: Clone, AT: Clone, BT: Clone, - (AL, AA): FundAction> - + RefundAction, HtlcLocation = AH, FundTransaction = AT>, - (BL, BA): RedeemAction, HtlcLocation = BH>, + (AL, AA): MakeFundAction> + + MakeRefundAction< + HtlcParams = HtlcParams, + HtlcLocation = AH, + FundTransaction = AT, + >, + (BL, BA): MakeRedeemAction, HtlcLocation = BH>, { #[allow(clippy::type_complexity)] type ActionKind = Action< Accept, Decline, Infallible, - <(AL, AA) as FundAction>::Output, - <(BL, BA) as RedeemAction>::Output, - <(AL, AA) as RefundAction>::Output, + <(AL, AA) as MakeFundAction>::Output, + <(BL, BA) as MakeRedeemAction>::Output, + <(AL, AA) as MakeRefundAction>::Output, >; fn actions(&self) -> Vec { @@ -49,7 +53,7 @@ where use self::LedgerState::*; let mut actions = match alpha_state { - NotDeployed => vec![Action::Fund(<(AL, AA)>::fund_action( + NotDeployed => vec![Action::Fund(<(AL, AA)>::make_fund_action( HtlcParams::new_alpha_params(request, response), ))], Funded { @@ -61,7 +65,7 @@ where htlc_location, fund_transaction, .. - } => vec![Action::Refund(<(AL, AA)>::refund_action( + } => vec![Action::Refund(<(AL, AA)>::make_refund_action( HtlcParams::new_alpha_params(request, response), htlc_location.clone(), &self.secret_source, @@ -71,7 +75,7 @@ where }; if let Funded { htlc_location, .. } = beta_state { - actions.push(Action::Redeem(<(BL, BA)>::redeem_action( + actions.push(Action::Redeem(<(BL, BA)>::make_redeem_action( HtlcParams::new_beta_params(request, response), htlc_location.clone(), &self.secret_source, // Derive identities with this. diff --git a/cnd/src/swap_protocols/rfc003/bob/actions/erc20.rs b/cnd/src/swap_protocols/rfc003/bob/actions/erc20.rs index b6db96b1d5..e5a7d510d1 100644 --- a/cnd/src/swap_protocols/rfc003/bob/actions/erc20.rs +++ b/cnd/src/swap_protocols/rfc003/bob/actions/erc20.rs @@ -5,7 +5,9 @@ use crate::{ actions::{ethereum, Actions}, ledger::Ethereum, rfc003::{ - actions::{erc20, Accept, Action, Decline, FundAction, RedeemAction, RefundAction}, + actions::{ + erc20, Accept, Action, Decline, MakeFundAction, MakeRedeemAction, MakeRefundAction, + }, bob, create_swap::HtlcParams, LedgerState, SwapCommunication, @@ -34,7 +36,7 @@ where AH: Clone, AI: Clone, AT: Clone, - (AL, AA): RedeemAction, HtlcLocation = AH>, + (AL, AA): MakeRedeemAction, HtlcLocation = AH>, { #[allow(clippy::type_complexity)] type ActionKind = Action< @@ -42,7 +44,7 @@ where Decline, ethereum::DeployContract, ethereum::CallContract, - <(AL, AA) as RedeemAction>::Output, + <(AL, AA) as MakeRedeemAction>::Output, ethereum::CallContract, >; @@ -68,7 +70,7 @@ where let mut actions = match (alpha_state, beta_state) { (Funded { htlc_location, .. }, Redeemed { secret, .. }) => { - vec![Action::Redeem(<(AL, AA)>::redeem_action( + vec![Action::Redeem(<(AL, AA)>::make_redeem_action( HtlcParams::new_alpha_params(request, response), htlc_location.clone(), &*self.secret_source, // Derive identities with this. @@ -119,17 +121,21 @@ where BH: Clone, BI: Clone, BT: Clone, - (BL, BA): FundAction> - + RefundAction, HtlcLocation = BH, FundTransaction = BT>, + (BL, BA): MakeFundAction> + + MakeRefundAction< + HtlcParams = HtlcParams, + HtlcLocation = BH, + FundTransaction = BT, + >, { #[allow(clippy::type_complexity)] type ActionKind = Action< Accept, Decline, Infallible, - <(BL, BA) as FundAction>::Output, + <(BL, BA) as MakeFundAction>::Output, ethereum::CallContract, - <(BL, BA) as RefundAction>::Output, + <(BL, BA) as MakeRefundAction>::Output, >; fn actions(&self) -> Vec { @@ -155,7 +161,7 @@ where (Funded { htlc_location, .. }, Redeemed { secret, .. }) => vec![Action::Redeem( erc20::redeem_action(*htlc_location, *secret, request.alpha_ledger.chain_id), )], - (Funded { .. }, NotDeployed) => vec![Action::Fund(<(BL, BA)>::fund_action( + (Funded { .. }, NotDeployed) => vec![Action::Fund(<(BL, BA)>::make_fund_action( HtlcParams::new_beta_params(request, response), ))], _ => vec![], @@ -167,7 +173,7 @@ where .. } = beta_state { - actions.push(Action::Refund(<(BL, BA)>::refund_action( + actions.push(Action::Refund(<(BL, BA)>::make_refund_action( HtlcParams::new_beta_params(request, response), htlc_location.clone(), &*self.secret_source, diff --git a/cnd/src/swap_protocols/rfc003/bob/actions/generic_impl.rs b/cnd/src/swap_protocols/rfc003/bob/actions/generic_impl.rs index 1942232c5b..b6732f2e4d 100644 --- a/cnd/src/swap_protocols/rfc003/bob/actions/generic_impl.rs +++ b/cnd/src/swap_protocols/rfc003/bob/actions/generic_impl.rs @@ -1,7 +1,7 @@ use crate::swap_protocols::{ actions::Actions, rfc003::{ - actions::{Accept, Action, Decline, FundAction, RedeemAction, RefundAction}, + actions::{Accept, Action, Decline, MakeFundAction, MakeRedeemAction, MakeRefundAction}, bob, create_swap::HtlcParams, LedgerState, SwapCommunication, @@ -22,18 +22,22 @@ where BI: Clone, AT: Clone, BT: Clone, - (BL, BA): FundAction> - + RefundAction, HtlcLocation = BH, FundTransaction = BT>, - (AL, AA): RedeemAction, HtlcLocation = AH>, + (BL, BA): MakeFundAction> + + MakeRefundAction< + HtlcParams = HtlcParams, + HtlcLocation = BH, + FundTransaction = BT, + >, + (AL, AA): MakeRedeemAction, HtlcLocation = AH>, { #[allow(clippy::type_complexity)] type ActionKind = Action< Accept, Decline, Infallible, - <(BL, BA) as FundAction>::Output, - <(AL, AA) as RedeemAction>::Output, - <(BL, BA) as RefundAction>::Output, + <(BL, BA) as MakeFundAction>::Output, + <(AL, AA) as MakeRedeemAction>::Output, + <(BL, BA) as MakeRefundAction>::Output, >; fn actions(&self) -> Vec { @@ -57,7 +61,7 @@ where use self::LedgerState::*; let mut actions = match (alpha_state, beta_state) { (Funded { htlc_location, .. }, Redeemed { secret, .. }) => { - vec![Action::Redeem(<(AL, AA)>::redeem_action( + vec![Action::Redeem(<(AL, AA)>::make_redeem_action( HtlcParams::new_alpha_params(request, response), htlc_location.clone(), &*self.secret_source, // Derive identities with this. @@ -65,7 +69,7 @@ where * action. */ ))] } - (Funded { .. }, NotDeployed) => vec![Action::Fund(<(BL, BA)>::fund_action( + (Funded { .. }, NotDeployed) => vec![Action::Fund(<(BL, BA)>::make_fund_action( HtlcParams::new_beta_params(request, response), ))], _ => vec![], @@ -82,7 +86,7 @@ where .. } = beta_state { - actions.push(Action::Refund(<(BL, BA)>::refund_action( + actions.push(Action::Refund(<(BL, BA)>::make_refund_action( HtlcParams::new_beta_params(request, response), htlc_location.clone(), &*self.secret_source, diff --git a/cnd/src/swap_protocols/rfc003/ethereum.rs b/cnd/src/swap_protocols/rfc003/ethereum.rs index bbfe3fa46a..6ffca667fd 100644 --- a/cnd/src/swap_protocols/rfc003/ethereum.rs +++ b/cnd/src/swap_protocols/rfc003/ethereum.rs @@ -51,7 +51,7 @@ impl From> for Erc20Htlc } impl HtlcParams { - pub fn bytecode(self) -> Bytes { - Erc20Htlc::from(self).into() + pub fn bytecode(&self) -> Bytes { + Erc20Htlc::from(self.clone()).into() } } diff --git a/cnd/src/swap_protocols/rfc003/ethereum/htlc_events.rs b/cnd/src/swap_protocols/rfc003/ethereum/htlc_events.rs index 4b8b03a165..69922153fe 100644 --- a/cnd/src/swap_protocols/rfc003/ethereum/htlc_events.rs +++ b/cnd/src/swap_protocols/rfc003/ethereum/htlc_events.rs @@ -119,7 +119,11 @@ impl }; let (transaction, log) = watch_for_event(self, start_of_swap, event) - .instrument(tracing::info_span!("htlc_redeemed")) + .instrument(tracing::trace_span!( + "htlc_redeemed", + htlc = format_args!("{:x}", htlc_deployment.location), + topic = format_args!("{:x}", *REDEEM_LOG_MSG) + )) .await?; let log_data = log.data.0.as_ref(); @@ -155,7 +159,11 @@ impl }; let (transaction, _) = watch_for_event(self, start_of_swap, event) - .instrument(tracing::info_span!("htlc_refunded")) + .instrument(tracing::trace_span!( + "htlc_refunded", + htlc = format_args!("{:x}", htlc_deployment.location), + topic = format_args!("{:x}", *REFUND_LOG_MSG) + )) .await?; Ok(Refunded { transaction }) @@ -188,7 +196,7 @@ impl }; let (transaction, log) = watch_for_event(self, start_of_swap, event) - .instrument(tracing::info_span!("htlc_funded")) + .instrument(tracing::trace_span!("htlc_funded")) .await?; let expected_asset = &htlc_params.asset; diff --git a/cnd/src/swap_protocols/swap_id.rs b/cnd/src/swap_protocols/swap_id.rs index ac53cad8a1..fae56e083f 100644 --- a/cnd/src/swap_protocols/swap_id.rs +++ b/cnd/src/swap_protocols/swap_id.rs @@ -35,3 +35,40 @@ impl fmt::Display for SwapId { self.0.fmt(f) } } + +/// This is an identifier created, and used locally, by a node to identify a +/// swap created by this node i.e., when a node is acting in the role of Alice +/// we need an identifier. +#[derive(Serialize, Deserialize, Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct NodeLocalSwapId(pub Uuid); + +impl Default for NodeLocalSwapId { + fn default() -> Self { + NodeLocalSwapId(Uuid::new_v4()) + } +} + +impl FromStr for NodeLocalSwapId { + type Err = uuid::Error; + fn from_str(s: &str) -> Result { + Uuid::from_str(s).map(NodeLocalSwapId) + } +} + +impl From for NodeLocalSwapId { + fn from(uuid: Uuid) -> Self { + NodeLocalSwapId(uuid) + } +} + +impl From for Uuid { + fn from(swap_id: NodeLocalSwapId) -> Self { + swap_id.0 + } +} + +impl fmt::Display for NodeLocalSwapId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + self.0.fmt(f) + } +} diff --git a/cnd/src/timestamp.rs b/cnd/src/timestamp.rs index e4adc6cca2..f0fa2886f5 100644 --- a/cnd/src/timestamp.rs +++ b/cnd/src/timestamp.rs @@ -20,6 +20,10 @@ impl Timestamp { pub fn plus(self, seconds: u32) -> Self { Self(self.0.checked_add(seconds).unwrap_or(std::u32::MAX)) } + + pub fn to_bytes(self) -> [u8; 4] { + self.0.to_le_bytes() + } } impl From for Timestamp { From dc805ba0c249a519dc0e09be5507dbf595bcca3b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2020 14:13:15 +0000 Subject: [PATCH 75/88] Bump structopt from 0.3.12 to 0.3.13 Bumps [structopt](https://github.com/TeXitoi/structopt) from 0.3.12 to 0.3.13. - [Release notes](https://github.com/TeXitoi/structopt/releases) - [Changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md) - [Commits](https://github.com/TeXitoi/structopt/commits) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a903703b85..909201f5d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1116,7 +1116,7 @@ version = "0.99.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784f84eebc366e15251c4a8c3acee82a6a6f427949776ecb88377362a9621738" dependencies = [ - "proc-macro-error", + "proc-macro-error 0.4.9", "proc-macro-hack", "proc-macro2 1.0.10", "quote 1.0.3", @@ -2444,13 +2444,26 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "052b3c9af39c7e5e94245f820530487d19eb285faedcb40e0c3275132293f242" dependencies = [ - "proc-macro-error-attr", + "proc-macro-error-attr 0.4.9", "proc-macro2 1.0.10", "quote 1.0.3", "rustversion", "syn 1.0.17", ] +[[package]] +name = "proc-macro-error" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8931031034aa65c73f3f1a05c3ec0fa51287fcd06557ecf4e88b2768bdca375e" +dependencies = [ + "proc-macro-error-attr 1.0.1", + "proc-macro2 1.0.10", + "quote 1.0.3", + "syn 1.0.17", + "version_check 0.9.1", +] + [[package]] name = "proc-macro-error-attr" version = "0.4.9" @@ -2464,6 +2477,19 @@ dependencies = [ "syn-mid", ] +[[package]] +name = "proc-macro-error-attr" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2147536f412ee7ae5529364ed50172ca0220fd64591e236296f45f36b38b2f98" +dependencies = [ + "proc-macro2 1.0.10", + "quote 1.0.3", + "syn 1.0.17", + "syn-mid", + "version_check 0.9.1", +] + [[package]] name = "proc-macro-hack" version = "0.5.11" @@ -3155,9 +3181,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8faa2719539bbe9d77869bfb15d4ee769f99525e707931452c97b693b3f159d" +checksum = "ff6da2e8d107dfd7b74df5ef4d205c6aebee0706c647f6bc6a2d5789905c00fb" dependencies = [ "clap", "lazy_static", @@ -3166,12 +3192,12 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f88b8e18c69496aad6f9ddf4630dd7d585bcaf765786cb415b9aec2fe5a0430" +checksum = "a489c87c08fbaf12e386665109dd13470dcc9c4583ea3e10dd2b4523e5ebd9ac" dependencies = [ "heck", - "proc-macro-error", + "proc-macro-error 1.0.1", "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", From a86bf5d758530ab8afc2f990451a8735eb41454b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2020 14:58:34 +0000 Subject: [PATCH 76/88] Bump download from 7.1.0 to 8.0.0 in /api_tests Bumps [download](https://github.com/kevva/download) from 7.1.0 to 8.0.0. - [Release notes](https://github.com/kevva/download/releases) - [Commits](https://github.com/kevva/download/compare/v7.1.0...v8.0.0) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 100 +++++++++++++++-------------------------- 2 files changed, 38 insertions(+), 64 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 8e94c272a3..e7b3d42255 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -47,7 +47,7 @@ "chai-subset": "^1.6.0", "chmod": "^0.2.1", "comit-sdk": "^0.15.2", - "download": "^7.1.0", + "download": "^8.0.0", "ethers": "^4.0.46", "find-cache-dir": "^3.3.1", "get-port": "^5.1.1", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index b39fbede6e..21cfc6f648 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -1604,16 +1604,6 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -caw@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/caw/-/caw-2.0.1.tgz#6c3ca071fc194720883c2dc5da9b074bfc7e9e95" - integrity sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA== - dependencies: - get-proxy "^2.0.0" - isurl "^1.0.0-alpha5" - tunnel-agent "^0.6.0" - url-to-options "^1.0.1" - chai-as-promised@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" @@ -1852,14 +1842,6 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -config-chain@^1.1.11: - version "1.1.12" - resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" - integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== - dependencies: - ini "^1.3.4" - proto-list "~1.2.1" - console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" @@ -2064,7 +2046,7 @@ decompress-unzip@^4.0.1: pify "^2.3.0" yauzl "^2.4.2" -decompress@^4.2.0: +decompress@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118" integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ== @@ -2174,23 +2156,22 @@ domexception@^1.0.1: dependencies: webidl-conversions "^4.0.2" -download@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/download/-/download-7.1.0.tgz#9059aa9d70b503ee76a132897be6dec8e5587233" - integrity sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ== +download@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/download/-/download-8.0.0.tgz#afc0b309730811731aae9f5371c9f46be73e51b1" + integrity sha512-ASRY5QhDk7FK+XrQtQyvhpDKanLluEEQtWl/J7Lxuf/b+i8RYh997QeXvL85xitrmRKVlx9c7eTrcRdq2GS4eA== dependencies: archive-type "^4.0.0" - caw "^2.0.1" content-disposition "^0.5.2" - decompress "^4.2.0" + decompress "^4.2.1" ext-name "^5.0.0" - file-type "^8.1.0" - filenamify "^2.0.0" - get-stream "^3.0.0" + file-type "^11.1.0" + filenamify "^3.0.0" + get-stream "^4.1.0" got "^8.3.1" - make-dir "^1.2.0" + make-dir "^2.1.0" p-event "^2.1.0" - pify "^3.0.0" + pify "^4.0.1" dtrace-provider@~0.8: version "0.8.8" @@ -2492,6 +2473,11 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" +file-type@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-11.1.0.tgz#93780f3fed98b599755d846b99a1617a2ad063b8" + integrity sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g== + file-type@^3.8.0: version "3.9.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" @@ -2512,20 +2498,15 @@ file-type@^6.1.0: resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== -file-type@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-8.1.0.tgz#244f3b7ef641bbe0cca196c7276e4b332399f68c" - integrity sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ== - filename-reserved-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" integrity sha1-q/c9+rc10EVECr/qLZHzieu/oik= -filenamify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-2.1.0.tgz#88faf495fb1b47abfd612300002a16228c677ee9" - integrity sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA== +filenamify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-3.0.0.tgz#9603eb688179f8c5d40d828626dcbb92c3a4672c" + integrity sha512-5EFZ//MsvJgXjBAFJ+Bh2YaCTRF/VP1YOmGrgt+KJ4SFRLjI87EIdwLLuT6wQX0I4F9W41xutobzczjsOKlI/g== dependencies: filename-reserved-regex "^2.0.0" strip-outer "^1.0.0" @@ -2720,13 +2701,6 @@ get-port@^5.1.1: resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== -get-proxy@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/get-proxy/-/get-proxy-2.1.0.tgz#349f2b4d91d44c4d4d4e9cba2ad90143fac5ef93" - integrity sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw== - dependencies: - npm-conf "^1.1.0" - get-stream@3.0.0, get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -2740,7 +2714,7 @@ get-stream@^2.2.0: object-assign "^4.0.1" pinkie-promise "^2.0.0" -get-stream@^4.0.0: +get-stream@^4.0.0, get-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== @@ -3048,7 +3022,7 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@^1.3.4, ini@~1.3.0: +ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== @@ -3943,13 +3917,21 @@ lowercase-keys@^1.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== -make-dir@^1.0.0, make-dir@^1.2.0: +make-dir@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== dependencies: pify "^3.0.0" +make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + make-dir@^3.0.0, make-dir@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.2.tgz#04a1acbf22221e1d6ef43559f43e05a90dbb4392" @@ -4278,14 +4260,6 @@ npm-bundled@^1.0.1: dependencies: npm-normalize-package-bin "^1.0.1" -npm-conf@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" - integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw== - dependencies: - config-chain "^1.1.11" - pify "^3.0.0" - npm-normalize-package-bin@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" @@ -4601,6 +4575,11 @@ pify@^3.0.0: resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" @@ -4698,11 +4677,6 @@ proper-lockfile@^4.1.1: retry "^0.12.0" signal-exit "^3.0.2" -proto-list@~1.2.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" - integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= - protobufjs@^5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-5.0.3.tgz#e4dfe9fb67c90b2630d15868249bcc4961467a17" @@ -5065,7 +5039,7 @@ semver@6.x, semver@^6.0.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: +semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== From 7c8fe83f1442092dbce90581f745fcb9b99555ca Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Wed, 8 Apr 2020 10:12:34 +1000 Subject: [PATCH 77/88] Do not start cnd if we cannot bind to HTTP API port If the HTTP API port is in use we should exit cnd. Using the `serve_incoming` warp method we can first bind, checking for failure, and then spawn the warp server. --- cnd/src/main.rs | 20 +++++++++++++------- cnd/src/network.rs | 9 +++++---- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/cnd/src/main.rs b/cnd/src/main.rs index 775ee4be6b..3ccce0df5c 100644 --- a/cnd/src/main.rs +++ b/cnd/src/main.rs @@ -37,7 +37,7 @@ use cnd::{ use rand::rngs::OsRng; use std::{process, sync::Arc}; use structopt::StructOpt; -use tokio::runtime; +use tokio::{net::TcpListener, runtime}; mod cli; mod trace; @@ -165,10 +165,10 @@ fn main() -> anyhow::Result<()> { }; runtime.block_on(load_swaps::load_swaps_from_database(deps.clone()))?; - runtime.spawn(spawn_warp_instance(settings, deps, facade2)); - // Block the current thread. - ::std::thread::park(); + let http_server_future = spawn_warp_instance(settings, deps, facade2); + runtime.block_on(http_server_future)?; + Ok(()) } @@ -183,7 +183,11 @@ fn version() { println!("{} {} ({})", name, version, short); } -async fn spawn_warp_instance(settings: Settings, dependencies: Facade, facade2: Facade2) { +async fn spawn_warp_instance( + settings: Settings, + dependencies: Facade, + facade2: Facade2, +) -> anyhow::Result<()> { let routes = route_factory::create( dependencies, facade2, @@ -191,10 +195,12 @@ async fn spawn_warp_instance(settings: Settings, dependencies: Facade, facade2: ); let listen_addr = settings.http_api.socket; + let listener = TcpListener::bind(listen_addr).await?; - tracing::info!("Starting HTTP server on {}", listen_addr); + tracing::info!("Starting HTTP server on {} ...", listen_addr); + warp::serve(routes).serve_incoming(listener).await; - warp::serve(routes).bind(listen_addr).await + Ok(()) } #[allow(clippy::print_stdout)] // We cannot use `log` before we have the config file diff --git a/cnd/src/network.rs b/cnd/src/network.rs index 3d7882b868..726f49ea37 100644 --- a/cnd/src/network.rs +++ b/cnd/src/network.rs @@ -34,6 +34,7 @@ use crate::{ }, transaction, }; +use anyhow::Context; use async_trait::async_trait; use futures::{ channel::oneshot::{self, Sender}, @@ -58,7 +59,7 @@ use std::{ io, pin::Pin, sync::Arc, - task::{Context, Poll}, + task::{self, Poll}, }; use tokio::{ runtime::{Handle, Runtime}, @@ -114,8 +115,8 @@ impl Swarm { .build(); for addr in settings.network.listen.clone() { - libp2p::Swarm::listen_on(&mut swarm, addr) - .expect("Could not listen on specified address"); + libp2p::Swarm::listen_on(&mut swarm, addr.clone()) + .with_context(|| format!("Address is not supported: {:?}", addr))?; } let swarm = Arc::new(Mutex::new(swarm)); @@ -184,7 +185,7 @@ struct SwarmWorker { impl futures::Future for SwarmWorker { type Output = (); - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll { loop { let mutex = self.swarm.lock(); futures::pin_mut!(mutex); From ed0857d19beba08ce059d04c898c1c62bb5ecbbf Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 9 Apr 2020 13:40:25 +1000 Subject: [PATCH 78/88] Use swap factory for for all halight dry tests --- api_tests/src/actors/swap_factory.ts | 311 ++++++++++++++++----------- api_tests/tests/ether_halight.ts | 7 +- api_tests/tests/lightning_routes.ts | 102 +++++---- 3 files changed, 244 insertions(+), 176 deletions(-) diff --git a/api_tests/src/actors/swap_factory.ts b/api_tests/src/actors/swap_factory.ts index 8273cdc0b9..6ef3fe2de0 100644 --- a/api_tests/src/actors/swap_factory.ts +++ b/api_tests/src/actors/swap_factory.ts @@ -19,18 +19,36 @@ import { Herc20EthereumErc20RequestParams, Peer, } from "comit-sdk"; +import { HarnessGlobal } from "../utils"; + +declare var global: HarnessGlobal; export default class SwapFactory { public static async newSwap( alice: Actor, - bob: Actor - ): Promise< - [ - HanEthereumEtherHalightLightningBitcoinRequestBody, - HanEthereumEtherHalightLightningBitcoinRequestBody - ] - > { - const ledgers: (keyof AllWallets)[] = ["ethereum", "lightning"]; + bob: Actor, + dry?: boolean + ): Promise<{ + hanEthereumEtherHalightLightningBitcoin: { + alice: HanEthereumEtherHalightLightningBitcoinRequestBody; + bob: HanEthereumEtherHalightLightningBitcoinRequestBody; + }; + herc20EthereumErc20HalightLightningBitcoin: { + alice: Herc20EthereumErc20HalightLightningBitcoinRequestBody; + bob: Herc20EthereumErc20HalightLightningBitcoinRequestBody; + }; + halightLightningBitcoinHanEthereumEther: { + alice: HalightLightningBitcoinHanEthereumEtherRequestBody; + bob: HalightLightningBitcoinHanEthereumEtherRequestBody; + }; + halightLightningBitcoinHerc20EthereumErc20: { + alice: HalightLightningBitcoinHerc20EthereumErc20RequestBody; + bob: HalightLightningBitcoinHerc20EthereumErc20RequestBody; + }; + }> { + const ledgers: (keyof AllWallets)[] = dry + ? [] + : ["ethereum", "lightning"]; for (const ledger of ledgers) { await alice.wallets.initializeForLedger( @@ -41,48 +59,169 @@ export default class SwapFactory { await bob.wallets.initializeForLedger(ledger, bob.logger, "bob"); } + const erc20TokenContract = global.tokenContract + ? global.tokenContract + : "0xB97048628DB6B661D4C2aA833e95Dbe1A905B280"; + const { alphaAbsoluteExpiry, betaCltvExpiry, } = defaultHalightHanHerc20Expiries(); - const aliceCreateSwapBody = await makeCreateSwapBody( - alice, - "Alice", - bob, - alphaAbsoluteExpiry, - betaCltvExpiry - ); - const bobCreateSwapBody = await makeCreateSwapBody( - bob, - "Bob", - alice, - alphaAbsoluteExpiry, - betaCltvExpiry - ); + const aliceIdentities = await getIdentities(alice); + const bobIdentities = await getIdentities(bob); + + const hanEthereumEtherHalightLightningBitcoin = { + alice: { + alpha: defaultHanEthereumEtherRequestParams( + alphaAbsoluteExpiry, + aliceIdentities.ethereum + ), + beta: defaultHalightLightningBitcoinRequestParams( + betaCltvExpiry, + aliceIdentities.lightning + ), + role: "Alice" as "Alice" | "Bob", + peer: await makePeer(bob), + }, + bob: { + alpha: defaultHanEthereumEtherRequestParams( + alphaAbsoluteExpiry, + bobIdentities.ethereum + ), + beta: defaultHalightLightningBitcoinRequestParams( + betaCltvExpiry, + bobIdentities.lightning + ), + role: "Bob" as "Alice" | "Bob", + peer: await makePeer(alice), + }, + }; + + const herc20EthereumErc20HalightLightningBitcoin = { + alice: { + alpha: defaultHerc20EthereumErc20RequestParams( + alphaAbsoluteExpiry, + aliceIdentities.ethereum, + erc20TokenContract + ), + beta: defaultHalightLightningBitcoinRequestParams( + betaCltvExpiry, + aliceIdentities.lightning + ), + role: "Alice" as "Alice" | "Bob", + peer: await makePeer(bob), + }, + bob: { + alpha: defaultHerc20EthereumErc20RequestParams( + alphaAbsoluteExpiry, + bobIdentities.ethereum, + erc20TokenContract + ), + beta: defaultHalightLightningBitcoinRequestParams( + betaCltvExpiry, + bobIdentities.lightning + ), + role: "Bob" as "Alice" | "Bob", + peer: await makePeer(alice), + }, + }; + + const halightLightningBitcoinHanEthereumEther = { + alice: { + alpha: defaultHalightLightningBitcoinRequestParams( + betaCltvExpiry, + aliceIdentities.lightning + ), + beta: defaultHanEthereumEtherRequestParams( + alphaAbsoluteExpiry, + aliceIdentities.ethereum + ), + + role: "Alice" as "Alice" | "Bob", + peer: await makePeer(bob), + }, + bob: { + alpha: defaultHalightLightningBitcoinRequestParams( + betaCltvExpiry, + bobIdentities.lightning + ), + beta: defaultHanEthereumEtherRequestParams( + alphaAbsoluteExpiry, + bobIdentities.ethereum + ), + + role: "Bob" as "Alice" | "Bob", + peer: await makePeer(alice), + }, + }; + + const halightLightningBitcoinHerc20EthereumErc20 = { + alice: { + alpha: defaultHalightLightningBitcoinRequestParams( + betaCltvExpiry, + aliceIdentities.lightning + ), + beta: defaultHerc20EthereumErc20RequestParams( + alphaAbsoluteExpiry, + aliceIdentities.ethereum, + erc20TokenContract + ), - return [aliceCreateSwapBody, bobCreateSwapBody]; + role: "Alice" as "Alice" | "Bob", + peer: await makePeer(bob), + }, + bob: { + alpha: defaultHalightLightningBitcoinRequestParams( + betaCltvExpiry, + bobIdentities.lightning + ), + beta: defaultHerc20EthereumErc20RequestParams( + alphaAbsoluteExpiry, + bobIdentities.ethereum, + erc20TokenContract + ), + + role: "Bob" as "Alice" | "Bob", + peer: await makePeer(alice), + }, + }; + + return { + hanEthereumEtherHalightLightningBitcoin, + herc20EthereumErc20HalightLightningBitcoin, + halightLightningBitcoinHanEthereumEther, + halightLightningBitcoinHerc20EthereumErc20, + }; } } -async function makeCreateSwapBody( - self: Actor, - cryptoRole: "Alice" | "Bob", - counterparty: Actor, - alphaAbsoluteExpiry: number, - betaCltvExpiry: number -): Promise { +async function getIdentities( + self: Actor +): Promise<{ ethereum: string; lightning: string }> { + let ethereum = "0x00a329c0648769a73afac7f9381e08fb43dbea72"; + let lightning = + "02ed138aaed50d2d597f6fe8d30759fd3949fe73fdf961322713f1c19e10036a06"; + + try { + ethereum = self.wallets.ethereum.account(); + } catch (e) { + self.logger.warn( + "Ethereum wallet not available, using static value for identity" + ); + } + + try { + lightning = await self.wallets.lightning.inner.getPubkey(); + } catch (e) { + self.logger.warn( + "Lightning wallet not available, using static value for identity" + ); + } + return { - alpha: defaultHanEthereumEtherRequestParams( - alphaAbsoluteExpiry, - self.wallets.ethereum.account() - ), - beta: defaultHalightLightningBitcoinRequestParams( - betaCltvExpiry, - await self.wallets.lightning.inner.getPubkey() - ), - role: cryptoRole, - peer: await makePeer(counterparty), + ethereum, + lightning, }; } @@ -120,100 +259,18 @@ function defaultHalightLightningBitcoinRequestParams( } function defaultHerc20EthereumErc20RequestParams( - absoluteExpiry: number + absoluteExpiry: number, + identity: string, + tokenContractAddress: string ): Herc20EthereumErc20RequestParams { return { amount: "9000000000000000000", - contract_address: "0xB97048628DB6B661D4C2aA833e95Dbe1A905B280", + contract_address: tokenContractAddress, chain_id: 17, - identity: "0x00a329c0648769a73afac7f9381e08fb43dbea72", + identity, absolute_expiry: absoluteExpiry, }; } -export function defaultHanEthereumEtherHalightLightningBitcoin( - lndPubkey: string, - peer: Peer, - role: "Alice" | "Bob", - ethereumIdentity: string -): HanEthereumEtherHalightLightningBitcoinRequestBody { - const { - alphaAbsoluteExpiry, - betaCltvExpiry, - } = defaultHalightHanHerc20Expiries(); - return { - alpha: defaultHanEthereumEtherRequestParams( - alphaAbsoluteExpiry, - ethereumIdentity - ), - beta: defaultHalightLightningBitcoinRequestParams( - betaCltvExpiry, - lndPubkey - ), - role, - peer, - }; -} - -export function defaultHerc20EthereumErc20HalightLightningBitcoin( - lndPubkey: string, - peer: Peer -): Herc20EthereumErc20HalightLightningBitcoinRequestBody { - const { - alphaAbsoluteExpiry, - betaCltvExpiry, - } = defaultHalightHanHerc20Expiries(); - return { - alpha: defaultHerc20EthereumErc20RequestParams(alphaAbsoluteExpiry), - beta: defaultHalightLightningBitcoinRequestParams( - betaCltvExpiry, - lndPubkey - ), - role: "Alice", - peer, - }; -} - -export function defaultHalightLightningBitcoinHanEthereumEther( - lndPubkey: string, - peer: Peer, - ethereumIdentity: string -): HalightLightningBitcoinHanEthereumEtherRequestBody { - const { - alphaCltvExpiry, - betaAbsoluteExpiry, - } = defaultHalightHanHerc20Expiries(); - return { - alpha: defaultHalightLightningBitcoinRequestParams( - alphaCltvExpiry, - lndPubkey - ), - beta: defaultHanEthereumEtherRequestParams( - betaAbsoluteExpiry, - ethereumIdentity - ), - role: "Alice", - peer, - }; -} - -export function defaultHalightLightningBitcoinHerc20EthereumErc20( - lndPubkey: string, - peer: Peer -): HalightLightningBitcoinHerc20EthereumErc20RequestBody { - const { - alphaCltvExpiry, - betaAbsoluteExpiry, - } = defaultHalightHanHerc20Expiries(); - return { - alpha: defaultHalightLightningBitcoinRequestParams( - alphaCltvExpiry, - lndPubkey - ), - beta: defaultHerc20EthereumErc20RequestParams(betaAbsoluteExpiry), - role: "Alice", - peer, - }; -} function defaultHalightHanHerc20Expiries() { const alphaAbsoluteExpiry = Math.round(Date.now() / 1000) + 8; diff --git a/api_tests/tests/ether_halight.ts b/api_tests/tests/ether_halight.ts index 53cf6fa5b7..9243f9d520 100644 --- a/api_tests/tests/ether_halight.ts +++ b/api_tests/tests/ether_halight.ts @@ -10,13 +10,14 @@ import { sleep } from "../src/utils"; it( "han-ethereum-ether-halight-lightning-bitcoin-alice-redeems-bob-redeems", twoActorTest(async ({ alice, bob }) => { - const [aliceBody, bobBody] = await SwapFactory.newSwap(alice, bob); + const bodies = (await SwapFactory.newSwap(alice, bob)) + .hanEthereumEtherHalightLightningBitcoin; // Bob needs to know about the swap first because he is not buffering incoming announcements about swaps he doesn't know about - await bob.createSwap(bobBody); + await bob.createSwap(bodies.bob); await sleep(500); - await alice.createSwap(aliceBody); + await alice.createSwap(bodies.alice); await alice.init(); diff --git a/api_tests/tests/lightning_routes.ts b/api_tests/tests/lightning_routes.ts index 7398154ca9..8fd13934d0 100644 --- a/api_tests/tests/lightning_routes.ts +++ b/api_tests/tests/lightning_routes.ts @@ -1,10 +1,5 @@ -import { oneActorTest } from "../src/actor_test"; -import { - defaultHalightLightningBitcoinHanEthereumEther, - defaultHalightLightningBitcoinHerc20EthereumErc20, - defaultHanEthereumEtherHalightLightningBitcoin, - defaultHerc20EthereumErc20HalightLightningBitcoin, -} from "../src/actors/swap_factory"; +import { twoActorTest } from "../src/actor_test"; +import SwapFactory from "../src/actors/swap_factory"; // ******************************************** // // Lightning routes // @@ -12,60 +7,75 @@ import { describe("Lightning routes tests", () => { it( - "lightning-routes-post-eth-lnbtc-return-201", - oneActorTest(async ({ alice }) => { - const body = defaultHanEthereumEtherHalightLightningBitcoin( - "0346093cc4b9010fa3885df8dfcb6015bc2190bc9f46f5935a48df0417eeb7667e", - { - peer_id: "QmXfGiwNESAFWUvDVJ4NLaKYYVopYdV5HbpDSgz5TSypkb", - }, - "Alice", - "0x00a329c0648769a73afac7f9381e08fb43dbea72" + "create-han-ethereum-ether-halight-lightning-bitcoin-returns-201", + twoActorTest(async ({ alice, bob }) => { + const bodies = (await SwapFactory.newSwap(alice, bob, true)) + .hanEthereumEtherHalightLightningBitcoin; + + const aliceSwapLocation = await alice.cnd.createHanEthereumEtherHalightLightningBitcoin( + bodies.alice ); - const location = await alice.cnd.createHanEthereumEtherHalightLightningBitcoin( - body + const bobSwapLocation = await bob.cnd.createHanEthereumEtherHalightLightningBitcoin( + bodies.bob ); - expect(typeof location).toBe("string"); + + expect(bobSwapLocation).toBeTruthy(); + expect(aliceSwapLocation).toBeTruthy(); }) ); it( - "lightning-routes-post-erc20-lnbtc-return-400", - oneActorTest(async ({ alice }) => { - const promise = alice.cnd.createHerc20EthereumErc20HalightLightningBitcoin( - defaultHerc20EthereumErc20HalightLightningBitcoin("", { - peer_id: "", - }) - ); - await expect(promise).rejects.toThrow("Route not yet supported"); + "create-herc20-ethereum-erc20-halight-lightning-bitcoin-returns-400", + twoActorTest(async ({ alice, bob }) => { + const bodies = (await SwapFactory.newSwap(alice, bob, true)) + .herc20EthereumErc20HalightLightningBitcoin; + await expect( + alice.cnd.createHerc20EthereumErc20HalightLightningBitcoin( + bodies.alice + ) + ).rejects.toThrow("Route not yet supported."); + await expect( + bob.cnd.createHerc20EthereumErc20HalightLightningBitcoin( + bodies.bob + ) + ).rejects.toThrow("Route not yet supported."); }) ); it( - "lightning-routes-post-lnbtc-eth-return-400", - oneActorTest(async ({ alice }) => { - const promise = alice.cnd.createHalightLightningBitcoinHanEthereumEther( - defaultHalightLightningBitcoinHanEthereumEther( - "", - { - peer_id: "", - }, - "0x00a329c0648769a73afac7f9381e08fb43dbea72" + "create-halight-lightning-bitcoin-han-ethereum-ether-returns-400", + twoActorTest(async ({ alice, bob }) => { + const bodies = (await SwapFactory.newSwap(alice, bob, true)) + .halightLightningBitcoinHanEthereumEther; + await expect( + alice.cnd.createHalightLightningBitcoinHanEthereumEther( + bodies.alice ) - ); - await expect(promise).rejects.toThrow("Route not yet supported"); + ).rejects.toThrow("Route not yet supported."); + await expect( + bob.cnd.createHalightLightningBitcoinHanEthereumEther( + bodies.bob + ) + ).rejects.toThrow("Route not yet supported."); }) ); it( - "lightning-routes-post-lnbtc-erc20-return-400", - oneActorTest(async ({ alice }) => { - const promise = alice.cnd.createHalightLightningBitcoinHerc20EthereumErc20( - defaultHalightLightningBitcoinHerc20EthereumErc20("", { - peer_id: "", - }) - ); - await expect(promise).rejects.toThrow("Route not yet supported"); + "create-halight-lightning-bitcoin-herc20-ethereum-erc20-returns-400", + twoActorTest(async ({ alice, bob }) => { + const bodies = (await SwapFactory.newSwap(alice, bob, true)) + .halightLightningBitcoinHerc20EthereumErc20; + + await expect( + alice.cnd.createHalightLightningBitcoinHerc20EthereumErc20( + bodies.alice + ) + ).rejects.toThrow("Route not yet supported."); + await expect( + bob.cnd.createHalightLightningBitcoinHerc20EthereumErc20( + bodies.bob + ) + ).rejects.toThrow("Route not yet supported."); }) ); }); From 624f26709875289ee1a0a1f95263d346ec03574a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 12 Apr 2020 14:12:33 +0000 Subject: [PATCH 79/88] Bump thiserror from 1.0.14 to 1.0.15 Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.14 to 1.0.15. - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.14...1.0.15) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f20ea0a2d..c60d327e17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3318,18 +3318,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0570dc61221295909abdb95c739f2e74325e14293b2026b0a7e195091ec54ae" +checksum = "54b3d3d2ff68104100ab257bb6bb0cb26c901abe4bd4ba15961f3bf867924012" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "227362df41d566be41a28f64401e07a043157c21c14b9785a0d8e256f940a8fd" +checksum = "ca972988113b7715266f91250ddb98070d033c62a011fa0fcc57434a649310dd" dependencies = [ "proc-macro2 1.0.10", "quote 1.0.3", From 872b1f15e2ebb6bac7ff393522c0bb9f56e7dff2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 12 Apr 2020 14:13:03 +0000 Subject: [PATCH 80/88] Bump derivative from 2.1.0 to 2.1.1 Bumps [derivative](https://github.com/mcarton/rust-derivative) from 2.1.0 to 2.1.1. - [Release notes](https://github.com/mcarton/rust-derivative/releases) - [Changelog](https://github.com/mcarton/rust-derivative/blob/master/CHANGELOG.md) - [Commits](https://github.com/mcarton/rust-derivative/commits) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f20ea0a2d..14db8e7653 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -485,7 +485,7 @@ dependencies = [ "blockchain_contracts", "chrono", "config", - "derivative 2.1.0", + "derivative 2.1.1", "diesel", "diesel_migrations", "digest 0.1.0", @@ -712,9 +712,9 @@ dependencies = [ [[package]] name = "derivative" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1eae4d76b7cefedd1b4f8cc24378b2fbd1ac1b66e3bbebe8e2192d3be81cb355" +checksum = "cb582b60359da160a9477ee80f15c8d784c477e69c217ef2cdd4169c24ea380f" dependencies = [ "proc-macro2 1.0.10", "quote 1.0.3", @@ -1598,7 +1598,7 @@ name = "libp2p-comit" version = "0.1.0" dependencies = [ "bytes", - "derivative 2.1.0", + "derivative 2.1.1", "futures", "futures_codec 0.4.0", "libp2p", From 2534e3c303ee11f669466c2219fbe6fc92d1bcc9 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 12 Apr 2020 14:13:26 +0000 Subject: [PATCH 81/88] Bump libp2p from 0.17.0 to 0.18.0 Bumps [libp2p](https://github.com/libp2p/rust-libp2p) from 0.17.0 to 0.18.0. - [Release notes](https://github.com/libp2p/rust-libp2p/releases) - [Changelog](https://github.com/libp2p/rust-libp2p/blob/master/CHANGELOG.md) - [Commits](https://github.com/libp2p/rust-libp2p/compare/v0.17.0...v0.18.0) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 40 ++++++++++++++++++++-------------------- cnd/Cargo.toml | 2 +- libp2p-comit/Cargo.toml | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f20ea0a2d..e52393f4dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1569,9 +1569,9 @@ checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018" [[package]] name = "libp2p" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a261244b8d7ff58f5d62ffa33589eb1ba7733a1dfee0902ad9fdfe62ada7009" +checksum = "aa5aedb713f76577818529be8283e35ec5e8b3ecdccfe0231ba4d860687438ab" dependencies = [ "bytes", "futures", @@ -1612,9 +1612,9 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.17.1" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfe1412f2afe1366a2661abd211bb1a27ee6a664d799071282f4fba997c6858" +checksum = "a1d2c17158c4dca984a77a5927aac6f0862d7f50c013470a415f93be498b5739" dependencies = [ "asn1_der", "bs58", @@ -1646,9 +1646,9 @@ dependencies = [ [[package]] name = "libp2p-core-derive" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0eeb25d5f152a826eac57c7d1cc3de10d72dc4051e90fe4c0cd139f07a069a3" +checksum = "329127858e4728db5ab60c33d5ae352a999325fdf190ed022ec7d3a4685ae2e6" dependencies = [ "quote 1.0.3", "syn 1.0.17", @@ -1656,9 +1656,9 @@ dependencies = [ [[package]] name = "libp2p-dns" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "647178f8683bf868f7f14d5e5718dbdc2445b9f6b24ce99da96cecd7c5d2d1a6" +checksum = "c0d0993481203d68e5ce2f787d033fb0cac6b850659ed6c784612db678977c71" dependencies = [ "futures", "libp2p-core", @@ -1667,9 +1667,9 @@ dependencies = [ [[package]] name = "libp2p-mdns" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b752276b3bea2fca1c291f43cefc8082d8a639bb8f9052cf5adc6accfcd7b44e" +checksum = "41e908d2aaf8ff0ec6ad1f02fe1844fd777fb0b03a68a226423630750ab99471" dependencies = [ "async-std", "data-encoding", @@ -1689,9 +1689,9 @@ dependencies = [ [[package]] name = "libp2p-mplex" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f317db8c062beecde87a8765ca03784e6f1a55daa5b9868bf60ebf9b9a2b92f" +checksum = "0832882b06619b2e81d74e71447753ea3c068164a0bca67847d272e856a04a02" dependencies = [ "bytes", "fnv", @@ -1705,9 +1705,9 @@ dependencies = [ [[package]] name = "libp2p-secio" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74130fa95effb780850ec790b7af777b893108d9b5983ab994b61d93d2eb0336" +checksum = "a7a0509a7e47245259954fef58b85b81bf4d29ae33a4365e38d718a866698774" dependencies = [ "aes-ctr", "ctr", @@ -1735,9 +1735,9 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4ec53df8978a5d6d9dac243fb1e3adf004f8b8d28f72e6f2160df34d5f39564" +checksum = "622605817885e67b5572189c2507e514b786beb69ed85a120dbb245a7f15383d" dependencies = [ "futures", "libp2p-core", @@ -1750,9 +1750,9 @@ dependencies = [ [[package]] name = "libp2p-tcp" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25c9d9c5448c189bba7ecdd1ca23800516281476e82810eff711ef04abaf9eb" +checksum = "b37ea44823d3ed223e4605da94b50177bc520f05ae2452286700549a32d81669" dependencies = [ "async-std", "futures", @@ -1765,9 +1765,9 @@ dependencies = [ [[package]] name = "libp2p-yamux" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee12c49426527908f81ffb6551b95f57149a8ea64f386bb7da3b123cdb9c01ba" +checksum = "02f91aea50f6571e0bc6c058dc0e9b270afd41ec28dd94e9e4bf607e78b9ab87" dependencies = [ "futures", "libp2p-core", diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index 95c92ba235..b7b8060e3c 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -31,7 +31,7 @@ http-api-problem = { version = "0.15", features = ["with_warp"] } impl-template = "1.0.0-alpha" lazy_static = "1" levenshtein = "1" -libp2p = { version = "0.17", default-features = false, features = ["tcp", "secio", "yamux", "mplex", "mdns", "dns"] } +libp2p = { version = "0.18", default-features = false, features = ["tcp", "secio", "yamux", "mplex", "mdns", "dns"] } libp2p-comit = { path = "../libp2p-comit" } libsqlite3-sys = { version = ">=0.8.0, <0.13.0", features = ["bundled"] } log = { version = "0.4", features = ["serde"] } diff --git a/libp2p-comit/Cargo.toml b/libp2p-comit/Cargo.toml index 23ca8e891a..6bc01efa6f 100644 --- a/libp2p-comit/Cargo.toml +++ b/libp2p-comit/Cargo.toml @@ -10,7 +10,7 @@ bytes = "0.5" derivative = "2" futures = { version = "0.3", default-features = false } futures_codec = "0.4" -libp2p = { version = "0.17", default-features = false } +libp2p = { version = "0.18", default-features = false } serde = { version = "1", features = ["derive"] } serde_json = "1.0" strum_macros = "0.18" From 1f1754ffaa13573246d5960652c9db7d8dab32d3 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 12 Apr 2020 14:13:51 +0000 Subject: [PATCH 82/88] Bump tokio from 0.2.16 to 0.2.17 Bumps [tokio](https://github.com/tokio-rs/tokio) from 0.2.16 to 0.2.17. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-0.2.16...tokio-0.2.17) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f20ea0a2d..db6170df1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3367,9 +3367,9 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee5a0dd887e37d37390c13ff8ac830f992307fe30a1fff0ab8427af67211ba28" +checksum = "39fb9142eb6e9cc37f4f29144e62618440b149a138eee01a7bbe9b9226aaf17c" dependencies = [ "bytes", "fnv", From e3570a299ed25535c4aa8b8493b0b6c88529a6d4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2020 14:13:12 +0000 Subject: [PATCH 83/88] Bump tokio from 0.2.17 to 0.2.18 Bumps [tokio](https://github.com/tokio-rs/tokio) from 0.2.17 to 0.2.18. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-0.2.17...tokio-0.2.18) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e8c396ec78..8ee26afce8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3367,9 +3367,9 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39fb9142eb6e9cc37f4f29144e62618440b149a138eee01a7bbe9b9226aaf17c" +checksum = "34ef16d072d2b6dc8b4a56c70f5c5ced1a37752116f8e7c1e80c659aa7cb6713" dependencies = [ "bytes", "fnv", From 1ffb3262aa245d5c3d3e703db2f8f58acffbbcd9 Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Wed, 8 Apr 2020 19:43:31 +1000 Subject: [PATCH 84/88] run e2e test job for mac-os as well --- .github/workflows/ci.yml | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 650fe5be2c..e2e9711b34 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,11 +39,6 @@ jobs: strategy: matrix: os: [macos-latest, ubuntu-latest] - include: - - os: ubuntu-latest - binary-suffix: "" - - os: macos-latest - binary-suffix: "" runs-on: ${{ matrix.os }} steps: - name: Checkout sources @@ -79,25 +74,26 @@ jobs: if: matrix.os != 'macos-latest' run: make test - - name: Upload cnd ${{ matrix.os }} binary - if: matrix.os == 'ubuntu-latest' + - name: Upload cnd-${{ matrix.os }} archive that contains the cnd binary uses: actions/upload-artifact@v1 with: - name: cnd + name: cnd-${{ matrix.os }} path: target/debug/cnd - e2e_test: - runs-on: ubuntu-latest + strategy: + matrix: + os: [macos-latest, ubuntu-latest] + runs-on: ${{ matrix.os }} needs: build steps: - name: Checkout sources uses: actions/checkout@v1 - - name: Download cnd binary + - name: Download cnd-${{ matrix.os }} archive and extract cnd binary uses: actions/download-artifact@v1 with: - name: cnd + name: cnd-${{ matrix.os }} path: target/debug/ - name: Fix missing executable permission From 2b2c6e4c908596bd22e9e1a9456626d07dfbf03c Mon Sep 17 00:00:00 2001 From: Philipp Hoenisch Date: Tue, 14 Apr 2020 16:09:18 +1000 Subject: [PATCH 85/88] Deserialization for networks main/test/regtest as retrieved by bitcoind --- cnd/src/btsieve/bitcoin/bitcoind_connector.rs | 59 ++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/cnd/src/btsieve/bitcoin/bitcoind_connector.rs b/cnd/src/btsieve/bitcoin/bitcoind_connector.rs index 517ce122dc..18c9f481b0 100644 --- a/cnd/src/btsieve/bitcoin/bitcoind_connector.rs +++ b/cnd/src/btsieve/bitcoin/bitcoind_connector.rs @@ -5,11 +5,12 @@ use crate::{ use async_trait::async_trait; use bitcoin::{BlockHash, Network}; use reqwest::{Client, Url}; -use serde::Deserialize; +use serde::{de, export::fmt, Deserialize, Deserializer}; #[derive(Copy, Clone, Debug, Deserialize)] pub struct ChainInfo { bestblockhash: BlockHash, + #[serde(deserialize_with = "deserialize_bitcoind_values")] pub chain: Network, } @@ -96,6 +97,35 @@ impl FetchNetworkId for BitcoindConnector { } } +pub fn deserialize_bitcoind_values<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + struct Visitor; + + impl<'de> de::Visitor<'de> for Visitor { + type Value = bitcoin::Network; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("a bitcoin network") + } + + fn visit_str(self, v: &str) -> Result + where + E: de::Error, + { + match v { + "main" => Ok(bitcoin::Network::Bitcoin), + "test" => Ok(bitcoin::Network::Testnet), + "regtest" => Ok(bitcoin::Network::Regtest), + unknown => Err(E::custom(format!("unknown bitcoin network {}", unknown))), + } + } + } + + deserializer.deserialize_str(Visitor) +} + #[cfg(test)] mod tests { @@ -155,4 +185,31 @@ mod tests { assert_eq!(raw_block_by_hash_url, Url::parse("http://localhost:8080/rest/block/2a593b84b1943521be01f97a59fc7feba30e7e8527fb2ba20b0158ca09016d02.hex").unwrap()); } } + + #[test] + fn test_custom_serde_deserializer() { + let chain_info = r#"{ + "chain": "test", + "bestblockhash": "00000000000000c473d592c8637824b8362d522af18bfb1d0e92107b96ecdc5c" + } + "#; + let info = serde_json::from_str::(chain_info).unwrap(); + assert_eq!(info.chain, Network::Testnet); + + let chain_info = r#"{ + "chain": "main", + "bestblockhash": "00000000000000c473d592c8637824b8362d522af18bfb1d0e92107b96ecdc5c" + } + "#; + let info = serde_json::from_str::(chain_info).unwrap(); + assert_eq!(info.chain, Network::Bitcoin); + + let chain_info = r#"{ + "chain": "regtest", + "bestblockhash": "00000000000000c473d592c8637824b8362d522af18bfb1d0e92107b96ecdc5c" + } + "#; + let info = serde_json::from_str::(chain_info).unwrap(); + assert_eq!(info.chain, Network::Regtest); + } } From 30fc86292aaa3988aa8ac0cc5f585ae9a49adb7e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 14 Apr 2020 15:34:47 +0000 Subject: [PATCH 86/88] Bump log4js from 6.1.2 to 6.2.0 in /api_tests Bumps [log4js](https://github.com/log4js-node/log4js-node) from 6.1.2 to 6.2.0. - [Release notes](https://github.com/log4js-node/log4js-node/releases) - [Changelog](https://github.com/log4js-node/log4js-node/blob/master/CHANGELOG.md) - [Commits](https://github.com/log4js-node/log4js-node/compare/v6.1.2...v6.2.0) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index e7b3d42255..6dff39812c 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -55,7 +55,7 @@ "jasmine": "^3.5.0", "jest": "^25.3.0", "js-sha256": "^0.9.0", - "log4js": "^6.1.2", + "log4js": "^6.2.0", "p-timeout": "^3.2.0", "prettier": "^2.0.4", "process-exists": "^4.0.0", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 21cfc6f648..8f098f91ca 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -3879,10 +3879,10 @@ lodash@^4.0.0, lodash@^4.17.13, lodash@^4.17.15: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== -log4js@*, log4js@^6.1.2: - version "6.1.2" - resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.1.2.tgz#04688e1f4b8080c127b7dccb0db1c759cbb25dc4" - integrity sha512-knS4Y30pC1e0n7rfx3VxcLOdBCsEo0o6/C7PVTGxdVK+5b1TYOSGQPn9FDcrhkoQBV29qwmA2mtkznPAQKnxQg== +log4js@*, log4js@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.2.0.tgz#e7514cd139c09b7b81a98b71c1b1eebc8a96c1ad" + integrity sha512-4x14gHnFaWgkKEygGtIBAvAaHuJX1z86bLx4SQ76jdgQmYxaW3SF6EFoEn9nRG6fW7TuKvyERItG6vxgNOCeTA== dependencies: date-format "^3.0.0" debug "^4.1.1" From ecfced8e04acde633d84461f04543f3632e0079f Mon Sep 17 00:00:00 2001 From: Philipp Hoenisch Date: Wed, 15 Apr 2020 09:13:26 +1000 Subject: [PATCH 87/88] Add missing changelog --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d1674399a..6952c16f50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## Changed +### Fixed + +- Deserialization problem of bitcoind's response: Bitcoind returns as chain/network either `main`,`test` or `regtest`. This fix was manually tested against bitcoind (0.17, 0.18 and 0.19). + +### Changed - Ensure that lnd parameters are defaulted if not present. From c6530770c14de8f6fb91c031a90000042bf55500 Mon Sep 17 00:00:00 2001 From: GitHub actions Date: Tue, 14 Apr 2020 23:58:17 +0000 Subject: [PATCH 88/88] Prepare release 0.7.3 --- CHANGELOG.md | 10 +++++++--- Cargo.lock | 2 +- cnd/Cargo.toml | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6952c16f50..d7c60e5998 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,13 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.7.3] - 2020-04-14 + ### Fixed -- Deserialization problem of bitcoind's response: Bitcoind returns as chain/network either `main`,`test` or `regtest`. This fix was manually tested against bitcoind (0.17, 0.18 and 0.19). +- Deserialization problem of bitcoind's response: Bitcoind returns as chain/network either `main`,`test` or `regtest`. This fix was manually tested against bitcoind (0.17, 0.18 and 0.19). ### Changed -- Ensure that lnd parameters are defaulted if not present. +- Ensure that lnd parameters are defaulted if not present. ## [0.7.2] - 2020-03-26 @@ -119,7 +121,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Move config files to standard location based on platform (OSX, Windows, Linux). - Align implementation with RFC-002 to use the decision header instead of status codes. -[Unreleased]: https://github.com/comit-network/comit-rs/compare/0.7.2...HEAD +[Unreleased]: https://github.com/comit-network/comit-rs/compare/0.7.3...HEAD + +[0.7.3]: https://github.com/comit-network/comit-rs/compare/0.7.2...0.7.3 [0.7.2]: https://github.com/comit-network/comit-rs/compare/0.7.1...0.7.2 diff --git a/Cargo.lock b/Cargo.lock index 8ee26afce8..df2c4ec0e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -473,7 +473,7 @@ dependencies = [ [[package]] name = "cnd" -version = "0.7.2" +version = "0.7.3" dependencies = [ "ambassador", "anyhow", diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index b7b8060e3c..1f238ffb2a 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -1,7 +1,7 @@ [package] authors = ["CoBloX developers "] name = "cnd" -version = "0.7.2" +version = "0.7.3" edition = "2018" description = "Reference implementation of a COMIT network daemon."