diff --git a/.github/actions/run-e2e-test/action.yml b/.github/actions/run-e2e-test/action.yml index f066979c56..ff15febb55 100644 --- a/.github/actions/run-e2e-test/action.yml +++ b/.github/actions/run-e2e-test/action.yml @@ -30,6 +30,18 @@ inputs: description: 'Whether to deploy the adder sample contract to the node.' required: false default: 'false' + image-path: + description: 'Custom path to docker image for aleph-node' + required: false + default: aleph-test-docker + node-image: + description: 'Custom name of aleph-node image' + required: false + default: aleph-node:latest + compose-file: + description: 'Custom docker-compose configuration' + required: false + default: '' runs: using: 'composite' @@ -38,7 +50,7 @@ runs: - name: Download artifact with docker image uses: actions/download-artifact@v2 with: - name: aleph-test-docker + name: ${{ inputs.image-path }} - name: Load node docker image shell: bash @@ -46,7 +58,7 @@ runs: - name: Run consensus party shell: bash - run: ./.github/scripts/run_consensus.sh -m ${{ inputs.min-validator-count }} -n ${{ inputs.node-count }} + run: NODE_IMAGE=${{ inputs.node-image }} DOCKER_COMPOSE=${{ inputs.compose-file }} ./.github/scripts/run_consensus.sh -m ${{ inputs.min-validator-count }} -n ${{ inputs.node-count }} - name: Sleep shell: bash diff --git a/.github/scripts/run_consensus.sh b/.github/scripts/run_consensus.sh index ca40484618..f5f82cbbfc 100755 --- a/.github/scripts/run_consensus.sh +++ b/.github/scripts/run_consensus.sh @@ -8,11 +8,12 @@ NODE_COUNT=5 MIN_VALIDATOR_COUNT=4 DOCKER_COMPOSE=${DOCKER_COMPOSE:-"docker/docker-compose.yml"} OVERRIDE_DOCKER_COMPOSE=${OVERRIDE_DOCKER_COMPOSE:-""} +NODE_IMAGE=${NODE_IMAGE:-aleph-node:latest} # default minimum validator count MIN_VALIDATOR_COUNT=4 -export NODE_IMAGE=aleph-node:latest +export NODE_IMAGE mkdir -p docker/data/ diff --git a/.github/scripts/run_e2e_test.sh b/.github/scripts/run_e2e_test.sh index 47dcdfa0d3..1e23eb5c76 100755 --- a/.github/scripts/run_e2e_test.sh +++ b/.github/scripts/run_e2e_test.sh @@ -116,6 +116,10 @@ if [[ -n "${ADDER:-}" ]]; then ARGS+=(-e "ADDER_METADATA=/contracts/adder/target/ink/metadata.json") fi +if [[ -n "${OUT_LATENCY:-}" ]]; then + ARGS+=(-e OUT_LATENCY) +fi + docker run -v "$(pwd)/contracts:/contracts" -v "$(pwd)/docker/data:/data" "${ARGS[@]}" aleph-e2e-client:latest exit $? diff --git a/.github/workflows/build-and-push-cliain.yaml b/.github/workflows/build-and-push-cliain.yaml index 32a2f983eb..ad77ef3cf5 100644 --- a/.github/workflows/build-and-push-cliain.yaml +++ b/.github/workflows/build-and-push-cliain.yaml @@ -21,6 +21,7 @@ jobs: uses: arduino/setup-protoc@v1 with: version: '3.6.1' + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Cargo | Build release binary run: | @@ -29,18 +30,18 @@ jobs: - name: GIT | Get branch name and commit SHA id: get_branch uses: ./.github/actions/get-branch - + - name: Login to ECR uses: docker/login-action@v1 with: registry: public.ecr.aws username: ${{ secrets.AWS_MAINNET_ACCESS_KEY_ID }} password: ${{ secrets.AWS_MAINNET_SECRET_ACCESS_KEY }} - + - name: Set up Docker Buildx id: buildx uses: docker/setup-buildx-action@master - + - name: Build and push latest docker image id: build-image env: diff --git a/.github/workflows/build-node-and-runtime.yml b/.github/workflows/build-node-and-runtime.yml index 4c9d4597b1..32415adf90 100644 --- a/.github/workflows/build-node-and-runtime.yml +++ b/.github/workflows/build-node-and-runtime.yml @@ -37,6 +37,7 @@ jobs: uses: arduino/setup-protoc@v1 with: version: '3.6.1' + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Install WASM target run: rustup target add wasm32-unknown-unknown diff --git a/.github/workflows/build-send-postsync-hook-runtime-image.yml b/.github/workflows/build-send-postsync-hook-runtime-image.yml index e66e0093cf..64485810a4 100644 --- a/.github/workflows/build-send-postsync-hook-runtime-image.yml +++ b/.github/workflows/build-send-postsync-hook-runtime-image.yml @@ -36,7 +36,8 @@ jobs: - name: Install Protoc uses: arduino/setup-protoc@v1 with: - version: '3.6.1' + version: '3.6.1' + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Build binary run: | @@ -76,7 +77,7 @@ jobs: docker tag ${{ env.ECR_PUSH_IMAGE }} ${{ env.ECR_LATEST }} docker push ${{ env.ECR_LATEST }} - + - name: GIT | Checkout aleph-apps repo uses: actions/checkout@master with: @@ -89,8 +90,8 @@ jobs: with: kustomize-version: "3.8.6" - - name: Update postsync hook docker image - env: + - name: Update postsync hook docker image + env: RELEASE_IMAGE: public.ecr.aws/p6e8q1z1/runtime-update-hook:${{ steps.vars.outputs.sha_short }} REGIONS_AWS: 'eu-central-1' run: | diff --git a/.github/workflows/check-excluded-packages.yml b/.github/workflows/check-excluded-packages.yml index 202fb804be..9eeb954a4e 100644 --- a/.github/workflows/check-excluded-packages.yml +++ b/.github/workflows/check-excluded-packages.yml @@ -31,6 +31,7 @@ jobs: uses: arduino/setup-protoc@v1 with: version: '3.6.1' + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Read excluded packages from Cargo.toml id: read_excluded diff --git a/.github/workflows/e2e-tests-main-devnet.yml b/.github/workflows/e2e-tests-main-devnet.yml index 839b64b956..70bb8fc8d9 100644 --- a/.github/workflows/e2e-tests-main-devnet.yml +++ b/.github/workflows/e2e-tests-main-devnet.yml @@ -68,7 +68,8 @@ jobs: - name: Install Protoc uses: arduino/setup-protoc@v1 with: - version: '3.6.1' + version: '3.6.1' + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Restore cache uses: ./.github/actions/restore-cache @@ -115,7 +116,8 @@ jobs: - name: Install Protoc uses: arduino/setup-protoc@v1 with: - version: '3.6.1' + version: '3.6.1' + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Install WASM target run: rustup target add wasm32-unknown-unknown @@ -153,7 +155,8 @@ jobs: - name: Install Protoc uses: arduino/setup-protoc@v1 with: - version: '3.6.1' + version: '3.6.1' + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Restore cache uses: ./.github/actions/restore-cache @@ -839,7 +842,8 @@ jobs: - name: Install Protoc uses: arduino/setup-protoc@v1 with: - version: '3.6.1' + version: '3.6.1' + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Install WASM target run: rustup target add wasm32-unknown-unknown diff --git a/.github/workflows/nightly-pipeline.yaml b/.github/workflows/nightly-pipeline.yaml index fe47743973..a426f97ffc 100644 --- a/.github/workflows/nightly-pipeline.yaml +++ b/.github/workflows/nightly-pipeline.yaml @@ -43,6 +43,37 @@ jobs: if-no-files-found: error retention-days: 7 + build-synthetic-network-docker: + needs: [build-test-docker] + name: Build docker image with the test node artifact and support for synthetic-network + runs-on: ubuntu-20.04 + steps: + - name: Checkout source code + uses: actions/checkout@v2 + + - name: Download artifact with docker image for aleph-node + uses: actions/download-artifact@v2 + with: + name: aleph-test-docker + + - name: Load node docker image + shell: bash + run: docker load -i aleph-node.tar + + - name: Build test docker image + id: build-image + run: | + scripts/synthetic-network/build_synthetic-network.sh + docker save -o aleph-node.tar aleph-node:syntheticnet + + - name: Upload test docker image + uses: actions/upload-artifact@v2 + with: + name: aleph-test-synthetic-docker + path: aleph-node.tar + if-no-files-found: error + retention-days: 7 + check-determinism: needs: [build-new-node] name: Verify runtime build determinism @@ -59,7 +90,8 @@ jobs: - name: Install Protoc uses: arduino/setup-protoc@v1 with: - version: '3.6.1' + version: '3.6.1' + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Install WASM target run: rustup target add wasm32-unknown-unknown @@ -96,7 +128,8 @@ jobs: - name: Install Protoc uses: arduino/setup-protoc@v1 with: - version: '3.6.1' + version: '3.6.1' + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Restore cache uses: ./.github/actions/restore-cache @@ -140,9 +173,45 @@ jobs: randomized: true timeout-minutes: 60 + run-e2e-high-out-latency: + needs: [build-synthetic-network-docker, build-test-client] + name: Run high out-latency test + runs-on: ubuntu-20.04 + steps: + - name: Checkout source code + uses: actions/checkout@v2 + + - name: Run e2e test + uses: ./.github/actions/run-e2e-test + with: + test-case: high_out_latency_for_all + image-path: aleph-test-synthetic-docker + node-image: aleph-node:syntheticnet + compose-file: docker/docker-compose.synthetic-network.yml + timeout-minutes: 30 + + run-e2e-no-quorum-without-high-out-latency: + needs: [build-synthetic-network-docker, build-test-client] + name: Run high out-latency for every quorum + runs-on: ubuntu-20.04 + steps: + - name: Checkout source code + uses: actions/checkout@v2 + + - name: Run e2e test + uses: ./.github/actions/run-e2e-test + with: + test-case: high_out_latency_for_each_quorum + image-path: aleph-test-synthetic-docker + node-image: aleph-node:syntheticnet + compose-file: docker/docker-compose.synthetic-network.yml + timeout-minutes: 15 + check-e2e-test-suite-completion: needs: [ run-e2e-authorities-are-staking, + run-e2e-high-out-latency, + run-e2e-no-quorum-without-high-out-latency, ] name: Check e2e test suite completion runs-on: ubuntu-20.04 diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 7e3431687a..fa644dc1f2 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -30,7 +30,8 @@ jobs: - name: Install Protoc uses: arduino/setup-protoc@v1 with: - version: '3.6.1' + version: '3.6.1' + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Install clippy and fmt run: rustup component add clippy rustfmt diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..2a602c4b2c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "scripts/synthetic-network/vendor/synthetic-network"] + path = scripts/synthetic-network/vendor/synthetic-network + url = https://github.com/daily-co/synthetic-network.git diff --git a/Cargo.toml b/Cargo.toml index 822e5fe487..d772088611 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,8 @@ exclude = [ "fork-off", "benches/payout-stakers", "bin/cliain", - "contracts/adder" + "contracts/adder", + "scripts/synthetic-network/synthetic-link", ] [profile.release] diff --git a/e2e-tests/Cargo.lock b/e2e-tests/Cargo.lock index 24029e5fcb..faad2015b8 100644 --- a/e2e-tests/Cargo.lock +++ b/e2e-tests/Cargo.lock @@ -54,8 +54,8 @@ dependencies = [ "aleph_client", "anyhow", "assert2", - "clap", - "env_logger", + "clap 3.2.23", + "env_logger 0.8.4", "frame-support", "frame-system", "futures", @@ -73,6 +73,7 @@ dependencies = [ "serde_json", "sp-core 6.0.0", "sp-runtime 6.0.0", + "synthetic-link", "tokio", ] @@ -207,7 +208,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -412,8 +413,8 @@ checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" dependencies = [ "atty", "bitflags", - "clap_derive", - "clap_lex", + "clap_derive 3.2.18", + "clap_lex 0.2.4", "indexmap", "once_cell", "strsim", @@ -421,6 +422,21 @@ dependencies = [ "textwrap", ] +[[package]] +name = "clap" +version = "4.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d63b9e9c07271b9957ad22c173bae2a4d9a81127680962039296abcd2f8251d" +dependencies = [ + "bitflags", + "clap_derive 4.0.21", + "clap_lex 0.3.0", + "is-terminal", + "once_cell", + "strsim", + "termcolor", +] + [[package]] name = "clap_derive" version = "3.2.18" @@ -434,6 +450,19 @@ dependencies = [ "syn", ] +[[package]] +name = "clap_derive" +version = "4.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "clap_lex" version = "0.2.4" @@ -443,6 +472,15 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "clap_lex" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -862,6 +900,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "encoding_rs" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +dependencies = [ + "cfg-if", +] + [[package]] name = "env_logger" version = "0.8.4" @@ -875,12 +922,46 @@ dependencies = [ "termcolor", ] +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + [[package]] name = "environmental" version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48c92028aaa870e83d51c64e5d4e0b6981b360c522198c23959f219a4e1b15b" +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "escape8259" version = "0.5.2" @@ -939,6 +1020,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.1.0" @@ -1333,6 +1429,15 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "hex" version = "0.4.3" @@ -1450,6 +1555,19 @@ dependencies = [ "webpki-roots", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "iana-time-zone" version = "0.1.53" @@ -1654,6 +1772,34 @@ dependencies = [ "num-traits", ] +[[package]] +name = "io-lifetimes" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" +dependencies = [ + "libc", + "windows-sys 0.42.0", +] + +[[package]] +name = "ipnet" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e" + +[[package]] +name = "is-terminal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330" +dependencies = [ + "hermit-abi 0.2.6", + "io-lifetimes", + "rustix", + "windows-sys 0.42.0", +] + [[package]] name = "itertools" version = "0.10.5" @@ -1879,6 +2025,12 @@ dependencies = [ "statrs", ] +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + [[package]] name = "lock_api" version = "0.4.9" @@ -1978,6 +2130,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -2034,6 +2192,24 @@ dependencies = [ "syn", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "nohash-hasher" version = "0.2.0" @@ -2131,7 +2307,7 @@ version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", ] @@ -2162,12 +2338,51 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "openssl" +version = "0.10.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29d971fd5722fec23977260f6e81aa67d2f22cadbdc2aa049f1022d9a3be1566" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-sys" +version = "0.9.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5454462c0eced1e97f2ec09036abc8da362e66802f66fd20f86854d9d8cbcbc4" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "os_str_bytes" version = "6.4.1" @@ -2468,6 +2683,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2736,6 +2957,52 @@ version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "reqwest" +version = "0.11.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + [[package]] name = "rfc6979" version = "0.1.0" @@ -2795,6 +3062,20 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.36.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.42.0", +] + [[package]] name = "rustls" version = "0.20.7" @@ -3059,6 +3340,29 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_repr" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a5ec9fa74a20ebbe5d9ac23dac1fc96ba0ecfe9f50f2843b52e537b10fbcb4e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "sha-1" version = "0.9.8" @@ -4171,12 +4475,41 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "synthetic-link" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap 4.0.29", + "env_logger 0.10.0", + "log", + "reqwest", + "serde", + "serde_json", + "serde_repr", + "tokio", +] + [[package]] name = "tap" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + [[package]] name = "termcolor" version = "1.1.3" @@ -4257,9 +4590,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.22.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" +checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" dependencies = [ "autocfg", "bytes", @@ -4272,7 +4605,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "winapi", + "windows-sys 0.42.0", ] [[package]] @@ -4286,6 +4619,16 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.23.4" @@ -4524,6 +4867,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" @@ -4583,6 +4932,18 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.83" @@ -4805,6 +5166,15 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + [[package]] name = "wyz" version = "0.5.1" diff --git a/e2e-tests/Cargo.toml b/e2e-tests/Cargo.toml index 0cb8cb0be4..edc7a56303 100644 --- a/e2e-tests/Cargo.toml +++ b/e2e-tests/Cargo.toml @@ -30,6 +30,7 @@ pallet-balances = { git = "https://github.com/Cardinal-Cryptography/substrate.gi aleph_client = { path = "../aleph-client" } primitives = { path = "../primitives", features = ["short_session"], default-features = false } pallet-elections = { path = "../pallets/elections" } +synthetic-link = { path = "../scripts/synthetic-network/synthetic-link" } [features] default = ["std"] diff --git a/e2e-tests/src/config.rs b/e2e-tests/src/config.rs index d2a53c2c00..10d781bd4f 100644 --- a/e2e-tests/src/config.rs +++ b/e2e-tests/src/config.rs @@ -27,6 +27,10 @@ static GLOBAL_CONFIG: Lazy = Lazy::new(|| { upgrade_finalization_wait_sessions: get_env("UPGRADE_FINALIZATION_WAIT_SESSIONS"), adder: get_env("ADDER"), adder_metadata: get_env("ADDER_METADATA"), + out_latency: get_env("OUT_LATENCY"), + synthetic_network_urls: env::var("SYNTHETIC_URLS") + .ok() + .map(|s| s.split(',').map(|s| s.to_string()).collect()), }, } }); @@ -34,7 +38,7 @@ static GLOBAL_CONFIG: Lazy = Lazy::new(|| { fn get_env(name: &str) -> Option where T: FromStr, - ::Err: std::fmt::Debug, + T::Err: std::fmt::Debug, { env::var(name).ok().map(|v| { v.parse() @@ -82,6 +86,23 @@ impl Config { RootConnection::new(&self.node, sudo_keypair).await.unwrap() } + pub fn validator_names<'a>(&'a self) -> Vec { + (0..self.validator_count) + .map(|id| format!("Node{}", id)) + .collect() + } + + pub fn synthetic_network_urls(&self) -> Vec { + match &self.test_case_params.synthetic_network_urls { + Some(urls) => urls.clone(), + None => self + .validator_names() + .into_iter() + .map(|node_name| format!("http://{}:80/qos", node_name)) + .collect(), + } + } + /// Get a `SignedConnection` where the signer is the first validator. pub async fn get_first_signed_connection(&self) -> SignedConnection { let node = &self.node; @@ -89,6 +110,15 @@ impl Config { let sender = accounts.remove(0); SignedConnection::new(node, sender).await } + + pub async fn create_signed_connections(&self) -> Vec { + futures::future::join_all( + get_validators_keys(self) + .into_iter() + .map(|account| async { SignedConnection::new(&self.node, account).await }), + ) + .await + } } /// Parameters which can be passed to test cases. @@ -114,4 +144,10 @@ pub struct TestCaseParams { /// Adder contract metadata. pub adder_metadata: Option, + + /// Milliseconds of network latency + pub out_latency: Option, + + /// List of URLs for the configuration endpoints of the synthetic-network + pub synthetic_network_urls: Option>, } diff --git a/e2e-tests/src/lib.rs b/e2e-tests/src/lib.rs index 9f150c60b8..1bf9a76cfd 100644 --- a/e2e-tests/src/lib.rs +++ b/e2e-tests/src/lib.rs @@ -9,6 +9,8 @@ mod elections; #[cfg(test)] mod rewards; #[cfg(test)] +mod synthetic_network; +#[cfg(test)] mod test; #[cfg(test)] mod transfer; diff --git a/e2e-tests/src/synthetic_network.rs b/e2e-tests/src/synthetic_network.rs new file mode 100644 index 0000000000..51692bc591 --- /dev/null +++ b/e2e-tests/src/synthetic_network.rs @@ -0,0 +1,24 @@ +use log::info; +use synthetic_link::SyntheticNetworkClient; + +pub type Milliseconds = u64; + +pub async fn set_out_latency(milliseconds: Milliseconds, synthetic_url: String) { + info!( + "setting out-latency of node {} to {}ms", + synthetic_url, milliseconds + ); + info!("creating an http client for url {}", synthetic_url); + let mut client = SyntheticNetworkClient::new(synthetic_url); + let mut config = client + .load_config() + .await + .expect("we should be able to download config of the synthetic-network "); + + config.default_link.egress.latency = milliseconds; + + client + .commit_config(&config) + .await + .expect("unable to commit network configuration"); +} diff --git a/e2e-tests/src/test/high_latency.rs b/e2e-tests/src/test/high_latency.rs new file mode 100644 index 0000000000..0c60b0bec8 --- /dev/null +++ b/e2e-tests/src/test/high_latency.rs @@ -0,0 +1,96 @@ +use std::cmp::max; + +use aleph_client::{ + pallets::session::SessionApi, + waiting::{AlephWaiting, BlockStatus}, +}; +use log::info; + +use crate::{config::setup_test, synthetic_network::set_out_latency}; + +const OUT_LATENCY: u64 = 500; + +/// Test if nodes are able to proceed despite high latency. More precisely, it first awaits predefined number of sessions, sets +/// egress-latency for each node using same value (default is 500 milliseconds) and verifies if after it was able to proceed two +/// more sessions. +#[tokio::test] +pub async fn high_out_latency_for_all() -> anyhow::Result<()> { + let config = setup_test(); + let out_latency = config.test_case_params.out_latency.unwrap_or(OUT_LATENCY); + + let connections = config.create_signed_connections().await; + info!("waiting for at least session 3"); + for connection in &connections { + if connection.get_session(None).await < 3 { + connection.wait_for_session(3, BlockStatus::Finalized).await; + } + } + + info!("setting out-latency"); + for synthetic_url in config.synthetic_network_urls() { + info!( + "setting out-latency of node {} to {}", + synthetic_url, out_latency + ); + set_out_latency(out_latency, synthetic_url).await; + } + + let mut max_session = 0; + for connection in &connections { + let node_session = connection.get_session(None).await; + max_session = max(max_session, node_session); + } + info!("current session is {}", max_session); + + for connection in connections { + connection + .wait_for_session(max_session + 2, BlockStatus::Finalized) + .await; + } + Ok(()) +} + +/// Test if nodes are able to proceed despite high latency, but set only for a subset of nodes. More precisely, it first awaits +/// predefined number of sessions, sets egress-latency for 1/3n of nodes using same value (default is 500 milliseconds) and +/// verifies if after it was able to proceed two more sessions. +#[tokio::test] +pub async fn high_out_latency_for_each_quorum() -> anyhow::Result<()> { + let config = setup_test(); + let out_latency = config.test_case_params.out_latency.unwrap_or(OUT_LATENCY); + + let connections = config.create_signed_connections().await; + info!("waiting for at least session 3"); + for connection in &connections { + if connection.get_session(None).await < 3 { + connection.wait_for_session(3, BlockStatus::Finalized).await; + } + } + + info!("setting out-latency"); + for synthetic_url in config + .synthetic_network_urls() + .into_iter() + .take(((config.validator_count - 1) / 3 + 1) as usize) + { + info!( + "setting out-latency of node {} to {}", + synthetic_url, out_latency + ); + set_out_latency(out_latency, synthetic_url).await; + } + + let mut max_session = 0; + for connection in &connections { + let node_session = connection.get_session(None).await; + max_session = max(max_session, node_session); + } + info!("current session is {}", max_session); + + info!("waiting for session {}", max_session + 2); + for connection in connections { + connection + .wait_for_session(max_session + 2, BlockStatus::Finalized) + .await; + } + Ok(()) +} diff --git a/e2e-tests/src/test/mod.rs b/e2e-tests/src/test/mod.rs index afadd91b9f..367ae28eda 100644 --- a/e2e-tests/src/test/mod.rs +++ b/e2e-tests/src/test/mod.rs @@ -6,6 +6,7 @@ pub use era_payout::era_payouts_calculated_correctly; pub use era_validators::era_validators; pub use fee::fee_calculation; pub use finalization::finalization; +pub use high_latency::{high_out_latency_for_all, high_out_latency_for_each_quorum}; pub use rewards::{ change_stake_and_force_new_era, disable_node, force_new_era, points_basic, points_stake_change, }; @@ -26,6 +27,7 @@ mod era_validators; mod fee; mod finalization; mod helpers; +mod high_latency; mod rewards; mod staking; mod transfer; diff --git a/scripts/synthetic-network/README.md b/scripts/synthetic-network/README.md index ce2897ea5a..836457f996 100644 --- a/scripts/synthetic-network/README.md +++ b/scripts/synthetic-network/README.md @@ -19,3 +19,23 @@ interact with its web-ui. Additionally, this folder contains an example .js script introducing API of the synthetic-network. You can use it by executing `run_script_for_synthetic-network.sh --script-path ./latency.js`. +# How to run e2e-tests that use synthetic-network + +All following commands are run from within root folder of this repository. + +```shell +# build aleph-node docker-image +# it assumes that aleph-node binary is stored at ./target/release/aleph-node +docker build -t aleph-node:latest -f docker/Dockerfile . + +# run synthetic-network with aleph-node using docker-compose +# by default, it should build for you a docker-image for synthetic-network +# consult its help for available options +./scripts/synthetic-network/run_consensus_synthetic-network.sh + +# run e2e-tests +cd e2e-tests +# set an ENV variable required by the e2e-test, namely a list of URLs for synthetic-network configuration endpoints +export SYNTHETIC_URLS="http://localhost:3000/qos,http://localhost:3001/qos,http://localhost:3002/qos,http://localhost:3003/qos,http://localhost:3004/qos" +cargo test latency +``` diff --git a/scripts/synthetic-network/build_synthetic-network.sh b/scripts/synthetic-network/build_synthetic-network.sh index ddb803829c..e25eb456c8 100755 --- a/scripts/synthetic-network/build_synthetic-network.sh +++ b/scripts/synthetic-network/build_synthetic-network.sh @@ -4,27 +4,17 @@ set -euo pipefail source ./scripts/common.sh -GIT_COMMIT=${GIT_COMMIT:-72bbb4fde915e4132c19cd7ce3605364abac58a5} +UPDATE=${UPDATE:-true} -TMPDIR="$(dirname $0)/vendor" -mkdir -p $TMPDIR -log "created a temporary folder at $TMPDIR" +if [[ "$UPDATE" = true ]]; then + git submodule init + git submodule update +fi pushd . - -log "cloning synthetic-network's git repo" -cd $TMPDIR -if [[ ! -d ./synthetic-network ]]; then - git clone https://github.com/daily-co/synthetic-network.git -fi -cd synthetic-network -git fetch origin -git checkout $GIT_COMMIT +cd scripts/synthetic-network/vendor/synthetic-network log "building base docker image for synthetic-network with support for synthetic-network" -log "patching synthetic network" -# aleph-node crashes since it uses newer glibc than this image -sed -i 's/FROM node:12.20.2/FROM node:19.2/' Dockerfile docker build -t syntheticnet . popd diff --git a/scripts/synthetic-network/run_consensus_synthetic-network.sh b/scripts/synthetic-network/run_consensus_synthetic-network.sh index 9c66c4d0f4..6cc4522217 100755 --- a/scripts/synthetic-network/run_consensus_synthetic-network.sh +++ b/scripts/synthetic-network/run_consensus_synthetic-network.sh @@ -15,17 +15,16 @@ Usage: IMPORTANT: this script requires aleph-node:latest docker image. --no-build-image skip docker image build - --commit 72bbb4fde915e4132c19cd7ce3605364abac58a5 - commit hash used to build synthetic-network, default is 72bbb4fde915e4132c19cd7ce3605364abac58a5 + --no-update + skip git-submodule update for the synthetic-network repository EOF exit 0 } function build_test_image() { - local commit=$1 - local path=$2 + local path=$1 - GIT_COMMIT=$commit ${path}/build_synthetic-network.sh + ${path}/build_synthetic-network.sh } while [[ $# -gt 0 ]]; do @@ -34,9 +33,9 @@ while [[ $# -gt 0 ]]; do BUILD_IMAGE=false shift ;; - --commit) - GIT_COMMIT="$2" - shift;shift + --no-update) + UPDATE=false + shift ;; --help) usage @@ -49,12 +48,17 @@ while [[ $# -gt 0 ]]; do done BUILD_IMAGE=${BUILD_IMAGE:-true} -GIT_COMMIT=${GIT_COMMIT:-72bbb4fde915e4132c19cd7ce3605364abac58a5} +UPDATE=${UPDATE:-true} + +if [[ "$UPDATE" = true ]]; then + git submodule init + git submodule update +fi if [[ "$BUILD_IMAGE" = true ]]; then log "building custom docker image for synthetic-network tests" path=$(dirname $0) - build_test_image $GIT_COMMIT $path + build_test_image $path fi log "running synthetic-network" diff --git a/scripts/synthetic-network/run_script_for_synthetic-network.sh b/scripts/synthetic-network/run_script_for_synthetic-network.sh index b8b44d98c3..419df5ad4b 100755 --- a/scripts/synthetic-network/run_script_for_synthetic-network.sh +++ b/scripts/synthetic-network/run_script_for_synthetic-network.sh @@ -12,25 +12,25 @@ Usage: IMPORTANT: first you need to call 'scripts/run_consensus_synthetic-network.sh' and let it run in background. It spawns docker-compose configured with synthetic-network. It requires node.js to run. - --commit 72bbb4fde915e4132c19cd7ce3605364abac58a5 - commit hash used to build synthetic-network, default is 72bbb4fde915e4132c19cd7ce3605364abac58a5 --script-path scripts/vendor/synthetic-network/frontend/udp_rate_sine_demo.js path to a synthetic-network scrypt. Default is a demo scripts/vendor/synthetic-network/frontend/udp_rate_sine_demo.js from the synthetic-network repo. Please consult synthetic-network repo for details: https://github.com/daily-co/synthetic-network + --no-update + skip git-submodule update for the synthetic-network repository EOF exit 0 } while [[ $# -gt 0 ]]; do case $1 in - --commit) - GIT_COMMIT="$2" - shift;shift - ;; --script-path) SCRIPT_PATH="$2" shift;shift ;; + --no-update) + UPDATE=false + shift + ;; --help) usage shift @@ -41,23 +41,16 @@ while [[ $# -gt 0 ]]; do esac done -GIT_COMMIT=${GIT_COMMIT:-72bbb4fde915e4132c19cd7ce3605364abac58a5} SCRIPT_PATH=${SCRIPT_PATH:-scripts/vendor/synthetic-network/frontend/udp_rate_sine_demo.js} SCRIPT_PATH=$(realpath $SCRIPT_PATH) +UPDATE=${UPDATE:-true} -TMPDIR="$(dirname $0)/vendor" -mkdir -p $TMPDIR -log "created a temporary folder at $TMPDIR" - -log "cloning synthetic-network's git repo" -cd $TMPDIR -if [[ ! -d ./synthetic-network ]]; then - git clone https://github.com/daily-co/synthetic-network.git +if [[ "$UPDATE" = true ]]; then + git submodule init + git submodule update fi -cd synthetic-network -git fetch origin -git checkout $GIT_COMMIT -cd frontend + +cd synthetic-network/frontend log "running .js script" node $SCRIPT_PATH ${@:1} diff --git a/scripts/synthetic-network/synthetic-link/Cargo.lock b/scripts/synthetic-network/synthetic-link/Cargo.lock new file mode 100644 index 0000000000..c583cf2385 --- /dev/null +++ b/scripts/synthetic-network/synthetic-link/Cargo.lock @@ -0,0 +1,1319 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bumpalo" +version = "3.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" + +[[package]] +name = "bytes" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" + +[[package]] +name = "cc" +version = "1.0.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d63b9e9c07271b9957ad22c173bae2a4d9a81127680962039296abcd2f8251d" +dependencies = [ + "bitflags", + "clap_derive", + "clap_lex", + "is-terminal", + "once_cell", + "strsim", + "termcolor", +] + +[[package]] +name = "clap_derive" +version = "4.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "encoding_rs" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "fastrand" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +dependencies = [ + "instant", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" + +[[package]] +name = "futures-sink" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" + +[[package]] +name = "futures-task" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" + +[[package]] +name = "futures-util" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "h2" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "http" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" +dependencies = [ + "libc", + "windows-sys 0.42.0", +] + +[[package]] +name = "ipnet" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec947b7a4ce12e3b87e353abae7ce124d025b6c7d6c5aea5cc0bcf92e9510ded" + +[[package]] +name = "is-terminal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330" +dependencies = [ + "hermit-abi 0.2.6", + "io-lifetimes", + "rustix", + "windows-sys 0.42.0", +] + +[[package]] +name = "itoa" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" + +[[package]] +name = "js-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.138" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" + +[[package]] +name = "linux-raw-sys" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "mio" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.42.0", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "num_cpus" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +dependencies = [ + "hermit-abi 0.1.19", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + +[[package]] +name = "openssl" +version = "0.10.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29d971fd5722fec23977260f6e81aa67d2f22cadbdc2aa049f1022d9a3be1566" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5454462c0eced1e97f2ec09036abc8da362e66802f66fd20f86854d9d8cbcbc4" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "os_str_bytes" +version = "6.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys 0.42.0", +] + +[[package]] +name = "percent-encoding" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "reqwest" +version = "0.11.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rustix" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.42.0", +] + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + +[[package]] +name = "schannel" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +dependencies = [ + "lazy_static", + "windows-sys 0.36.1", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "security-framework" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "socket2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synthetic-link" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "env_logger", + "log", + "reqwest", + "serde", + "serde_json", + "serde_repr", + "tokio", +] + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" +dependencies = [ + "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.42.0", +] + +[[package]] +name = "tokio-macros" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "unicode-bidi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" + +[[package]] +name = "web-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", +] + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] diff --git a/scripts/synthetic-network/synthetic-link/Cargo.toml b/scripts/synthetic-network/synthetic-link/Cargo.toml new file mode 100644 index 0000000000..2b0226b48a --- /dev/null +++ b/scripts/synthetic-network/synthetic-link/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "synthetic-link" +version = "0.1.0" +authors = ["Cardinal Cryptography"] +edition = "2021" +license = "Apache 2.0" + +[dependencies] +anyhow = "1.0.66" +clap = { version = "4.0.29", features = ["derive"] } +env_logger = "0.10.0" +log = "0.4.17" +reqwest = { version = "0.11.13", features = ["json"] } +serde = { version = "1.0.149", features = ["derive"] } +serde_json = "1.0.89" +serde_repr = "0.1.9" +tokio = { version = "1.23.0", features = ["full"] } diff --git a/scripts/synthetic-network/synthetic-link/src/lib.rs b/scripts/synthetic-network/synthetic-link/src/lib.rs new file mode 100644 index 0000000000..ba5f5a5c96 --- /dev/null +++ b/scripts/synthetic-network/synthetic-link/src/lib.rs @@ -0,0 +1,266 @@ +use std::ops::RangeInclusive; + +use anyhow::bail; +use reqwest::Client; +use serde::{Deserialize, Serialize}; +use serde_repr::{Deserialize_repr, Serialize_repr}; + +const DEFAULT_SYNTHETIC_NETWORK: SyntheticNetwork = SyntheticNetwork { + default_link: DEFAULT_SYNTHETIC_LINK, + flows: Vec::new(), +}; + +const DEFAULT_SYNTHETIC_LINK: SyntheticLink = SyntheticLink { + ingress: DEFAULT_QOS, + egress: DEFAULT_QOS, +}; + +const DEFAULT_QOS: QualityOfService = QualityOfService { + rate: 1000000000, + loss: StrengthParam::zero(), + latency: 0, + jitter: 0, + jitter_strength: StrengthParam::zero(), + reorder_packets: false, +}; + +const DEFAULT_FLOW: Flow = Flow { + ip: IpPattern::All, + protocol: Protocol::All, + port_range: PortRange::all(), +}; + +#[derive(Serialize, Deserialize, Clone)] +pub struct SyntheticNetwork { + pub default_link: SyntheticLink, + pub flows: Vec, +} + +impl Default for SyntheticNetwork { + fn default() -> Self { + DEFAULT_SYNTHETIC_NETWORK + } +} + +#[derive(Serialize, Deserialize, Clone)] +pub struct SyntheticLink { + pub ingress: QualityOfService, + pub egress: QualityOfService, +} + +impl Default for SyntheticLink { + fn default() -> Self { + DEFAULT_SYNTHETIC_LINK + } +} + +#[derive(Serialize, Deserialize, Clone)] +pub struct QualityOfService { + pub rate: u64, + pub loss: StrengthParam, + pub latency: u64, + pub jitter: u64, + pub jitter_strength: StrengthParam, + pub reorder_packets: bool, +} + +impl Default for QualityOfService { + fn default() -> Self { + DEFAULT_QOS + } +} + +#[derive(Serialize, Deserialize, Clone)] +pub struct SyntheticFlow { + pub label: NonEmptyString, + pub flow: Flow, + pub link: SyntheticLink, +} + +impl SyntheticFlow { + pub fn new(label: NonEmptyString) -> Self { + Self { + label, + flow: DEFAULT_FLOW, + link: DEFAULT_SYNTHETIC_LINK, + } + } +} + +#[derive(Serialize, Deserialize, Clone)] +pub struct Flow { + pub ip: IpPattern, + pub protocol: Protocol, + #[serde(flatten)] + pub port_range: PortRange, +} + +impl Default for Flow { + fn default() -> Self { + DEFAULT_FLOW + } +} + +/// Simple wrapper for the `String` type representing only non-empty strings. +#[derive(Serialize, Deserialize, Clone)] +pub struct NonEmptyString(String); + +impl NonEmptyString { + /// Creates an instance of the NonEmptyString type. Bails if provided value `is_empty`. + pub fn new(value: String) -> anyhow::Result { + if value.is_empty() { + bail!("`value` must be non-empty"); + } + Ok(Self(value)) + } +} + +impl AsRef for NonEmptyString { + fn as_ref(&self) -> &String { + &self.0 + } +} + +/// Simple wrapper for the `f64` type representing number in range 0..=1. +#[derive(Serialize, Deserialize, Clone)] +pub struct StrengthParam(f64); + +impl Default for StrengthParam { + fn default() -> Self { + Self(0.0) + } +} + +impl StrengthParam { + /// Creates an instance of the `StrengthParam` type. Bails if provided value is not withing 0..=1 range. + pub fn new(value: f64) -> anyhow::Result { + if value > 1.0 { + bail!("value shouldn't be larger than 1"); + } + if value < 0.0 { + bail!("value shouldn't be smaller than 0"); + } + Ok(Self(value)) + } + + const fn zero() -> Self { + Self(0.0) + } +} + +impl AsRef for StrengthParam { + fn as_ref(&self) -> &f64 { + &self.0 + } +} + +#[derive(Serialize_repr, Deserialize_repr, Clone)] +#[repr(u8)] +pub enum Protocol { + Icmp = 1, + Tcp = 6, + Udp = 17, + All = 0, +} + +/// Simple wrapper for the `RangeInclusive` type. +#[derive(Serialize, Deserialize, Clone)] +#[serde(try_from = "PortRangeSerde", into = "PortRangeSerde")] +pub struct PortRange(RangeInclusive); + +impl PortRange { + pub const fn all() -> Self { + Self(0..=u16::MAX) + } + + /// Creates an instance of the `PortRange` type. Bails if `port_min > port_max`. + pub fn new(port_min: u16, port_max: u16) -> anyhow::Result { + if port_min > port_max { + bail!("`port_min` is larger than `port_max`"); + } + Ok(Self(port_min..=port_max)) + } +} + +impl AsRef> for PortRange { + fn as_ref(&self) -> &RangeInclusive { + &self.0 + } +} + +#[derive(Serialize, Deserialize, Clone)] +struct PortRangeSerde { + port_min: u16, + port_max: u16, +} + +impl TryFrom for PortRange { + type Error = anyhow::Error; + + fn try_from(value: PortRangeSerde) -> Result { + Self::new(value.port_min, value.port_max) + } +} + +impl From for PortRangeSerde { + fn from(value: PortRange) -> Self { + PortRangeSerde { + port_min: *value.0.start(), + port_max: *value.0.end(), + } + } +} + +/// Custom type for representing IP patterns, namely `all addresses` or any other specific value. +#[derive(Serialize, Deserialize, Clone)] +#[serde(from = "IpPatternSerde", into = "IpPatternSerde")] +pub enum IpPattern { + All, + Ip(u32), +} + +#[derive(Serialize, Deserialize, Clone)] +struct IpPatternSerde(u32); + +impl From for IpPattern { + fn from(value: IpPatternSerde) -> Self { + match value.0 { + 0 => IpPattern::All, + ip => IpPattern::Ip(ip), + } + } +} + +impl From for IpPatternSerde { + fn from(value: IpPattern) -> Self { + let ip = match value { + IpPattern::All => 0, + IpPattern::Ip(ip) => ip, + }; + IpPatternSerde(ip) + } +} + +pub struct SyntheticNetworkClient { + client: Client, + url: String, +} + +impl SyntheticNetworkClient { + pub fn new(url: String) -> Self { + SyntheticNetworkClient { + client: Client::new(), + url, + } + } + + pub async fn commit_config(&mut self, config: &SyntheticNetwork) -> anyhow::Result<()> { + let result = self.client.post(&self.url).json(config).send().await; + Ok(result.map(|_| ())?) + } + + pub async fn load_config(&mut self) -> anyhow::Result { + let result = self.client.get(&self.url).send().await?; + Ok(result.json::().await?) + } +} diff --git a/scripts/synthetic-network/synthetic-link/src/main.rs b/scripts/synthetic-network/synthetic-link/src/main.rs new file mode 100644 index 0000000000..01f7a68924 --- /dev/null +++ b/scripts/synthetic-network/synthetic-link/src/main.rs @@ -0,0 +1,34 @@ +use clap::{arg, Parser}; +use log::info; +use synthetic_link::{SyntheticNetwork, SyntheticNetworkClient}; + +#[derive(Parser, Debug)] +struct Args { + #[arg(short, long, default_value = "http://Node0:80/qos")] + url: String, +} + +#[tokio::main] +async fn main() { + env_logger::init(); + + let args = Args::parse(); + let synth_net_url = args.url; + + info!("reading SyntheticNetwork configuration from stdin"); + let deserializer = serde_json::Deserializer::from_reader(std::io::stdin()); + let synth_net_config: SyntheticNetwork = deserializer + .into_iter() + .next() + .unwrap_or_else(|| panic!("no configuration on stdin")) + .unwrap_or_else(|e| panic!("unable to parse SyntheticNetwork config: {}", e)); + info!("parsed SyntheticNetwork configuration"); + + info!("commiting configuration"); + let mut synth_net_client = SyntheticNetworkClient::new(synth_net_url); + synth_net_client + .commit_config(&synth_net_config) + .await + .unwrap_or_else(|e| panic!("failed to commit SyntheticNetwork configuration: {}", e)); + info!("successfully committed new configuration"); +} diff --git a/scripts/synthetic-network/vendor/synthetic-network b/scripts/synthetic-network/vendor/synthetic-network new file mode 160000 index 0000000000..72bbb4fde9 --- /dev/null +++ b/scripts/synthetic-network/vendor/synthetic-network @@ -0,0 +1 @@ +Subproject commit 72bbb4fde915e4132c19cd7ce3605364abac58a5 diff --git a/shell.nix b/shell.nix index d21ea4d5ee..030d32db42 100644 --- a/shell.nix +++ b/shell.nix @@ -6,7 +6,7 @@ let nixpkgs = versions.nixpkgs; env = versions.stdenv; project = import ./default.nix ( buildOptions // { inherit versions; } ); - rust = nixpkgs.rust.override { + rust = versions.rustToolchain.rust.override { extensions = [ "rust-src" ]; }; nativeBuildInputs = [rust nixpkgs.cacert nixpkgs.openssl] ++ project.nativeBuildInputs; @@ -15,4 +15,6 @@ nixpkgs.mkShell.override { stdenv = env; } { inherit nativeBuildInputs; inherit (project) buildInputs shellHook; + # RUST_SRC_PATH might be needed by the `rust-analyzer` + RUST_SRC_PATH = "${versions.rustToolchain.rust-src}/lib/rustlib/src/rust/library/"; }