From 86db99143c7496569ff2716373833ea0018a010c Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Tue, 17 Dec 2024 03:48:51 +0700 Subject: [PATCH 01/31] fix(repo): Solving publisher slowness (#352) * feat(repo): add sv-emitter package * build(repo): adjust run-publisher * feat(repo): first version of consumer * feat(repo): add the rest of payloads * refactor(repo): reuse executors * fix(repo): tests * build(repo): configure devops to emitter/consumer * build(repo): update chart version * fix(repo): consumer cli argument * build(repo): docker action * build(repo): fix consumer chart * build(repo): fix consumer chart * build(repo): fix consumer chart * build(repo): chart * fix(repo): general stuff * build(repo): docker action * ci(repo): fix * fix(repo): chain config * fix(repo): docker images * feat(repo): improve docker build * refactor(repo): a lot of improvements * fix(repo): fix helm chart nats config * feat(repo): worked using mirror * fix(repo): adjust nats cluster config * build(repo): adjust github action * build(repo): update chart version * build(repo): fix docker images * build(repo): lint warnings * ci(repo): adjust docker action * build(repo): fix docker file * fix(repo): stream creation * build(repo): fix tls for nats * build(repo): fix chart * build(repo): fix chart * build(repo): fix chart * build(repo): fix chart * fix(repo): use sts instead of deployment for consumer * fix(repo): fix chart * fix(repo): remove initcontainer * fix(repo): update chart * fix(repo): fix resources on consumer * fix(repo): bump chart * fix(repo): bump chart * fix(repo): bump chart * build(repo): fix makefile * build(repo): add publisher into one single Dockerfile * ci(repo): fix docker publish action * build(repo): fix build docker * ci(repo): fix docker action * ci(repo): fix tests * ci(repo): fix ci.yaml * build(repo): adjust fuel dependencies features --- .editorconfig | 4 + .github/workflows/ci.yaml | 44 +- .github/workflows/docker_publish.yaml | 20 +- .gitignore | 1 + .prettierignore | 3 +- .rustfmt.toml | 5 + Cargo.lock | 109 +- Cargo.toml | 23 +- Makefile | 40 +- Tiltfile | 74 +- cluster/README.md | 68 +- cluster/charts/fuel-streams/Chart.yaml | 2 +- .../charts/fuel-streams/templates/_hpa.yaml | 56 + .../fuel-streams/templates/certificate.yaml | 52 - .../templates/consumer/statefulset.yaml | 84 + .../templates/nats/certificate.yaml | 52 + .../{ => nats}/external-service.yaml | 32 +- .../publisher/network-configmap.yaml | 31 - .../templates/publisher/statefulset.yaml | 66 +- .../templates/webserver/deployment.yaml | 8 +- .../tests/consumer/deployment_test.yaml | 305 + .../tests/external_service_test.yaml | 2 +- .../tests/publisher/network-configmap.yaml | 87 - cluster/charts/fuel-streams/values.yaml | 422 +- cluster/docker/fuel-core.Dockerfile | 84 + .../docker/fuel-streams-publisher.Dockerfile | 131 - cluster/docker/nats.conf | 84 +- cluster/docker/sv-consumer.Dockerfile | 75 + cluster/scripts/build_docker.sh | 84 + cluster/scripts/build_publisher.sh | 16 - cluster/scripts/gen_env_secret.sh | 2 +- cluster/scripts/setup_k8s.sh | 4 +- cluster/scripts/setup_minikube.sh | 20 +- crates/fuel-streams-core/Cargo.toml | 19 +- .../src}/fuel_core_like.rs | 38 +- .../fuel-streams-core/src/fuel_core_types.rs | 14 +- crates/fuel-streams-core/src/inputs/types.rs | 23 + crates/fuel-streams-core/src/lib.rs | 10 +- crates/fuel-streams-core/src/logs/types.rs | 104 +- .../fuel-streams-core/src/nats/nats_client.rs | 8 +- .../src/nats/nats_client_opts.rs | 35 + crates/fuel-streams-core/src/outputs/types.rs | 28 +- .../fuel-streams-core/src/primitive_types.rs | 176 +- .../fuel-streams-core/src/receipts/types.rs | 447 +- .../src/stream}/fuel_streams.rs | 31 +- crates/fuel-streams-core/src/stream/mod.rs | 2 + .../src/stream/stream_impl.rs | 28 +- .../src/transactions/types.rs | 28 +- crates/fuel-streams-core/src/types.rs | 3 +- .../fuel-streams-core/src/utxos/subjects.rs | 22 +- crates/fuel-streams-core/src/utxos/types.rs | 2 +- crates/fuel-streams-executors/Cargo.toml | 31 + crates/fuel-streams-executors/src/blocks.rs | 81 + crates/fuel-streams-executors/src/inputs.rs | 129 + crates/fuel-streams-executors/src/lib.rs | 250 + crates/fuel-streams-executors/src/logs.rs | 38 + crates/fuel-streams-executors/src/outputs.rs | 155 + crates/fuel-streams-executors/src/receipts.rs | 238 + .../src/transactions.rs | 100 + crates/fuel-streams-executors/src/utxos.rs | 85 + crates/fuel-streams-publisher/Cargo.toml | 23 +- crates/fuel-streams-publisher/src/lib.rs | 13 - crates/fuel-streams-publisher/src/main.rs | 3 +- .../src/publisher/blocks_streams.rs | 25 +- .../src/publisher/mod.rs | 145 +- .../src/publisher/payloads/blocks.rs | 29 - .../src/publisher/payloads/inputs.rs | 178 - .../src/publisher/payloads/logs.rs | 39 - .../src/publisher/payloads/mod.rs | 22 - .../src/publisher/payloads/outputs.rs | 161 - .../src/publisher/payloads/receipts.rs | 235 - .../src/publisher/payloads/transactions.rs | 177 - .../src/publisher/payloads/utxos.rs | 145 - .../fuel-streams-publisher/src/server/http.rs | 3 +- .../src/telemetry/system.rs | 83 +- crates/sv-consumer/Cargo.toml | 48 + crates/sv-consumer/src/cli.rs | 22 + crates/sv-consumer/src/lib.rs | 31 + crates/sv-consumer/src/main.rs | 134 + crates/sv-emitter/Cargo.lock | 7553 +++++++++++++++++ crates/sv-emitter/Cargo.toml | 51 + crates/sv-emitter/src/cli.rs | 24 + crates/sv-emitter/src/lib.rs | 2 + crates/sv-emitter/src/main.rs | 205 + crates/sv-emitter/src/shutdown.rs | 104 + examples/multiple-streams.rs | 19 - scripts/run_publisher.sh | 35 +- scripts/set_env.sh | 6 +- tests/Cargo.toml | 2 +- tests/tests/publisher.rs | 93 +- 90 files changed, 11636 insertions(+), 2189 deletions(-) create mode 100644 cluster/charts/fuel-streams/templates/_hpa.yaml delete mode 100644 cluster/charts/fuel-streams/templates/certificate.yaml create mode 100644 cluster/charts/fuel-streams/templates/consumer/statefulset.yaml create mode 100644 cluster/charts/fuel-streams/templates/nats/certificate.yaml rename cluster/charts/fuel-streams/templates/{ => nats}/external-service.yaml (55%) delete mode 100644 cluster/charts/fuel-streams/templates/publisher/network-configmap.yaml create mode 100644 cluster/charts/fuel-streams/tests/consumer/deployment_test.yaml delete mode 100644 cluster/charts/fuel-streams/tests/publisher/network-configmap.yaml create mode 100644 cluster/docker/fuel-core.Dockerfile delete mode 100644 cluster/docker/fuel-streams-publisher.Dockerfile create mode 100644 cluster/docker/sv-consumer.Dockerfile create mode 100755 cluster/scripts/build_docker.sh delete mode 100755 cluster/scripts/build_publisher.sh rename crates/{fuel-streams-publisher/src/publisher => fuel-streams-core/src}/fuel_core_like.rs (92%) rename crates/{fuel-streams-publisher/src/publisher => fuel-streams-core/src/stream}/fuel_streams.rs (87%) create mode 100644 crates/fuel-streams-executors/Cargo.toml create mode 100644 crates/fuel-streams-executors/src/blocks.rs create mode 100644 crates/fuel-streams-executors/src/inputs.rs create mode 100644 crates/fuel-streams-executors/src/lib.rs create mode 100644 crates/fuel-streams-executors/src/logs.rs create mode 100644 crates/fuel-streams-executors/src/outputs.rs create mode 100644 crates/fuel-streams-executors/src/receipts.rs create mode 100644 crates/fuel-streams-executors/src/transactions.rs create mode 100644 crates/fuel-streams-executors/src/utxos.rs delete mode 100644 crates/fuel-streams-publisher/src/publisher/payloads/blocks.rs delete mode 100644 crates/fuel-streams-publisher/src/publisher/payloads/inputs.rs delete mode 100644 crates/fuel-streams-publisher/src/publisher/payloads/logs.rs delete mode 100644 crates/fuel-streams-publisher/src/publisher/payloads/mod.rs delete mode 100644 crates/fuel-streams-publisher/src/publisher/payloads/outputs.rs delete mode 100644 crates/fuel-streams-publisher/src/publisher/payloads/receipts.rs delete mode 100644 crates/fuel-streams-publisher/src/publisher/payloads/transactions.rs delete mode 100644 crates/fuel-streams-publisher/src/publisher/payloads/utxos.rs create mode 100644 crates/sv-consumer/Cargo.toml create mode 100644 crates/sv-consumer/src/cli.rs create mode 100644 crates/sv-consumer/src/lib.rs create mode 100644 crates/sv-consumer/src/main.rs create mode 100644 crates/sv-emitter/Cargo.lock create mode 100644 crates/sv-emitter/Cargo.toml create mode 100644 crates/sv-emitter/src/cli.rs create mode 100644 crates/sv-emitter/src/lib.rs create mode 100644 crates/sv-emitter/src/main.rs create mode 100644 crates/sv-emitter/src/shutdown.rs diff --git a/.editorconfig b/.editorconfig index 72e61c1b..12808c50 100644 --- a/.editorconfig +++ b/.editorconfig @@ -19,3 +19,7 @@ trim_trailing_whitespace = false [*.{yml,yaml}] indent_size = 2 + +[{Makefile,**.mk}] +# Use tabs for indentation (Makefiles require tabs) +indent_style = tab diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8fd6c99a..fd142d16 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,13 +1,7 @@ name: CI on: - workflow_dispatch: pull_request: - types: - - opened - - synchronize - - edited - - reopened push: branches: - main @@ -187,24 +181,24 @@ jobs: - name: Install dependencies run: cargo fetch - test-helm: - needs: install-deps - name: Test Helm - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up Helm - uses: azure/setup-helm@v4 - with: - version: "latest" - - - name: Install helm unittest plugin - run: | - helm plugin install https://github.com/helm-unittest/helm-unittest.git - - - name: Run Helm unit tests - run: | - make helm-test + # test-helm: + # needs: install-deps + # name: Test Helm + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 + # - name: Set up Helm + # uses: azure/setup-helm@v4 + # with: + # version: "latest" + + # - name: Install helm unittest plugin + # run: | + # helm plugin install https://github.com/helm-unittest/helm-unittest.git + + # - name: Run Helm unit tests + # run: | + # make helm-test test: needs: install-deps @@ -364,7 +358,7 @@ jobs: github.event_name == 'workflow_dispatch' needs: - test - - test-helm + # - test-helm - build runs-on: ubuntu-latest permissions: diff --git a/.github/workflows/docker_publish.yaml b/.github/workflows/docker_publish.yaml index 47ba1bd8..ed2d0ba1 100644 --- a/.github/workflows/docker_publish.yaml +++ b/.github/workflows/docker_publish.yaml @@ -20,11 +20,15 @@ concurrency: jobs: build-and-publish-image: runs-on: ubuntu-latest - if: | - (github.event_name == 'release' && github.event.action == 'published') || - github.ref == 'refs/heads/main' || - github.event_name == 'workflow_dispatch' || - github.event_name == 'pull_request' + strategy: + matrix: + package: + - name: fuel-streams-publisher + image: cluster/docker/fuel-core.Dockerfile + - name: sv-emitter + image: cluster/docker/fuel-core.Dockerfile + - name: sv-consumer + image: cluster/docker/sv-consumer.Dockerfile steps: - uses: actions/checkout@v4 @@ -38,5 +42,7 @@ jobs: with: username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - image: ghcr.io/fuellabs/fuel-streams-publisher - dockerfile: cluster/docker/fuel-streams-publisher.Dockerfile + image: ghcr.io/fuellabs/${{ matrix.package.name }} + dockerfile: ${{ matrix.package.image }} + build-args: |- + PACKAGE_NAME=${{ matrix.package.name }} diff --git a/.gitignore b/.gitignore index c3ed4a0a..5e8b6a25 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ coverage/ docs/ **/**/charts/**.tgz values-publisher-secrets.yaml +.vscode/launch.json diff --git a/.prettierignore b/.prettierignore index 8b7b5b96..0063613c 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,2 @@ -helm -cluster +cluster/charts pnpm-lock.yaml diff --git a/.rustfmt.toml b/.rustfmt.toml index aaebb675..2d0df4eb 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -10,3 +10,8 @@ use_field_init_shorthand = true reorder_imports = true reorder_modules = true tab_spaces = 4 +# Add these new settings +format_macro_matchers = true +format_macro_bodies = true +# If you want macros to ignore the max_width setting +overflow_delimited_expr = true diff --git a/Cargo.lock b/Cargo.lock index e1cc9d60..890561a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2825,22 +2825,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "eventsource-client" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43ddc25e1ad2cc0106d5e2d967397b4fb2068a66677ee9b0eea4600e5cfe8fb4" -dependencies = [ - "futures", - "hyper 0.14.31", - "hyper-rustls 0.24.2", - "hyper-timeout 0.4.1", - "log", - "pin-project", - "rand", - "tokio", -] - [[package]] name = "eyre" version = "0.6.12" @@ -3084,7 +3068,6 @@ dependencies = [ "clap 4.5.23", "const_format", "dirs", - "dotenvy", "fuel-core", "fuel-core-chain-config", "fuel-core-compression", @@ -3129,14 +3112,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a10ccde16fd926137070d3baa77a1096c2ff6cdca26d14177139c16e59e697d" dependencies = [ "anyhow", - "base64 0.22.1", "cynic", "derive_more 0.99.18", - "eventsource-client", "fuel-core-types 0.40.2", - "futures", "hex", - "hyper-rustls 0.24.2", "itertools 0.12.1", "reqwest 0.11.27", "schemafy_lib", @@ -3687,14 +3666,19 @@ dependencies = [ name = "fuel-streams-core" version = "0.0.13" dependencies = [ + "anyhow", "async-nats", "async-trait", "chrono", "clap 4.5.23", "displaydoc", "dotenvy", + "fuel-core", + "fuel-core-bin", "fuel-core-client", "fuel-core-importer", + "fuel-core-services", + "fuel-core-storage", "fuel-core-types 0.40.2", "fuel-data-parser", "fuel-streams-macros", @@ -3720,6 +3704,25 @@ dependencies = [ "tokio", ] +[[package]] +name = "fuel-streams-executors" +version = "0.0.13" +dependencies = [ + "anyhow", + "async-nats", + "fuel-core", + "fuel-streams-core", + "futures", + "num_cpus", + "rayon", + "serde", + "serde_json", + "sha2 0.10.8", + "thiserror 2.0.4", + "tokio", + "tracing", +] + [[package]] name = "fuel-streams-macros" version = "0.0.13" @@ -3746,26 +3749,20 @@ dependencies = [ "elasticsearch", "fuel-core", "fuel-core-bin", - "fuel-core-importer", "fuel-core-services", - "fuel-core-storage", - "fuel-core-types 0.40.2", - "fuel-streams", "fuel-streams-core", + "fuel-streams-executors", "futures", "mockall 0.13.1", "mockall_double", - "num_cpus", "openssl", "parking_lot", "prometheus", "rand", - "rayon", "rust_decimal", "serde", "serde_json", "serde_prometheus", - "sha2 0.10.8", "sysinfo", "thiserror 2.0.4", "tokio", @@ -4573,12 +4570,9 @@ dependencies = [ "futures-util", "http 0.2.12", "hyper 0.14.31", - "log", "rustls 0.21.12", - "rustls-native-certs 0.6.3", "tokio", "tokio-rustls 0.24.1", - "webpki-roots 0.25.4", ] [[package]] @@ -6424,6 +6418,15 @@ dependencies = [ "syn 2.0.90", ] +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + [[package]] name = "number_prefix" version = "0.4.0" @@ -8727,6 +8730,47 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" +[[package]] +name = "sv-consumer" +version = "0.0.13" +dependencies = [ + "anyhow", + "async-nats", + "clap 4.5.23", + "fuel-core", + "fuel-streams-core", + "fuel-streams-executors", + "futures", + "openssl", + "serde_json", + "sv-emitter", + "thiserror 2.0.4", + "tokio", + "tokio-util", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "sv-emitter" +version = "0.0.13" +dependencies = [ + "anyhow", + "async-nats", + "clap 4.5.23", + "fuel-core", + "fuel-core-bin", + "fuel-core-types 0.40.2", + "fuel-streams-core", + "fuel-streams-executors", + "futures", + "openssl", + "thiserror 2.0.4", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "symbolic-common" version = "12.12.3" @@ -9125,7 +9169,9 @@ checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", + "libc", "num-conv", + "num_threads", "powerfmt", "serde", "time-core", @@ -9602,6 +9648,7 @@ dependencies = [ "sharded-slab", "smallvec", "thread_local", + "time", "tracing", "tracing-core", "tracing-log", diff --git a/Cargo.toml b/Cargo.toml index f5b1c85b..9e36651f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,21 +33,31 @@ clap = { version = "4.5", features = ["derive", "env"] } dotenvy = "0.15" displaydoc = "0.2" futures = "0.3" -fuel-core-bin = { version = "0.40.2", features = ["p2p", "relayer", "rocksdb"] } -fuel-core = { version = "0.40.2", features = ["p2p", "relayer", "rocksdb"] } -fuel-core-client = { version = "0.40.2" } +fuel-core-bin = { version = "0.40.2", default-features = false, features = [ + "p2p", + "relayer", + "rocksdb", +] } +fuel-core = { version = "0.40.2", default-features = false, features = [ + "p2p", + "relayer", + "rocksdb", +] } +fuel-core-client = { version = "0.40.2", default-features = false, features = ["std"] } fuel-core-importer = { version = "0.40.2" } fuel-core-storage = { version = "0.40.2" } -fuel-core-types = { version = "0.40.2", features = ["test-helpers", "serde"] } -fuel-core-services = { version = "0.40.2" } +fuel-core-types = { version = "0.40.2", default-features = false, features = ["std", "serde"] } +fuel-core-services = { version = "0.40.2", default-features = false, features = ["test-helpers"] } futures-util = "0.3" itertools = "0.13" mockall = "0.13" mockall_double = "0.3.1" hex = "0.4" pretty_assertions = "1.4" +num_cpus = "1.16" rand = "0.8" serde = { version = "1.0", features = ["derive"] } +rayon = "1.10.0" serde_json = "1.0" sha2 = "0.10" strum = "0.26" @@ -65,6 +75,9 @@ fuel-streams-core = { version = "0.0.13", path = "crates/fuel-streams-core" } fuel-streams-publisher = { version = "0.0.13", path = "crates/fuel-streams-publisher" } fuel-streams-macros = { version = "0.0.13", path = "crates/fuel-streams-macros" } subject-derive = { version = "0.0.13", path = "crates/fuel-streams-macros/subject-derive" } +fuel-streams-executors = { version = "0.0.13", path = "crates/fuel-streams-executors" } +sv-emitter = { version = "0.0.13", path = "crates/sv-emitter" } +sv-consumer = { version = "0.0.13", path = "crates/sv-consumer" } # Workspace projects [workspace.metadata.cargo-machete] diff --git a/Makefile b/Makefile index 937e3fb6..51aa1ac1 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ RUST_VERSION := 1.81.0 clean clean-build cleanup-artifacts test-watch test bench helm-test \ fmt fmt-cargo fmt-rust fmt-prettier fmt-markdown lint lint-cargo \ lint-rust lint-clippy lint-prettier lint-markdown lint-machete \ - audit audit-fix-test audit-fix load-test run-publisher \ + audit audit-fix-test audit-fix load-test run-publisher run-consumer \ run-mainnet-dev run-mainnet-profiling run-testnet-dev run-testnet-profiling \ start-nats stop-nats restart-nats clean-nats minikube-setup minikube-start \ minikube-delete k8s-setup helm-setup cluster-setup pre-cluster \ @@ -112,6 +112,9 @@ clean-build: rm -rf target/ rm -rf node_modules/ +cleanup-artifacts: REPO_OWNER="fuellabs" +cleanup-artifacts: REPO_NAME="data-systems" +cleanup-artifacts: DAYS_TO_KEEP=10 cleanup-artifacts: @echo "Running artifact cleanup..." @./scripts/cleanup_artifacts.sh $(REPO_OWNER) $(REPO_NAME) $(DAYS_TO_KEEP) @@ -120,16 +123,20 @@ cleanup-artifacts: # Testing # ------------------------------------------------------------ +test-watch: PROFILE="all" test-watch: cargo watch -x "test --profile $(PROFILE)" +test: PACKAGE="all" +test: PROFILE="dev" test: + @echo "Running tests for package $(PACKAGE) with profile $(PROFILE)" @if [ "$(PACKAGE)" = "all" ] || [ -z "$(PACKAGE)" ]; then \ - cargo nextest run --cargo-profile $(PROFILE) --workspace --color always --locked --no-tests=pass && \ - cargo test --profile $(PROFILE) --doc --workspace; \ + cargo nextest run --cargo-profile $(PROFILE) --workspace --color always --no-tests=pass --all-features && \ + cargo test --profile $(PROFILE) --doc --workspace --all-features; \ else \ - cargo nextest run --cargo-profile $(PROFILE) -p $(PACKAGE) --color always --locked --no-tests=pass && \ - cargo test --profile $(PROFILE) --doc -p $(PACKAGE); \ + cargo nextest run --cargo-profile $(PROFILE) -p $(PACKAGE) --color always --no-tests=pass --all-features && \ + cargo test --profile $(PROFILE) --doc -p $(PACKAGE) --all-features; \ fi bench: @@ -201,13 +208,15 @@ load-test: # Publisher Run Commands # ------------------------------------------------------------ +run-publisher: NETWORK="testnet" +run-publisher: PACKAGE="sv-emitter" +run-publisher: MODE="dev" +run-publisher: PORT="4000" +run-publisher: TELEMETRY_PORT="8080" +run-publisher: NATS_URL="localhost:4222" +run-publisher: EXTRA_ARGS="" run-publisher: check-network - @./scripts/run_publisher.sh \ - --network $(NETWORK) \ - --mode $(MODE) \ - $(if $(PORT),--port $(PORT),) \ - $(if $(TELEMETRY_PORT),--telemetry-port $(TELEMETRY_PORT),) \ - $(if $(extra_args),--extra-args "$(extra_args)",) + @./scripts/run_publisher.sh run-mainnet-dev: $(MAKE) run-publisher NETWORK=mainnet MODE=dev @@ -221,6 +230,13 @@ run-testnet-dev: run-testnet-profiling: $(MAKE) run-publisher NETWORK=testnet MODE=profiling +run-consumer: NATS_CORE_URL="localhost:4222" +run-consumer: NATS_PUBLISHER_URL="localhost:4223" +run-consumer: + cargo run --package sv-consumer --profile dev -- \ + --nats-core-url $(NATS_CORE_URL) \ + --nats-publisher-url $(NATS_PUBLISHER_URL) + # ------------------------------------------------------------ # Docker Compose # ------------------------------------------------------------ @@ -241,6 +257,8 @@ restart-nats: clean-nats: $(MAKE) run-docker-compose COMMAND="down -v --rmi all --remove-orphans" +reset-nats: clean-nats start-nats + # ------------------------------------------------------------ # Local cluster (Minikube) # ------------------------------------------------------------ diff --git a/Tiltfile b/Tiltfile index 254afdb9..0c3a7bac 100755 --- a/Tiltfile +++ b/Tiltfile @@ -10,15 +10,46 @@ version_settings(True) # Enable 'new version' banner # Load environment variables from .env file dotenv() -# Build publisher image with proper configuration for Minikube +allow_k8s_contexts('minikube') + +# Build sv-emitter +custom_build( + ref='sv-emitter:latest', + command=[ + './cluster/scripts/build_docker.sh', + '--image-name', 'sv-emitter', + '--dockerfile', './cluster/docker/fuel-core.Dockerfile', + '--build-args', '--build-arg PACKAGE_NAME=sv-emitter' + ], + deps=[ + './src', + './Cargo.toml', + './Cargo.lock', + './cluster/docker/fuel-core.Dockerfile' + ], + live_update=[ + sync('./src', '/usr/src'), + sync('./Cargo.toml', '/usr/src/Cargo.toml'), + sync('./Cargo.lock', '/usr/src/Cargo.lock'), + run('cargo build', trigger=['./src', './Cargo.toml', './Cargo.lock']) + ], + skips_local_docker=True, + ignore=['./target'] +) + +# Build sv-consumer custom_build( - ref='fuel-streams-publisher:latest', - command=['./cluster/scripts/build_publisher.sh'], + ref='sv-consumer:latest', + command=[ + './cluster/scripts/build_docker.sh', + '--image-name', 'sv-consumer', + '--dockerfile', './cluster/docker/sv-consumer.Dockerfile' + ], deps=[ './src', './Cargo.toml', './Cargo.lock', - './cluster/docker/fuel-streams-publisher.Dockerfile' + './cluster/docker/sv-consumer.Dockerfile' ], live_update=[ sync('./src', '/usr/src'), @@ -41,45 +72,30 @@ RESOURCES = { 'labels': 'publisher', 'config_mode': ['minimal', 'full'] }, + 'consumer': { + 'name': 'fuel-streams-sv-consumer', + 'ports': ['8082:8082'], + 'labels': 'consumer', + 'config_mode': ['minimal', 'full'] + }, 'nats-core': { 'name': 'fuel-streams-nats-core', - 'ports': ['4222:4222', '8222:8222'], + 'ports': ['4222:4222', '6222:6222', '7422:7422'], 'labels': 'nats', 'config_mode': ['minimal', 'full'] }, 'nats-client': { 'name': 'fuel-streams-nats-client', - 'ports': ['4223:4222', '8443:8443'], + 'ports': ['14222:4222', '17422:7422', '8443:8443'], 'labels': 'nats', 'config_mode': ['minimal', 'full'] }, 'nats-publisher': { 'name': 'fuel-streams-nats-publisher', - 'ports': ['4224:4222'], + 'ports': ['24222:4222', '27422:7422'], 'labels': 'nats', 'config_mode': ['minimal', 'full'] - }, - # 'grafana': { - # 'name': 'fuel-streams-grafana', - # 'ports': ['3000:3000'], - # 'labels': 'monitoring', - # 'config_mode': ['minimal', 'full'] - # }, - # 'prometheus-operator': { - # 'name': 'fuel-streams-prometheus-operator', - # 'labels': 'monitoring', - # 'config_mode': ['minimal', 'full'] - # }, - # 'kube-state-metrics': { - # 'name': 'fuel-streams-kube-state-metrics', - # 'labels': 'monitoring', - # 'config_mode': ['minimal', 'full'] - # }, - # 'node-exporter': { - # 'name': 'fuel-streams-prometheus-node-exporter', - # 'labels': 'monitoring', - # 'config_mode': ['minimal', 'full'] - # } + } } k8s_yaml(helm( diff --git a/cluster/README.md b/cluster/README.md index 389ef86f..835541bd 100755 --- a/cluster/README.md +++ b/cluster/README.md @@ -10,15 +10,15 @@ The latter is intended for local development, but it also allows us to deploy th The following are prerequisites for spinning up the fuel-data-systems cluster locally: -- kubectl - `https://www.howtoforge.com/how-to-install-kubernetes-with-minikube-ubuntu-20-04/` +- kubectl + `https://www.howtoforge.com/how-to-install-kubernetes-with-minikube-ubuntu-20-04/` -- Tilt: - `https://docs.tilt.dev/install.html` +- Tilt: + `https://docs.tilt.dev/install.html` -- minikube based on the following description: - `https://phoenixnap.com/kb/install-minikube-on-ubuntu` - `https://minikube.sigs.k8s.io/docs/start/` +- minikube based on the following description: + `https://phoenixnap.com/kb/install-minikube-on-ubuntu` + `https://minikube.sigs.k8s.io/docs/start/` ...or alternatively use this tool which will automatically set up your cluster: `https://github.com/tilt-dev/ctlptl##minikube-with-a-built-in-registry` @@ -26,32 +26,36 @@ The following are prerequisites for spinning up the fuel-data-systems cluster lo ## Setup 1. To setup and start the local environment, run: - ```bash - make cluster-setup # Sets up both minikube and kubernetes configuration - ``` - Alternatively, you can run the setup steps individually: - ```bash - make minikube-setup # Sets up minikube with required addons - make k8s-setup # Configures kubernetes with proper namespace and context - ``` + ```bash + make cluster-setup # Sets up both minikube and kubernetes configuration + ``` - You can also start the minikube cluster without running the setup script: - ```bash - make minikube-start # Start minikube cluster - ``` + Alternatively, you can run the setup steps individually: + + ```bash + make minikube-setup # Sets up minikube with required addons + make k8s-setup # Configures kubernetes with proper namespace and context + ``` + + You can also start the minikube cluster without running the setup script: + + ```bash + make minikube-start # Start minikube cluster + ``` 2. Start the Tilt services: - ```bash - make cluster-up # Starts Tiltfile services - ``` + ```bash + make cluster-up # Starts Tiltfile services + ``` You can use the following commands to manage the services: + ```bash -make cluster-up # Start services -make cluster-down # Stop services -make cluster-reset # Reset services -make minikube-start # Start minikube (if you've already run setup before) +make cluster-up # Start services +make cluster-down # Stop services +make cluster-reset # Reset services +make minikube-start # Start minikube (if you've already run setup before) ``` ## Using `k9s` for an interactive terminal UI @@ -62,9 +66,9 @@ Run it with `k9s --context= --namespace=.yaml`. -- Tilt [tutorial](https://docs.tilt.dev/tutorial.html) +- How [kubernetes works](https://www.youtube.com/watch?v=ZuIQurh_kDk) +- Kubernetes [concepts](https://kubernetes.io/docs/concepts/) +- Kubectl [overview](https://kubernetes.io/docs/reference/kubectl/overview/) +- Kubectl [cheat sheet](https://kubernetes.io/docs/reference/kubectl/cheatsheet/) +- Helm [chart tutorial](https://docs.bitnami.com/kubernetes/how-to/create-your-first-helm-chart/), then examine the helm charts in this repository, and the values yaml files that are used to template them. The defults values are in the charts themselves as `values.yaml`, and the values for specific configurations are at `values/.yaml`. +- Tilt [tutorial](https://docs.tilt.dev/tutorial.html) diff --git a/cluster/charts/fuel-streams/Chart.yaml b/cluster/charts/fuel-streams/Chart.yaml index 588a1013..ae02c5af 100755 --- a/cluster/charts/fuel-streams/Chart.yaml +++ b/cluster/charts/fuel-streams/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 appVersion: "1.0" description: A Helm chart for Kubernetes name: fuel-streams -version: 0.1.2 +version: 0.4.10 dependencies: - name: nats version: 1.2.6 diff --git a/cluster/charts/fuel-streams/templates/_hpa.yaml b/cluster/charts/fuel-streams/templates/_hpa.yaml new file mode 100644 index 00000000..76482c37 --- /dev/null +++ b/cluster/charts/fuel-streams/templates/_hpa.yaml @@ -0,0 +1,56 @@ +{{- define "k8s.hpa" -}} +{{- $service := .service -}} +{{- $context := .context -}} +{{- $autoscaling := $service.autoscaling -}} +{{- if $autoscaling.enabled }} +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + {{- include "k8s.metadata" (dict "context" $context "suffix" (printf "-%s" $service.name)) | nindent 2 }} + labels: + {{- include "fuel-streams.labels" $context | nindent 4 }} + app.kubernetes.io/component: {{ $service.name }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "fuel-streams.fullname" $context }}-{{ $service.name }} + minReplicas: {{ $autoscaling.minReplicas }} + maxReplicas: {{ $autoscaling.maxReplicas }} + behavior: + scaleDown: + stabilizationWindowSeconds: {{ $autoscaling.behavior.scaleDown.stabilizationWindowSeconds | default 300 }} + policies: + - type: Percent + value: {{ $autoscaling.behavior.scaleDown.percentValue | default 100 }} + periodSeconds: {{ $autoscaling.behavior.scaleDown.periodSeconds | default 15 }} + scaleUp: + stabilizationWindowSeconds: {{ $autoscaling.behavior.scaleUp.stabilizationWindowSeconds | default 0 }} + policies: + - type: Percent + value: {{ $autoscaling.behavior.scaleUp.percentValue | default 100 }} + periodSeconds: {{ $autoscaling.behavior.scaleUp.periodSeconds | default 15 }} + - type: Pods + value: {{ $autoscaling.behavior.scaleUp.podValue | default 4 }} + periodSeconds: {{ $autoscaling.behavior.scaleUp.periodSeconds | default 15 }} + selectPolicy: Max + metrics: + {{- if $autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ $autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if $autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ $autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/cluster/charts/fuel-streams/templates/certificate.yaml b/cluster/charts/fuel-streams/templates/certificate.yaml deleted file mode 100644 index 971e1070..00000000 --- a/cluster/charts/fuel-streams/templates/certificate.yaml +++ /dev/null @@ -1,52 +0,0 @@ -{{- $tls := .Values.tls }} -{{- $externalService := .Values.externalService }} -{{- if and $tls.enabled $externalService.dns }} -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - {{- include "k8s.metadata" (dict "context" . "suffix" "-cert-validator") | nindent 2 }} - labels: - {{- include "fuel-streams.labels" . | nindent 4 }} - {{- include "set-value" (dict "context" $tls "path" "labels") | nindent 4 }} - app.kubernetes.io/service: external-service - annotations: - cert-manager.io/cluster-issuer: {{ $tls.issuer }} - kubernetes.io/ingress.class: nginx - acme.cert-manager.io/http01-ingress-class: nginx - nginx.ingress.kubernetes.io/ssl-redirect: "false" - nginx.ingress.kubernetes.io/force-ssl-redirect: "false" - {{- include "set-value" (dict "context" $tls "path" "annotations") | nindent 4 }} -spec: - ingressClassName: nginx - rules: - - host: {{ $externalService.dns }} - http: - paths: - - path: /.well-known/acme-challenge/ - pathType: Prefix - backend: - service: - name: cm-acme-http-solver - port: - number: 8089 ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - {{- include "k8s.metadata" (dict "context" . "suffix" "-ws-cert") | nindent 2 }} - labels: - {{- include "fuel-streams.labels" . | nindent 4 }} - {{- include "set-value" (dict "context" $tls "path" "labels") | nindent 4 }} - app.kubernetes.io/service: external-service - annotations: - {{- include "set-value" (dict "context" $tls "path" "annotations") | nindent 4 }} -spec: - secretName: {{ include "fuel-streams.fullname" . }}-ws-tls - duration: {{ $tls.duration }} - renewBefore: {{ $tls.renewBefore }} - dnsNames: - - {{ $externalService.dns }} - issuerRef: - name: {{ $tls.issuer }} - kind: ClusterIssuer -{{- end }} diff --git a/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml b/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml new file mode 100644 index 00000000..d0a7a370 --- /dev/null +++ b/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml @@ -0,0 +1,84 @@ +{{- $consumer := .Values.consumer -}} +{{- if $consumer.enabled -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + {{- include "k8s.metadata" (dict "context" . "suffix" "-consumer") | nindent 2 }} + annotations: + {{- include "set-value" (dict "context" $consumer "path" "config.annotations") | nindent 4 }} + labels: + {{- include "fuel-streams.labels" . | nindent 4 }} + {{- include "set-value" (dict "context" $consumer "path" "config.labels") | nindent 4 }} + app.kubernetes.io/component: consumer +spec: + serviceName: {{ include "fuel-streams.fullname" . }}-consumer + {{- if not $consumer.autoscaling.enabled }} + replicas: {{ $consumer.config.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "fuel-streams.selectorLabels" . | nindent 6 }} + {{- include "set-value" (dict "context" $consumer "path" "config.selectorLabels") | nindent 6 }} + app.kubernetes.io/component: consumer + + template: + metadata: + annotations: + {{- include "set-value" (dict "context" $consumer "path" "config.podAnnotations") | nindent 8 }} + labels: + {{- include "fuel-streams.selectorLabels" . | nindent 8 }} + {{- include "set-value" (dict "context" $consumer "path" "config.labels") | nindent 8 }} + app.kubernetes.io/component: consumer + + spec: + {{- if .Values.serviceAccount.create }} + serviceAccountName: {{ include "fuel-streams.serviceAccountName" . }} + {{- end }} + {{- include "set-field-and-value" (dict "context" $consumer "field" "imagePullSecrets" "path" "config.imagePullSecrets") | nindent 6 }} + {{- include "set-field-and-value" (dict "context" $consumer "field" "nodeSelector" "path" "config.nodeSelector") | nindent 6 }} + {{- include "set-field-and-value" (dict "context" $consumer "field" "affinity" "path" "config.affinity") | nindent 6 }} + {{- include "set-field-and-value" (dict "context" $consumer "field" "tolerations" "path" "config.tolerations") | nindent 6 }} + {{- include "k8s.security-context" (dict "context" . "service" "consumer") | nindent 6 }} + + containers: + - name: consumer + image: "{{ $consumer.image.repository }}:{{ $consumer.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ $consumer.image.pullPolicy }} + args: + {{- toYaml $consumer.image.args | nindent 12 }} + + ports: + - name: consumer + containerPort: {{ $consumer.port }} + protocol: TCP + {{- if $consumer.ports }} + {{- toYaml $consumer.ports | nindent 12 }} + {{- end }} + + {{- include "set-field-and-value" (dict "context" $consumer "field" "resources" "path" "config.resources") | nindent 10 }} + {{- include "k8s.probes" (dict "context" . "service" "consumer") | nindent 10 }} + {{- include "k8s.container-security-context" (dict "context" . "service" "consumer") | nindent 10 }} + + env: + {{- range $key, $value := $consumer.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- with $consumer.extraEnv }} + {{- toYaml . | nindent 12 }} + {{- end }} + + envFrom: + - configMapRef: + name: {{ include "fuel-streams.fullname" $ }}-consumer + optional: true + - secretRef: + name: {{ include "fuel-streams.fullname" $ }}-consumer + optional: true + {{- with $consumer.envFrom }} + {{- toYaml . | nindent 12 }} + {{- end }} + + +{{- include "k8s.hpa" (dict "context" . "service" (dict "name" "consumer" "autoscaling" $consumer.autoscaling)) }} +{{- end }} diff --git a/cluster/charts/fuel-streams/templates/nats/certificate.yaml b/cluster/charts/fuel-streams/templates/nats/certificate.yaml new file mode 100644 index 00000000..3425c04c --- /dev/null +++ b/cluster/charts/fuel-streams/templates/nats/certificate.yaml @@ -0,0 +1,52 @@ +{{- $cert := .Values.natsExternalService.certificate}} +{{- $service := .Values.natsExternalService.service }} +{{- if and .Values.natsExternalService.enabled $service.dns }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + {{- include "k8s.metadata" (dict "context" . "suffix" "-nats-cert-validator") | nindent 2 }} + labels: + {{- include "fuel-streams.labels" . | nindent 4 }} + {{- include "set-value" (dict "context" $cert "path" "labels") | nindent 4 }} + app.kubernetes.io/service: external-ws + annotations: + cert-manager.io/cluster-issuer: {{ $cert.issuer }} + kubernetes.io/ingress.class: nginx + acme.cert-manager.io/http01-ingress-class: nginx + nginx.ingress.kubernetes.io/ssl-redirect: "false" + nginx.ingress.kubernetes.io/force-ssl-redirect: "false" + {{- include "set-value" (dict "context" $cert "path" "annotations") | nindent 4 }} +spec: + ingressClassName: nginx + rules: + - host: {{ $service.dns }} + http: + paths: + - path: /.well-known/acme-challenge/ + pathType: Prefix + backend: + service: + name: cm-acme-http-solver + port: + number: 8089 +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + {{- include "k8s.metadata" (dict "context" . "suffix" "-nats-cert") | nindent 2 }} + labels: + {{- include "fuel-streams.labels" . | nindent 4 }} + {{- include "set-value" (dict "context" $cert "path" "labels") | nindent 4 }} + app.kubernetes.io/service: external-ws + annotations: + {{- include "set-value" (dict "context" $cert "path" "annotations") | nindent 4 }} +spec: + secretName: {{ include "fuel-streams.fullname" . }}-nats-tls + duration: {{ $cert.duration }} + renewBefore: {{ $cert.renewBefore }} + dnsNames: + - {{ $service.dns }} + issuerRef: + name: {{ $cert.issuer }} + kind: ClusterIssuer +{{- end }} diff --git a/cluster/charts/fuel-streams/templates/external-service.yaml b/cluster/charts/fuel-streams/templates/nats/external-service.yaml similarity index 55% rename from cluster/charts/fuel-streams/templates/external-service.yaml rename to cluster/charts/fuel-streams/templates/nats/external-service.yaml index 4b2c4602..57afb5a0 100644 --- a/cluster/charts/fuel-streams/templates/external-service.yaml +++ b/cluster/charts/fuel-streams/templates/nats/external-service.yaml @@ -1,15 +1,15 @@ -{{- $externalService := .Values.externalService }} -{{- if and $externalService.enabled $externalService.dns }} +{{- $service := .Values.natsExternalService.service }} +{{- if and .Values.natsExternalService.enabled $service.dns }} apiVersion: v1 kind: Service metadata: - {{- include "k8s.metadata" (dict "context" . "suffix" "-external") | nindent 2 }} + {{- include "k8s.metadata" (dict "context" . "suffix" "-nats-external") | nindent 2 }} labels: {{- include "fuel-streams.labels" . | nindent 4 }} - {{- include "set-value" (dict "context" $externalService "path" "labels") | nindent 4 }} - app.kubernetes.io/service: external-service + {{- include "set-value" (dict "context" $service "path" "labels") | nindent 4 }} + app.kubernetes.io/service: external-ws annotations: - external-dns.alpha.kubernetes.io/hostname: {{ $externalService.dns | quote }} + external-dns.alpha.kubernetes.io/hostname: {{ $service.dns | quote }} external-dns.alpha.kubernetes.io/cloudflare-proxied: "false" service.beta.kubernetes.io/aws-load-balancer-attributes: load_balancing.cross_zone.enabled=true service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp @@ -18,14 +18,28 @@ metadata: service.beta.kubernetes.io/aws-load-balancer-target-group-attributes: preserve_client_ip.enabled=true,stickiness.enabled=true,stickiness.type=source_ip,load_balancing.cross_zone.enabled=true service.beta.kubernetes.io/aws-load-balancer-type: external service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags: "WebSocket=true" - {{- include "set-value" (dict "context" $externalService "path" "annotations") | nindent 2 }} + {{- include "set-value" (dict "context" $service "path" "annotations") | nindent 2 }} spec: type: LoadBalancer loadBalancerClass: service.k8s.aws/nlb externalTrafficPolicy: Local ports: - {{- toYaml $externalService.ports | nindent 4 }} + - name: http-acme + port: 80 + targetPort: 8089 + protocol: TCP + - appProtocol: tcp + name: nats + port: 4222 + protocol: TCP + targetPort: nats + - appProtocol: tcp + name: wss + port: 8443 + protocol: TCP + targetPort: websocket selector: {{- include "fuel-streams.selectorLabels" . | nindent 4 }} - app.kubernetes.io/service: external-service + app.kubernetes.io/service: external-ws {{- end }} + diff --git a/cluster/charts/fuel-streams/templates/publisher/network-configmap.yaml b/cluster/charts/fuel-streams/templates/publisher/network-configmap.yaml deleted file mode 100644 index 18a644ef..00000000 --- a/cluster/charts/fuel-streams/templates/publisher/network-configmap.yaml +++ /dev/null @@ -1,31 +0,0 @@ -{{- $publisher := .Values.publisher }} -apiVersion: v1 -kind: ConfigMap -metadata: - {{- include "k8s.metadata" (dict "context" . "suffix" "-network-config") | nindent 2 }} - annotations: - {{- include "set-value" (dict "context" $publisher "path" "config.annotations") | nindent 4 }} - labels: - {{- include "fuel-streams.labels" . | nindent 4 }} - {{- include "set-value" (dict "context" $publisher "path" "config.labels") | nindent 4 }} - app.kubernetes.io/component: publisher -data: - P2P_PORT: "30333" - DB_PATH: {{ .Values.publisher.storage.mountPath | quote }} - POA_INSTANT: "false" - SERVICE_NAME: "Publisher Node ({{ $publisher.network }})" - {{- if eq $publisher.network "mainnet" }} - RELAYER_V2_LISTENING_CONTRACTS: "0xAEB0c00D0125A8a788956ade4f4F12Ead9f65DDf" - RELAYER_DA_DEPLOY_HEIGHT: "20620434" - RELAYER_LOG_PAGE_SIZE: "2000" - SYNC_HEADER_BATCH_SIZE: "100" - RESERVED_NODES: "/dnsaddr/mainnet.fuel.network" - CHAIN_CONFIG: "mainnet" - {{- else if eq $publisher.network "testnet" }} - RELAYER_V2_LISTENING_CONTRACTS: "0x01855B78C1f8868DE70e84507ec735983bf262dA" - RELAYER_DA_DEPLOY_HEIGHT: "5827607" - RELAYER_LOG_PAGE_SIZE: "2000" - SYNC_HEADER_BATCH_SIZE: "100" - RESERVED_NODES: "/dns4/p2p-testnet.fuel.network/tcp/30333/p2p/16Uiu2HAmDxoChB7AheKNvCVpD4PHJwuDGn8rifMBEHmEynGHvHrf,/dns4/p2p-testnet.fuel.network/tcp/30333/p2p/16Uiu2HAmHnANNk4HjAxQV66BNCRxd2MBUU89ijboZkE69aLuSn1g,/dns4/p2p-testnet.fuel.network/tcp/30333/p2p/16Uiu2HAmVE468rpkh2X1kzz8qQXmqNFiPxU5Lrya28nZdbRUdVJX" - CHAIN_CONFIG: "testnet" - {{- end }} diff --git a/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml b/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml index 0ad2c022..5bdbec61 100644 --- a/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml +++ b/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml @@ -19,7 +19,7 @@ spec: matchLabels: {{- include "fuel-streams.selectorLabels" . | nindent 6 }} {{- include "set-value" (dict "context" $publisher "path" "config.selectorLabels") | nindent 6 }} - app.kubernetes.io/component: publisher + app.kubernetes.io/component: publisher template: metadata: @@ -45,7 +45,7 @@ spec: emptyDir: {} - name: var-dir emptyDir: {} - + initContainers: - name: update-{{ $publisher.storage.name }} image: alpine:latest @@ -81,6 +81,64 @@ spec: - name: publisher image: "{{ $publisher.image.repository }}:{{ $publisher.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ $publisher.image.pullPolicy }} + args: + # Common arguments + - "--enable-relayer" + - "--enable-p2p" + - "--keypair" + - "$(KEYPAIR)" + - "--relayer" + - "$(RELAYER)" + - "--ip" + - "0.0.0.0" + - "--port" + - "$(PORT)" + - "--db-path" + - "$(DB_PATH)" + - "--nats-url" + - "$(NATS_URL)" + - "--sync-header-batch-size" + - "100" + - "--relayer-log-page-size" + - "2000" + - "--sync-block-stream-buffer-size" + - "50" + - "--max-database-cache-size" + - "17179869184" + - "--state-rewind-duration" + - "136y" + - "--request-timeout" + - "60" + - "--graphql-max-complexity" + - "1000000000" + {{- if eq $publisher.network "mainnet" }} + # Mainnet specific args + - "--service-name" + - "Publisher Node (Mainnet)" + - "--snapshot" + - "./chain-config/mainnet" + - "--reserved-nodes" + - "/dnsaddr/mainnet.fuel.network" + - "--relayer-v2-listening-contracts" + - "0xAEB0c00D0125A8a788956ade4f4F12Ead9f65DDf" + - "--relayer-da-deploy-height" + - "20620434" + {{- else if eq $publisher.network "testnet" }} + # Testnet specific args + - "--service-name" + - "Publisher Node (Testnet)" + - "--snapshot" + - "./chain-config/testnet" + - "--reserved-nodes" + - "/dns4/p2p-testnet.fuel.network/tcp/30333/p2p/16Uiu2HAmDxoChB7AheKNvCVpD4PHJwuDGn8rifMBEHmEynGHvHrf,/dns4/p2p-testnet.fuel.network/tcp/30333/p2p/16Uiu2HAmHnANNk4HjAxQV66BNCRxd2MBUU89ijboZkE69aLuSn1g,/dns4/p2p-testnet.fuel.network/tcp/30333/p2p/16Uiu2HAmVE468rpkh2X1kzz8qQXmqNFiPxU5Lrya28nZdbRUdVJX" + - "--relayer-v2-listening-contracts" + - "0x01855B78C1f8868DE70e84507ec735983bf262dA" + - "--relayer-da-deploy-height" + - "5827607" + {{- end }} + {{- if $publisher.image.extraArgs }} + {{- toYaml $publisher.image.extraArgs | nindent 12 }} + {{- end }} ports: - name: http containerPort: {{ int $publisher.service.port }} @@ -96,6 +154,8 @@ spec: env: - name: TMPDIR value: "/var/fuel-streams/tmp" + - name: DB_PATH + value: {{ $publisher.storage.mountPath | default "/mnt/db" | quote }} {{- range $key, $value := $publisher.env }} - name: {{ $key }} value: {{ $value | quote }} @@ -105,8 +165,6 @@ spec: {{- end }} envFrom: - - configMapRef: - name: {{ include "fuel-streams.fullname" $ }}-network-config - configMapRef: name: {{ include "fuel-streams.fullname" $ }}-publisher optional: true diff --git a/cluster/charts/fuel-streams/templates/webserver/deployment.yaml b/cluster/charts/fuel-streams/templates/webserver/deployment.yaml index 759fc13a..b0bd4782 100644 --- a/cluster/charts/fuel-streams/templates/webserver/deployment.yaml +++ b/cluster/charts/fuel-streams/templates/webserver/deployment.yaml @@ -10,7 +10,7 @@ metadata: {{- include "fuel-streams.labels" . | nindent 4 }} {{- include "set-value" (dict "context" $webserver "path" "config.labels") | nindent 4 }} app.kubernetes.io/component: webserver - app.kubernetes.io/service: external-service + app.kubernetes.io/service: external-ws spec: {{- if not $webserver.autoscaling.enabled }} @@ -21,7 +21,7 @@ spec: {{- include "fuel-streams.selectorLabels" . | nindent 6 }} {{- include "set-value" (dict "context" $webserver "path" "config.selectorLabels") | nindent 6 }} app.kubernetes.io/component: webserver - app.kubernetes.io/service: external-service + app.kubernetes.io/service: external-ws template: metadata: @@ -31,7 +31,7 @@ spec: {{- include "fuel-streams.selectorLabels" . | nindent 8 }} {{- include "set-value" (dict "context" $webserver "path" "config.labels") | nindent 8 }} app.kubernetes.io/component: webserver - app.kubernetes.io/service: external-service + app.kubernetes.io/service: external-ws spec: {{- if .Values.serviceAccount.create }} @@ -69,4 +69,6 @@ spec: {{- with $webserver.extraEnv }} {{- toYaml . | nindent 12 }} {{- end }} + +{{- include "k8s.hpa" (dict "context" . "service" (dict "name" "webserver" "autoscaling" $webserver.autoscaling)) }} {{- end }} diff --git a/cluster/charts/fuel-streams/tests/consumer/deployment_test.yaml b/cluster/charts/fuel-streams/tests/consumer/deployment_test.yaml new file mode 100644 index 00000000..03334a73 --- /dev/null +++ b/cluster/charts/fuel-streams/tests/consumer/deployment_test.yaml @@ -0,0 +1,305 @@ +suite: Testing Consumer deployment +templates: + - templates/consumer/deployment.yaml +tests: + - it: should not create deployment when consumer is disabled + set: + consumer.enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: should create deployment with correct kind and metadata + set: + consumer.enabled: true + asserts: + - isKind: + of: Deployment + documentIndex: 0 + - isAPIVersion: + of: apps/v1 + documentIndex: 0 + - equal: + path: metadata.name + value: RELEASE-NAME-fuel-streams-consumer + - equal: + path: metadata.labels["app.kubernetes.io/component"] + value: consumer + - equal: + path: metadata.labels["app.kubernetes.io/service"] + value: external-service + documentIndex: 0 + + - it: should set correct selector labels + set: + consumer.enabled: true + asserts: + - equal: + path: spec.selector.matchLabels["app.kubernetes.io/component"] + value: consumer + documentIndex: 0 + - isSubset: + path: spec.selector.matchLabels + content: + app.kubernetes.io/name: fuel-streams + app.kubernetes.io/instance: RELEASE-NAME + documentIndex: 0 + + - it: should set image configuration correctly + set: + consumer.enabled: true + consumer.image.repository: ghcr.io/fuellabs/fuel-streams-webserver + consumer.image.tag: latest + consumer.image.pullPolicy: Always + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: ghcr.io/fuellabs/fuel-streams-webserver:latest + documentIndex: 0 + - equal: + path: spec.template.spec.containers[0].imagePullPolicy + value: Always + documentIndex: 0 + + - it: should use chart version when tag is not specified + set: + consumer.enabled: true + consumer.image.repository: ghcr.io/fuellabs/fuel-streams-webserver + consumer.image.tag: null + Chart: + Version: "1.0" + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: ghcr.io/fuellabs/fuel-streams-webserver:1.0 + documentIndex: 0 + + - it: should configure ports correctly + set: + consumer.enabled: true + consumer.port: 8082 + consumer.ports: + - name: metrics + containerPort: 9090 + protocol: TCP + asserts: + - lengthEqual: + path: spec.template.spec.containers[0].ports + count: 2 + documentIndex: 0 + - contains: + path: spec.template.spec.containers[0].ports + content: + name: consumer + containerPort: 8082 + protocol: TCP + documentIndex: 0 + - contains: + path: spec.template.spec.containers[0].ports + content: + name: metrics + containerPort: 9090 + protocol: TCP + documentIndex: 0 + + - it: should set replicas when autoscaling is disabled + set: + consumer.enabled: true + consumer.autoscaling.enabled: false + consumer.config.replicaCount: 3 + asserts: + - equal: + path: spec.replicas + value: 3 + documentIndex: 0 + + - it: should not set replicas when autoscaling is enabled + set: + consumer.enabled: true + consumer.autoscaling.enabled: true + consumer.config.replicaCount: 3 + asserts: + - isNull: + path: spec.replicas + documentIndex: 0 + + - it: should merge environment variables correctly + set: + consumer.enabled: true + consumer.env: + RUST_LOG: info + APP_PORT: "8080" + consumer.extraEnv: + - name: EXTRA_VAR + value: "extra-value" + - name: SECRET_VAR + valueFrom: + secretKeyRef: + name: my-secret + key: my-key + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: RUST_LOG + value: "info" + documentIndex: 0 + - contains: + path: spec.template.spec.containers[0].env + content: + name: APP_PORT + value: "8080" + documentIndex: 0 + - contains: + path: spec.template.spec.containers[0].env + content: + name: EXTRA_VAR + value: "extra-value" + documentIndex: 0 + - contains: + path: spec.template.spec.containers[0].env + content: + name: SECRET_VAR + valueFrom: + secretKeyRef: + name: my-secret + key: my-key + documentIndex: 0 + + - it: should set security context when specified + set: + consumer.enabled: true + consumer.config.securityContext: + runAsUser: 1000 + runAsGroup: 3000 + fsGroup: 2000 + asserts: + - equal: + path: spec.template.spec.securityContext.runAsUser + value: 1000 + documentIndex: 0 + - equal: + path: spec.template.spec.securityContext.runAsGroup + value: 3000 + documentIndex: 0 + - equal: + path: spec.template.spec.securityContext.fsGroup + value: 2000 + documentIndex: 0 + + - it: should set resource limits and requests + set: + consumer.enabled: true + consumer.config.resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 50m + memory: 64Mi + asserts: + - equal: + path: spec.template.spec.containers[0].resources.limits.cpu + value: 100m + documentIndex: 0 + - equal: + path: spec.template.spec.containers[0].resources.limits.memory + value: 128Mi + documentIndex: 0 + - equal: + path: spec.template.spec.containers[0].resources.requests.cpu + value: 50m + documentIndex: 0 + - equal: + path: spec.template.spec.containers[0].resources.requests.memory + value: 64Mi + documentIndex: 0 + + - it: should create HPA with correct configuration when autoscaling is enabled + set: + consumer.enabled: true + consumer.autoscaling.enabled: true + consumer.autoscaling.minReplicas: 2 + consumer.autoscaling.maxReplicas: 5 + consumer.autoscaling.targetCPUUtilizationPercentage: 75 + consumer.autoscaling.targetMemoryUtilizationPercentage: 85 + asserts: + - hasDocuments: + count: 2 + - isKind: + of: HorizontalPodAutoscaler + documentIndex: 1 + - equal: + path: spec.minReplicas + value: 2 + documentIndex: 1 + - equal: + path: spec.maxReplicas + value: 5 + documentIndex: 1 + - equal: + path: spec.metrics[0].resource.target.averageUtilization + value: 75 + documentIndex: 1 + - equal: + path: spec.metrics[1].resource.target.averageUtilization + value: 85 + documentIndex: 1 + + - it: should configure HPA scaling behavior correctly + set: + consumer.enabled: true + consumer.autoscaling.enabled: true + consumer.autoscaling.behavior.scaleDown.stabilizationWindowSeconds: 400 + consumer.autoscaling.behavior.scaleDown.percentValue: 50 + consumer.autoscaling.behavior.scaleUp.stabilizationWindowSeconds: 60 + consumer.autoscaling.behavior.scaleUp.percentValue: 200 + consumer.autoscaling.behavior.scaleUp.podValue: 6 + asserts: + - equal: + path: spec.behavior.scaleDown.stabilizationWindowSeconds + value: 400 + documentIndex: 1 + - equal: + path: spec.behavior.scaleDown.policies[0].type + value: Percent + documentIndex: 1 + - equal: + path: spec.behavior.scaleDown.policies[0].value + value: 50 + documentIndex: 1 + - equal: + path: spec.behavior.scaleUp.stabilizationWindowSeconds + value: 60 + documentIndex: 1 + - equal: + path: spec.behavior.scaleUp.policies[0].type + value: Percent + documentIndex: 1 + - equal: + path: spec.behavior.scaleUp.policies[0].value + value: 200 + documentIndex: 1 + - equal: + path: spec.behavior.scaleUp.policies[1].type + value: Pods + documentIndex: 1 + - equal: + path: spec.behavior.scaleUp.policies[1].value + value: 6 + documentIndex: 1 + - equal: + path: spec.behavior.scaleUp.selectPolicy + value: Max + documentIndex: 1 + + - it: should not create HPA when autoscaling is disabled + set: + consumer.enabled: true + consumer.autoscaling.enabled: false + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Deployment + documentIndex: 0 diff --git a/cluster/charts/fuel-streams/tests/external_service_test.yaml b/cluster/charts/fuel-streams/tests/external_service_test.yaml index 11a70a5e..611cb452 100644 --- a/cluster/charts/fuel-streams/tests/external_service_test.yaml +++ b/cluster/charts/fuel-streams/tests/external_service_test.yaml @@ -73,7 +73,7 @@ tests: path: spec.selector content: app.kubernetes.io/name: fuel-streams - app.kubernetes.io/service: external-service + app.kubernetes.io/service: external-ws - it: should set correct annotations set: diff --git a/cluster/charts/fuel-streams/tests/publisher/network-configmap.yaml b/cluster/charts/fuel-streams/tests/publisher/network-configmap.yaml deleted file mode 100644 index dfb5a7b3..00000000 --- a/cluster/charts/fuel-streams/tests/publisher/network-configmap.yaml +++ /dev/null @@ -1,87 +0,0 @@ -suite: Testing Publisher network configmap -templates: - - templates/publisher/network-configmap.yaml -tests: - - it: should configure mainnet correctly - set: - publisher.enabled: true - publisher.network: mainnet - publisher.storage.mountPath: /mnt/db - asserts: - - isKind: - of: ConfigMap - - equal: - path: metadata.name - value: RELEASE-NAME-fuel-streams-network-config - - equal: - path: data.P2P_PORT - value: "30333" - - equal: - path: data.DB_PATH - value: /mnt/db - - equal: - path: data.POA_INSTANT - value: "false" - - equal: - path: data.SERVICE_NAME - value: "Publisher Node (mainnet)" - - equal: - path: data.RELAYER_V2_LISTENING_CONTRACTS - value: "0xAEB0c00D0125A8a788956ade4f4F12Ead9f65DDf" - - equal: - path: data.RELAYER_DA_DEPLOY_HEIGHT - value: "20620434" - - equal: - path: data.RELAYER_LOG_PAGE_SIZE - value: "2000" - - equal: - path: data.SYNC_HEADER_BATCH_SIZE - value: "100" - - equal: - path: data.RESERVED_NODES - value: "/dnsaddr/mainnet.fuel.network" - - equal: - path: data.CHAIN_CONFIG - value: "mainnet" - - - it: should configure testnet correctly - set: - publisher.enabled: true - publisher.network: testnet - publisher.storage.mountPath: /mnt/db - asserts: - - isKind: - of: ConfigMap - - equal: - path: metadata.name - value: RELEASE-NAME-fuel-streams-network-config - - equal: - path: data.P2P_PORT - value: "30333" - - equal: - path: data.DB_PATH - value: /mnt/db - - equal: - path: data.POA_INSTANT - value: "false" - - equal: - path: data.SERVICE_NAME - value: "Publisher Node (testnet)" - - equal: - path: data.RELAYER_V2_LISTENING_CONTRACTS - value: "0x01855B78C1f8868DE70e84507ec735983bf262dA" - - equal: - path: data.RELAYER_DA_DEPLOY_HEIGHT - value: "5827607" - - equal: - path: data.RELAYER_LOG_PAGE_SIZE - value: "2000" - - equal: - path: data.SYNC_HEADER_BATCH_SIZE - value: "100" - - equal: - path: data.RESERVED_NODES - value: "/dns4/p2p-testnet.fuel.network/tcp/30333/p2p/16Uiu2HAmDxoChB7AheKNvCVpD4PHJwuDGn8rifMBEHmEynGHvHrf,/dns4/p2p-testnet.fuel.network/tcp/30333/p2p/16Uiu2HAmHnANNk4HjAxQV66BNCRxd2MBUU89ijboZkE69aLuSn1g,/dns4/p2p-testnet.fuel.network/tcp/30333/p2p/16Uiu2HAmVE468rpkh2X1kzz8qQXmqNFiPxU5Lrya28nZdbRUdVJX" - - equal: - path: data.CHAIN_CONFIG - value: "testnet" diff --git a/cluster/charts/fuel-streams/values.yaml b/cluster/charts/fuel-streams/values.yaml index e00d00d1..4c1a1aac 100755 --- a/cluster/charts/fuel-streams/values.yaml +++ b/cluster/charts/fuel-streams/values.yaml @@ -72,29 +72,6 @@ startupProbe: failureThreshold: 6 successThreshold: 1 -tls: - enabled: false - issuer: "letsencrypt-prod" - duration: "2160h" - renewBefore: "360h" - annotations: {} - labels: {} - -externalService: - enabled: false - dns: "streams.svc.cluster.local" - labels: {} - annotations: {} - ports: - - name: websocket - port: 8443 - targetPort: websocket - protocol: TCP - - name: webserver - port: 8082 - targetPort: http - protocol: TCP - # ------------------------------------------------------------------------------------------------- # Monitoring # ------------------------------------------------------------------------------------------------- @@ -111,9 +88,10 @@ publisher: network: mainnet image: - repository: fuel-streams-publisher + repository: sv-emitter pullPolicy: Never tag: "latest" + extraArgs: [] service: type: ClusterIP @@ -126,7 +104,7 @@ publisher: storage: name: rocks-db - size: 10Gi + size: 1Gi storageClass: standard accessMode: ReadWriteOnce mountPath: /mnt/db @@ -154,11 +132,21 @@ publisher: maxReplicas: 3 targetCPUUtilizationPercentage: 80 targetMemoryUtilizationPercentage: 80 + behavior: + scaleDown: + stabilizationWindowSeconds: 300 + percentValue: 100 + periodSeconds: 15 + scaleUp: + stabilizationWindowSeconds: 0 + percentValue: 100 + podValue: 4 + periodSeconds: 15 env: + PORT: 8080 PUBLISHER_MAX_THREADS: "32" NATS_URL: "fuel-streams-nats-publisher:4222" - HISTORICAL: "true" # Additional environment variables with complex structures # extraEnv: [] @@ -185,17 +173,26 @@ publisher: # name: additional-secrets # ------------------------------------------------------------------------------------------------- -# WebServer configuration +# Consumer configuration # ------------------------------------------------------------------------------------------------- -webserver: - enabled: false - port: 8082 - +consumer: + enabled: true + port: 8081 image: - repository: fuel-streams-webserver + repository: sv-consumer pullPolicy: Never - tag: "latest" + tag: latest + args: + - --nats-core-url + - $(NATS_CORE_URL) + - --nats-publisher-url + - $(NATS_PUBLISHER_URL) + + env: + PORT: 8081 + NATS_CORE_URL: "fuel-streams-nats-core:4222" + NATS_PUBLISHER_URL: "fuel-streams-nats-publisher:4222" config: replicaCount: 1 @@ -212,20 +209,24 @@ webserver: startupProbe: {} securityContext: {} containerSecurityContext: {} - resources: - requests: - cpu: 100m - memory: 128Mi - limits: - cpu: 500m - memory: 512Mi + resources: {} autoscaling: - enabled: false + enabled: true minReplicas: 1 maxReplicas: 3 targetCPUUtilizationPercentage: 80 targetMemoryUtilizationPercentage: 80 + behavior: + scaleDown: + stabilizationWindowSeconds: 300 + percentValue: 100 + periodSeconds: 15 + scaleUp: + stabilizationWindowSeconds: 0 + percentValue: 100 + podValue: 4 + periodSeconds: 15 # ------------------------------------------------------------------------------------------------- # NATS Core configuration @@ -233,10 +234,8 @@ webserver: nats-core: enabled: true - natsBox: enabled: false - promExporter: enabled: false port: 6777 @@ -254,15 +253,16 @@ nats-core: repository: nats tag: 2.10.22-alpine env: - GOMEMLIMIT: 8GiB - startupProbe: - initialDelaySeconds: 60 - periodSeconds: 10 - failureThreshold: 1080 - resources: - requests: - cpu: 8 - memory: 8Gi + GOMEMLIMIT: 2GiB + merge: + # startupProbe: + # initialDelaySeconds: 60 + # periodSeconds: 10 + # failureThreshold: 1080 + resources: + requests: + cpu: 8 + memory: 2Gi service: enabled: true @@ -271,8 +271,12 @@ nats-core: enabled: true cluster: enabled: true + websocket: + enabled: true leafnodes: enabled: true + mqtt: + enabled: false monitor: enabled: false @@ -283,6 +287,22 @@ nats-core: replicas: 3 routeURLs: useFQDN: true + + websocket: + enabled: true + port: 8443 + tls: + enabled: false + # secretName: fuel-streams-nats-tls + # dir: /etc/nats-certs/websocket + # cert: tls.crt + # key: tls.key + merge: + no_tls: true + # same_origin: false + # compression: false + # handshake_timeout: "20s" + # no_auth_user: default_user jetstream: enabled: true @@ -290,7 +310,7 @@ nats-core: dir: /data pvc: enabled: true - size: 500Gi + size: 20Gi storageClassName: standard leafnodes: @@ -303,25 +323,36 @@ nats-core: merge: jetstream: - max_file_store: << 500GiB >> - max_memory_store: << 7168MiB >> - domain: "central" + domain: CORE + max_file_store: << 20GiB >> + max_memory_store: << 1792MiB >> max_payload: << 8MiB >> + system_account: SYS + accounts: + SYS: + users: + - user: sys + password: sys + ADMIN: + jetstream: enabled + users: + - user: admin + password: admin + PUBLIC: + jetstream: enabled + users: + - user: default_user + password: "" # ------------------------------------------------------------------------------------------------- -# NATS Client configuration +# NATS Publisher configuration # ------------------------------------------------------------------------------------------------- -nats-client: +nats-publisher: enabled: true - global: - labels: - app.kubernetes.io/service: external-service - natsBox: enabled: false - promExporter: enabled: false @@ -330,15 +361,16 @@ nats-client: repository: nats tag: 2.10.22-alpine env: - GOMEMLIMIT: 2GiB - startupProbe: - initialDelaySeconds: 60 - periodSeconds: 10 - failureThreshold: 1080 - resources: - requests: - cpu: 2 - memory: 2Gi + GOMEMLIMIT: 1GiB + merge: + # startupProbe: + # initialDelaySeconds: 60 + # periodSeconds: 10 + # failureThreshold: 1080 + resources: + requests: + cpu: 4 + memory: 1Gi service: enabled: true @@ -346,14 +378,18 @@ nats-client: nats: enabled: true websocket: + enabled: false + leafnodes: enabled: true monitor: enabled: false + mqtt: + enabled: false statefulSet: merge: spec: - replicas: 2 + replicas: 3 podTemplate: topologySpreadConstraints: @@ -362,29 +398,30 @@ nats-client: whenUnsatisfiable: DoNotSchedule config: + cluster: + enabled: false + + websocket: + enabled: false + jetstream: enabled: true fileStore: dir: /data pvc: enabled: true - size: 20Gi + size: 5Gi storageClassName: standard - merge: - domain: "client" leafnodes: enabled: true port: 7422 - remotes: - - url: "nats://nats-core:7422" - - websocket: - enabled: true - port: 8443 merge: - no_tls: true - no_auth_user: default_user + remotes: + - urls: ["nats://sys:sys@fuel-streams-nats-core:7422"] + account: SYS + - urls: ["nats://admin:admin@fuel-streams-nats-core:7422"] + account: ADMIN monitor: enabled: false @@ -392,44 +429,39 @@ nats-client: merge: jetstream: - max_file_store: << 20GiB >> - max_memory_store: << 2048MiB >> + domain: PUBLISHER + max_file_store: << 5GiB >> + max_memory_store: << 768MiB >> max_payload: << 8MiB >> + system_account: SYS accounts: - USERS: + SYS: + users: + - user: sys + password: sys + ADMIN: + jetstream: enabled + users: + - user: admin + password: admin + PUBLIC: jetstream: enabled users: - user: default_user - permissions: - subscribe: ">" - publish: - deny: - - "*.by_id.>" - - "*.blocks.>" - - "*.transactions.>" - - "*.inputs.>" - - "*.outputs.>" - - "*.receipts.>" - - "*.logs.>" - - "*.utxos.>" - - "$JS.API.STREAM.CREATE.>" - - "$JS.API.STREAM.UPDATE.>" - - "$JS.API.STREAM.DELETE.>" - - "$JS.API.STREAM.PURGE.>" - - "$JS.API.STREAM.RESTORE.>" - - "$JS.API.STREAM.MSG.DELETE.>" - - "$JS.API.CONSUMER.DURABLE.CREATE.>" + password: "" # ------------------------------------------------------------------------------------------------- -# NATS Publisher configuration +# NATS Client configuration # ------------------------------------------------------------------------------------------------- -nats-publisher: +nats-client: enabled: true + global: + labels: + app.kubernetes.io/service: external-ws natsBox: enabled: false - promExporter: enabled: false @@ -438,28 +470,31 @@ nats-publisher: repository: nats tag: 2.10.22-alpine env: - GOMEMLIMIT: 3GiB - startupProbe: - initialDelaySeconds: 60 - periodSeconds: 10 - failureThreshold: 1080 - resources: - requests: - cpu: 4 - memory: 4Gi + GOMEMLIMIT: 512MiB + merge: + resources: + requests: + cpu: 2 + memory: 512Mi service: enabled: true ports: nats: enabled: true + websocket: + enabled: true + leafnodes: + enabled: true monitor: enabled: false + mqtt: + enabled: false statefulSet: merge: spec: - replicas: 3 + replicas: 2 podTemplate: topologySpreadConstraints: @@ -468,22 +503,41 @@ nats-publisher: whenUnsatisfiable: DoNotSchedule config: + cluster: + enabled: false + jetstream: enabled: true fileStore: dir: /data pvc: enabled: true - size: 50Gi + size: 2Gi storageClassName: standard - merge: - domain: "publisher" leafnodes: enabled: true port: 7422 - remotes: - - url: "nats://nats-core:7422" + merge: + remotes: + - urls: ["ws://admin:admin@fuel-streams-nats-core:8443"] + account: ADMIN + + websocket: + enabled: true + port: 8443 + tls: + enabled: false + # secretName: fuel-streams-nats-tls + # dir: /etc/nats-certs/websocket + # cert: tls.crt + # key: tls.key + merge: + no_tls: true + # same_origin: false + # compression: false + # handshake_timeout: "20s" + # no_auth_user: default_user monitor: enabled: false @@ -491,6 +545,122 @@ nats-publisher: merge: jetstream: - max_file_store: << 50GiB >> - max_memory_store: << 3072MiB >> + domain: CLIENT + max_file_store: << 2GiB >> + max_memory_store: << 384MiB >> max_payload: << 8MiB >> + system_account: SYS + accounts: + SYS: + users: + - user: sys + password: sys + ADMIN: + jetstream: enabled + users: + - user: admin + password: admin + PUBLIC: + jetstream: enabled + users: + - user: default_user + password: "" + + # TODO: Add users and permissions later + # accounts: + # USERS: + # jetstream: enabled + # users: + # - user: default_user + # permissions: + # subscribe: ">" + # publish: + # deny: + # - "*.by_id.>" + # - "*.blocks.>" + # - "*.transactions.>" + # - "*.inputs.>" + # - "*.outputs.>" + # - "*.receipts.>" + # - "*.logs.>" + # - "*.utxos.>" + # - "$JS.API.STREAM.CREATE.>" + # - "$JS.API.STREAM.UPDATE.>" + # - "$JS.API.STREAM.DELETE.>" + # - "$JS.API.STREAM.PURGE.>" + # - "$JS.API.STREAM.RESTORE.>" + # - "$JS.API.STREAM.MSG.DELETE.>" + # - "$JS.API.CONSUMER.DURABLE.CREATE.>" + +# ------------------------------------------------------------------------------------------------- +# NATS External Service configuration (WebSocket) +# ------------------------------------------------------------------------------------------------- + +natsExternalService: + enabled: true + certificate: + issuer: "letsencrypt-prod" + duration: "2160h" + renewBefore: "360h" + annotations: {} + labels: {} + service: + dns: "stream-dev.fuel.network" + labels: {} + annotations: {} + +# ------------------------------------------------------------------------------------------------- +# WebServer configuration +# ------------------------------------------------------------------------------------------------- + +webserver: + enabled: false + port: 8443 + + image: + repository: fuel-streams-webserver + pullPolicy: Never + tag: "latest" + + config: + replicaCount: 1 + labels: {} + annotations: {} + podAnnotations: {} + nodeSelector: {} + tolerations: [] + affinity: {} + imagePullSecrets: [] + ports: [] + livenessProbe: {} + readinessProbe: {} + startupProbe: {} + securityContext: {} + containerSecurityContext: {} + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 500m + memory: 256Mi + + autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + targetMemoryUtilizationPercentage: 80 + behavior: + scaleDown: + stabilizationWindowSeconds: 300 + percentValue: 100 + periodSeconds: 15 + scaleUp: + stabilizationWindowSeconds: 0 + percentValue: 100 + podValue: 4 + periodSeconds: 15 + + env: + PORT: 8443 diff --git a/cluster/docker/fuel-core.Dockerfile b/cluster/docker/fuel-core.Dockerfile new file mode 100644 index 00000000..0ec3f52b --- /dev/null +++ b/cluster/docker/fuel-core.Dockerfile @@ -0,0 +1,84 @@ +# Stage 1: Build +FROM --platform=$BUILDPLATFORM tonistiigi/xx AS xx +FROM --platform=$BUILDPLATFORM rust:1.81.0 AS chef + +# Add package name as build argument +ARG PACKAGE_NAME +ARG TARGETPLATFORM + +RUN cargo install cargo-chef && rustup target add wasm32-unknown-unknown +WORKDIR /build/ + +COPY --from=xx / / + +# hadolint ignore=DL3008 +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + lld \ + clang \ + libclang-dev \ + && xx-apt-get update \ + && xx-apt-get install -y libc6-dev g++ binutils \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + + +FROM chef AS planner +ENV CARGO_NET_GIT_FETCH_WITH_CLI=true +COPY . . +RUN cargo chef prepare --recipe-path recipe.json + + +FROM chef AS builder +ARG PACKAGE_NAME +ARG DEBUG_SYMBOLS=false +ENV CARGO_NET_GIT_FETCH_WITH_CLI=true +ENV CARGO_PROFILE_RELEASE_DEBUG=$DEBUG_SYMBOLS +COPY --from=planner /build/recipe.json recipe.json +RUN echo $CARGO_PROFILE_RELEASE_DEBUG +# Build our project dependencies, not our application! +RUN \ + --mount=type=cache,target=/usr/local/cargo/registry/index \ + --mount=type=cache,target=/usr/local/cargo/registry/cache \ + --mount=type=cache,target=/usr/local/cargo/git/db \ + --mount=type=cache,target=/build/target \ + xx-cargo chef cook --release --no-default-features -p ${PACKAGE_NAME} --recipe-path recipe.json +# Up to this point, if our dependency tree stays the same, +# all layers should be cached. +COPY . . +# build application +RUN \ + --mount=type=cache,target=/usr/local/cargo/registry/index \ + --mount=type=cache,target=/usr/local/cargo/registry/cache \ + --mount=type=cache,target=/usr/local/cargo/git/db \ + --mount=type=cache,target=/build/target \ + xx-cargo build --release --no-default-features -p ${PACKAGE_NAME} \ + && xx-verify ./target/$(xx-cargo --print-target-triple)/release/${PACKAGE_NAME} \ + && cp ./target/$(xx-cargo --print-target-triple)/release/${PACKAGE_NAME} /root/${PACKAGE_NAME} \ + && cp ./target/$(xx-cargo --print-target-triple)/release/${PACKAGE_NAME}.d /root/${PACKAGE_NAME}.d + +# Stage 2: Run +FROM ubuntu:22.04 AS run + +ARG PACKAGE_NAME +ARG PORT=4000 +ARG P2P_PORT=30333 +ENV IP="${IP}" +ENV PORT="${PORT}" + +WORKDIR /usr/src + +RUN apt-get update -y \ + && apt-get install -y --no-install-recommends ca-certificates curl \ + && apt-get autoremove -y \ + && apt-get clean -y \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=builder /root/${PACKAGE_NAME} . +COPY --from=builder /root/${PACKAGE_NAME}.d . + +COPY /cluster/chain-config ./chain-config +EXPOSE ${PORT} +EXPOSE ${P2P_PORT} + +ENTRYPOINT ["./${PACKAGE_NAME}"] diff --git a/cluster/docker/fuel-streams-publisher.Dockerfile b/cluster/docker/fuel-streams-publisher.Dockerfile deleted file mode 100644 index a93014e2..00000000 --- a/cluster/docker/fuel-streams-publisher.Dockerfile +++ /dev/null @@ -1,131 +0,0 @@ -# Stage 1: Build -FROM --platform=$BUILDPLATFORM tonistiigi/xx AS xx -FROM --platform=$BUILDPLATFORM rust:1.81.0 AS chef - -ARG TARGETPLATFORM -RUN cargo install cargo-chef && rustup target add wasm32-unknown-unknown -WORKDIR /build/ - -COPY --from=xx / / - -# hadolint ignore=DL3008 -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - lld \ - clang \ - libclang-dev \ - && xx-apt-get update \ - && xx-apt-get install -y libc6-dev g++ binutils \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - - -FROM chef AS planner -ENV CARGO_NET_GIT_FETCH_WITH_CLI=true -COPY . . -RUN cargo chef prepare --recipe-path recipe.json - - -FROM chef AS builder -ARG DEBUG_SYMBOLS=false -ENV CARGO_NET_GIT_FETCH_WITH_CLI=true -ENV CARGO_PROFILE_RELEASE_DEBUG=$DEBUG_SYMBOLS -COPY --from=planner /build/recipe.json recipe.json -RUN echo $CARGO_PROFILE_RELEASE_DEBUG -# Build our project dependencies, not our application! -RUN \ - --mount=type=cache,target=/usr/local/cargo/registry/index \ - --mount=type=cache,target=/usr/local/cargo/registry/cache \ - --mount=type=cache,target=/usr/local/cargo/git/db \ - --mount=type=cache,target=/build/target \ - xx-cargo chef cook --release --no-default-features -p fuel-streams-publisher --recipe-path recipe.json -# Up to this point, if our dependency tree stays the same, -# all layers should be cached. -COPY . . -# build application -RUN \ - --mount=type=cache,target=/usr/local/cargo/registry/index \ - --mount=type=cache,target=/usr/local/cargo/registry/cache \ - --mount=type=cache,target=/usr/local/cargo/git/db \ - --mount=type=cache,target=/build/target \ - xx-cargo build --release --no-default-features -p fuel-streams-publisher \ - && xx-verify ./target/$(xx-cargo --print-target-triple)/release/fuel-streams-publisher \ - && cp ./target/$(xx-cargo --print-target-triple)/release/fuel-streams-publisher /root/fuel-streams-publisher \ - && cp ./target/$(xx-cargo --print-target-triple)/release/fuel-streams-publisher.d /root/fuel-streams-publisher.d - -# Stage 2: Run -FROM ubuntu:22.04 AS run - -ARG IP=0.0.0.0 -ARG PORT=4000 -ARG TELEMETRY_PORT=8080 -ARG P2P_PORT=30333 -ARG DB_PATH=/mnt/db/ -ARG POA_INSTANT=false -ARG RELAYER_LOG_PAGE_SIZE=2000 -ARG SERVICE_NAME="NATS Publisher Node" -ARG SYNC_HEADER_BATCH_SIZE=100 -ARG RESERVED_NODES=/dns4/p2p-testnet.fuel.network/tcp/30333/p2p/16Uiu2HAmDxoChB7AheKNvCVpD4PHJwuDGn8rifMBEHmEynGHvHrf - -ENV IP=$IP -ENV PORT=$PORT -ENV TELEMETRY_PORT=$TELEMETRY_PORT -ENV DB_PATH=$DB_PATH -ENV POA_INSTANT=false -ENV RELAYER_LOG_PAGE_SIZE=$RELAYER_LOG_PAGE_SIZE -ENV SERVICE_NAME=$SERVICE_NAME -ENV SYNC_HEADER_BATCH_SIZE=$SYNC_HEADER_BATCH_SIZE -ENV RESERVED_NODES=$RESERVED_NODES -ENV HISTORICAL=false - -ENV KEYPAIR= -ENV RELAYER= -ENV RELAYER_V2_LISTENING_CONTRACTS= -ENV RELAYER_DA_DEPLOY_HEIGHT= -ENV CHAIN_CONFIG= -ENV NATS_URL= -ENV USE_PUBLISHER_METRICS= -ENV USE_ELASTIC_LOGGING= - -WORKDIR /usr/src - -RUN apt-get update -y \ - && apt-get install -y --no-install-recommends ca-certificates curl \ - # Clean up - && apt-get autoremove -y \ - && apt-get clean -y \ - && rm -rf /var/lib/apt/lists/* - -COPY --from=builder /root/fuel-streams-publisher . -COPY --from=builder /root/fuel-streams-publisher.d . - -COPY /cluster/chain-config ./chain-config -EXPOSE ${PORT} -EXPOSE ${P2P_PORT} -EXPOSE ${TELEMETRY_PORT} - -# https://stackoverflow.com/a/44671685 -# https://stackoverflow.com/a/40454758 -# hadolint ignore=DL3025 -CMD exec ./fuel-streams-publisher \ - --service-name "${SERVICE_NAME}" \ - --nats-url $NATS_URL \ - --keypair $KEYPAIR \ - --relayer $RELAYER \ - --ip $IP \ - --port $PORT \ - --telemetry-port $TELEMETRY_PORT \ - --peering-port $P2P_PORT \ - --db-path "${DB_PATH}" \ - --utxo-validation \ - --poa-instant $POA_INSTANT \ - --snapshot ./chain-config/${CHAIN_CONFIG} \ - --enable-p2p \ - --reserved-nodes $RESERVED_NODES \ - --sync-header-batch-size $SYNC_HEADER_BATCH_SIZE \ - --enable-relayer \ - --relayer-v2-listening-contracts $RELAYER_V2_LISTENING_CONTRACTS \ - --relayer-da-deploy-height $RELAYER_DA_DEPLOY_HEIGHT \ - --relayer-log-page-size $RELAYER_LOG_PAGE_SIZE \ - --sync-block-stream-buffer-size 30 \ - $([ "$HISTORICAL" = "true" ] && echo "--historical") diff --git a/cluster/docker/nats.conf b/cluster/docker/nats.conf index 783a0450..cf5af290 100644 --- a/cluster/docker/nats.conf +++ b/cluster/docker/nats.conf @@ -1,52 +1,46 @@ +# Core settings port = 4222 http_port = 8222 -server_name = "fuel-nats-server" -authorization = { - timeout = 5 - ADMIN = { - publish = ">" - subscribe = ">" - } - default_permissions = { - subscribe = ">" - publish = { - deny = [ - "*.blocks.>", - "*.transactions.>", - "*.inputs.>", - "*.outputs.>", - "*.receipts.>", - "*.logs.>", - "*.utxos.>", - "$JS.API.STREAM.CREATE.>", - "$JS.API.STREAM.UPDATE.>", - "$JS.API.STREAM.DELETE.>", - "$JS.API.STREAM.PURGE.>", - "$JS.API.STREAM.RESTORE.>", - "$JS.API.STREAM.MSG.DELETE.>", - "$JS.API.CONSUMER.DURABLE.CREATE.>", - ] - } - } - users = [ - { user = admin, password = $NATS_ADMIN_PASS, permissions = $ADMIN }, - { user = default_user } - ] +# Jetstream settings +jetstream { + max_file_store = 536870912000 # 500GB + max_memory_store = 7516192768 # ~7.1GB } -jetstream = { - max_file_store = 21474836480 -} +# Max payload setting +max_payload = 8388608 # 8MB -max_payload = 8388608 - -websocket = { - port = 8443 - no_tls = true - same_origin = false - allowed_origins = [] - compression = false - handshake_timeout = "10s" - no_auth_user = default_user +# Authorization settings +authorization { + timeout = 5 + ADMIN = { + publish = ">" + subscribe = ">" + } + default_permissions = { + subscribe = ">" + publish = { + deny = [ + "*.blocks.>", + "*.transactions.>", + "*.inputs.>", + "*.outputs.>", + "*.receipts.>", + "*.logs.>", + "*.utxos.>", + "$JS.API.STREAM.CREATE.>", + "$JS.API.STREAM.UPDATE.>", + "$JS.API.STREAM.DELETE.>", + "$JS.API.STREAM.PURGE.>", + "$JS.API.STREAM.RESTORE.>", + "$JS.API.STREAM.MSG.DELETE.>", + "$JS.API.CONSUMER.DURABLE.CREATE.>" + ] + } + } + users = [ + { user = admin, password = $NATS_ADMIN_PASS, permissions = $ADMIN } + { user = default_user } + ] } diff --git a/cluster/docker/sv-consumer.Dockerfile b/cluster/docker/sv-consumer.Dockerfile new file mode 100644 index 00000000..533e8459 --- /dev/null +++ b/cluster/docker/sv-consumer.Dockerfile @@ -0,0 +1,75 @@ +# Stage 1: Build +FROM --platform=$BUILDPLATFORM tonistiigi/xx AS xx +FROM --platform=$BUILDPLATFORM rust:1.81.0 AS chef + +ARG TARGETPLATFORM +RUN cargo install cargo-chef && rustup target add wasm32-unknown-unknown +WORKDIR /build/ + +COPY --from=xx / / + +# hadolint ignore=DL3008 +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + lld \ + clang \ + libclang-dev \ + && xx-apt-get update \ + && xx-apt-get install -y libc6-dev g++ binutils \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + + +FROM chef AS planner +ENV CARGO_NET_GIT_FETCH_WITH_CLI=true +COPY . . +RUN cargo chef prepare --recipe-path recipe.json + + +FROM chef AS builder +ARG DEBUG_SYMBOLS=false +ENV CARGO_NET_GIT_FETCH_WITH_CLI=true +ENV CARGO_PROFILE_RELEASE_DEBUG=$DEBUG_SYMBOLS +COPY --from=planner /build/recipe.json recipe.json +RUN echo $CARGO_PROFILE_RELEASE_DEBUG +# Build our project dependencies, not our application! +RUN \ + --mount=type=cache,target=/usr/local/cargo/registry/index \ + --mount=type=cache,target=/usr/local/cargo/registry/cache \ + --mount=type=cache,target=/usr/local/cargo/git/db \ + --mount=type=cache,target=/build/target \ + xx-cargo chef cook --release --no-default-features -p sv-consumer --recipe-path recipe.json +# Up to this point, if our dependency tree stays the same, +# all layers should be cached. +COPY . . +# build application +RUN \ + --mount=type=cache,target=/usr/local/cargo/registry/index \ + --mount=type=cache,target=/usr/local/cargo/registry/cache \ + --mount=type=cache,target=/usr/local/cargo/git/db \ + --mount=type=cache,target=/build/target \ + xx-cargo build --release --no-default-features -p sv-consumer \ + && xx-verify ./target/$(xx-cargo --print-target-triple)/release/sv-consumer \ + && cp ./target/$(xx-cargo --print-target-triple)/release/sv-consumer /root/sv-consumer \ + && cp ./target/$(xx-cargo --print-target-triple)/release/sv-consumer.d /root/sv-consumer.d + +# Stage 2: Run +FROM ubuntu:22.04 AS run + +ARG PORT=8080 +ENV PORT=$PORT +WORKDIR /usr/src + +RUN apt-get update -y \ + && apt-get install -y --no-install-recommends ca-certificates curl \ + # Clean up + && apt-get autoremove -y \ + && apt-get clean -y \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=builder /root/sv-consumer . +COPY --from=builder /root/sv-consumer.d . + +EXPOSE ${PORT} + +ENTRYPOINT ["./sv-consumer"] diff --git a/cluster/scripts/build_docker.sh b/cluster/scripts/build_docker.sh new file mode 100755 index 00000000..ef274b27 --- /dev/null +++ b/cluster/scripts/build_docker.sh @@ -0,0 +1,84 @@ +#!/usr/bin/env bash + +# Remove the -g flag from set +set -euo pipefail + +# Help/Usage function +usage() { + cat << EOF +Usage: $(basename "$0") [OPTIONS] + +Build a Docker image using specified parameters. + +Options: + --image-name Name for the Docker image (default: fuel-streams-publisher) + --dockerfile Path to Dockerfile (default: cluster/docker/fuel-core.Dockerfile) + --build-args Additional Docker build arguments (optional) + -h, --help Show this help message + +Environment variables: + TAG Docker image tag (default: latest) + DOCKER_HOST Docker daemon socket (optional) + +Examples: + $(basename "$0") --image-name my-image --dockerfile ./Dockerfile + $(basename "$0") --image-name my-image --dockerfile ./Dockerfile --build-args "--build-arg KEY=VALUE" +EOF + exit 1 +} + +# Show help if no arguments or help flag +if [[ $# -eq 0 ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then + usage +fi + +# Default values +IMAGE_NAME="fuel-streams-publisher" +DOCKERFILE="cluster/docker/fuel-core.Dockerfile" +BUILD_ARGS="" +TAG=${TAG:-"latest"} # From environment variable with default + +# Parse named arguments +while [[ $# -gt 0 ]]; do + case $1 in + --image-name) + IMAGE_NAME="$2" + shift 2 + ;; + --dockerfile) + DOCKERFILE="$2" + shift 2 + ;; + --build-args) + BUILD_ARGS="$2" + shift 2 + ;; + *) + echo "Error: Unknown argument '$1'" + usage + ;; + esac +done + +# Validate required files exist +if [[ ! -f "$DOCKERFILE" ]]; then + echo "Error: Dockerfile not found at $DOCKERFILE" + exit 1 +fi + +# Ensure we're using minikube's docker daemon +if [[ -n "${DOCKER_HOST:-}" ]]; then + echo "Using provided DOCKER_HOST: $DOCKER_HOST" +else + eval $(minikube docker-env) +fi + +echo "Building image ${IMAGE_NAME}:${TAG} using ${DOCKERFILE}" +echo "Build args: ${BUILD_ARGS}" + +# Build the docker image with build args if provided +if [[ -n "${BUILD_ARGS}" ]]; then + docker build ${BUILD_ARGS} -t "${IMAGE_NAME}:${TAG}" -f "${DOCKERFILE}" . +else + docker build -t "${IMAGE_NAME}:${TAG}" -f "${DOCKERFILE}" . +fi diff --git a/cluster/scripts/build_publisher.sh b/cluster/scripts/build_publisher.sh deleted file mode 100755 index 0fe43d4b..00000000 --- a/cluster/scripts/build_publisher.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# Use environment variables provided by Tilt if available -IMAGE_NAME=${EXPECTED_IMAGE:-"fuel-streams-publisher"} -TAG=${EXPECTED_TAG:-"latest"} -DOCKERFILE="cluster/docker/fuel-streams-publisher.Dockerfile" - -# Ensure we're using minikube's docker daemon if not already set -if [ -z "${DOCKER_HOST:-}" ]; then - eval $(minikube docker-env) -fi - -# Build the docker image -docker build -t ${IMAGE_NAME}:${TAG} -f ${DOCKERFILE} . diff --git a/cluster/scripts/gen_env_secret.sh b/cluster/scripts/gen_env_secret.sh index df0680d3..2d4a1e6c 100755 --- a/cluster/scripts/gen_env_secret.sh +++ b/cluster/scripts/gen_env_secret.sh @@ -4,7 +4,7 @@ source .env # Generate the YAML configuration -cat <cluster/charts/fuel-streams/values-publisher-secrets.yaml +cat << EOF > cluster/charts/fuel-streams/values-publisher-secrets.yaml publisher: extraEnv: - name: RELAYER diff --git a/cluster/scripts/setup_k8s.sh b/cluster/scripts/setup_k8s.sh index bb7537e8..791c8595 100755 --- a/cluster/scripts/setup_k8s.sh +++ b/cluster/scripts/setup_k8s.sh @@ -4,13 +4,13 @@ set -euo pipefail # Parse command line arguments -NAMESPACE="${1:-fuel-streams}" # Use first argument, default to "fuel-streams" if not provided +NAMESPACE="${1:-fuel-streams}" # Use first argument, default to "fuel-streams" if not provided # Configure namespace and context echo -e "\n\033[1;33mConfiguring ${NAMESPACE} namespace and context:\033[0m" # Check if namespace exists -if kubectl get namespace ${NAMESPACE} &>/dev/null; then +if kubectl get namespace ${NAMESPACE} &> /dev/null; then echo "Namespace ${NAMESPACE} already exists" else echo "Creating namespace ${NAMESPACE}..." diff --git a/cluster/scripts/setup_minikube.sh b/cluster/scripts/setup_minikube.sh index 0c01374a..55c63555 100755 --- a/cluster/scripts/setup_minikube.sh +++ b/cluster/scripts/setup_minikube.sh @@ -4,12 +4,12 @@ set -euo pipefail # Check if minikube is installed -if ! command -v minikube &>/dev/null; then +if ! command -v minikube &> /dev/null; then echo "Installing minikube..." - sudo curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && - sudo chmod +x minikube && - sudo cp minikube /usr/local/bin/ && - sudo rm minikube + sudo curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 \ + && sudo chmod +x minikube \ + && sudo cp minikube /usr/local/bin/ \ + && sudo rm minikube else echo "minikube is already installed" fi @@ -17,13 +17,9 @@ fi # Delete any existing minikube cluster minikube delete -# Default values for resources -DEFAULT_DISK_SIZE='50000mb' -DEFAULT_MEMORY='12000mb' - -# Get parameters with defaults -DISK_SIZE=${1:-$DEFAULT_DISK_SIZE} -MEMORY=${2:-$DEFAULT_MEMORY} +# Set disk and memory size, using defaults if not provided +DISK_SIZE=${1:-'50000mb'} +MEMORY=${2:-'12000mb'} # Start minikube with specified resources minikube start \ diff --git a/crates/fuel-streams-core/Cargo.toml b/crates/fuel-streams-core/Cargo.toml index 1ff4045f..69a28916 100644 --- a/crates/fuel-streams-core/Cargo.toml +++ b/crates/fuel-streams-core/Cargo.toml @@ -11,15 +11,29 @@ version = { workspace = true } rust-version = { workspace = true } [dependencies] +anyhow = { workspace = true } async-nats = { workspace = true } async-trait = { workspace = true } chrono = { workspace = true } clap = { workspace = true } displaydoc = { workspace = true } dotenvy = { workspace = true } -fuel-core-client = { workspace = true } +fuel-core = { workspace = true, default-features = false, features = [ + "p2p", + "relayer", + "rocksdb", + "test-helpers", +] } +fuel-core-bin = { workspace = true, default-features = false, features = [ + "p2p", + "relayer", + "rocksdb", +] } +fuel-core-client = { workspace = true, default-features = false, features = ["std"] } fuel-core-importer = { workspace = true } -fuel-core-types = { workspace = true } +fuel-core-services = { workspace = true, default-features = false, features = ["test-helpers"] } +fuel-core-storage = { workspace = true } +fuel-core-types = { workspace = true, default-features = false, features = ["std", "serde"] } fuel-data-parser = { workspace = true } fuel-streams-macros = { workspace = true } futures = { workspace = true } @@ -27,6 +41,7 @@ hex = { workspace = true } pretty_assertions = { workspace = true, optional = true } rand = { workspace = true } serde = { workspace = true } +serde_json = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } diff --git a/crates/fuel-streams-publisher/src/publisher/fuel_core_like.rs b/crates/fuel-streams-core/src/fuel_core_like.rs similarity index 92% rename from crates/fuel-streams-publisher/src/publisher/fuel_core_like.rs rename to crates/fuel-streams-core/src/fuel_core_like.rs index 921cf743..93a395a7 100644 --- a/crates/fuel-streams-publisher/src/publisher/fuel_core_like.rs +++ b/crates/fuel-streams-core/src/fuel_core_like.rs @@ -2,15 +2,8 @@ use std::{sync::Arc, time::Duration}; use fuel_core::{ combined_database::CombinedDatabase, - database::{ - database_description::{on_chain::OnChain, DatabaseHeight}, - Database, - }, + database::{database_description::on_chain::OnChain, Database}, fuel_core_graphql_api::ports::DatabaseBlocks, - state::{ - generic_database::GenericDatabase, - iterable_key_value_view::IterableKeyValueViewWrapper, - }, }; use fuel_core_bin::FuelService; use fuel_core_importer::ports::ImporterDatabase; @@ -19,14 +12,9 @@ use fuel_core_types::{ blockchain::consensus::{Consensus, Sealed}, fuel_types::BlockHeight, }; -use fuel_streams_core::types::*; use tokio::{sync::broadcast::Receiver, time::sleep}; -pub type OffchainDatabase = GenericDatabase< - IterableKeyValueViewWrapper< - fuel_core::fuel_core_graphql_api::storage::Column, - >, ->; +use crate::types::*; /// Interface for `fuel-core` related logic. /// This was introduced to simplify mocking and testing the `fuel-streams-publisher` crate. @@ -42,6 +30,7 @@ pub trait FuelCoreLike: Sync + Send { fn base_asset_id(&self) -> &FuelCoreAssetId; fn chain_id(&self) -> &FuelCoreChainId; + fn fuel_service(&self) -> &FuelService; fn database(&self) -> &CombinedDatabase; fn onchain_database(&self) -> &Database { @@ -60,14 +49,19 @@ pub trait FuelCoreLike: Sync + Send { &self, ) -> Receiver; - fn get_latest_block_height(&self) -> anyhow::Result { + fn get_latest_block_height(&self) -> anyhow::Result { Ok(self .onchain_database() .latest_block_height()? - .map(|h| h.as_u64()) + .map(|h| *h) .unwrap_or_default()) } + fn get_tx_status( + &self, + tx_id: &FuelCoreBytes32, + ) -> anyhow::Result>; + fn get_receipts( &self, tx_id: &FuelCoreBytes32, @@ -198,6 +192,10 @@ impl FuelCoreLike for FuelCore { Ok(()) } + fn fuel_service(&self) -> &FuelService { + &self.fuel_service + } + async fn stop(&self) { if matches!( self.fuel_service.state(), @@ -262,12 +260,18 @@ impl FuelCoreLike for FuelCore { .subscribe() } + fn get_tx_status( + &self, + tx_id: &FuelCoreBytes32, + ) -> anyhow::Result> { + Ok(self.offchain_database()?.get_tx_status(tx_id)?) + } + fn get_receipts( &self, tx_id: &FuelCoreBytes32, ) -> anyhow::Result>> { let receipts = self - .offchain_database()? .get_tx_status(tx_id)? .map(|status| match &status { FuelCoreTransactionStatus::Success { receipts, .. } diff --git a/crates/fuel-streams-core/src/fuel_core_types.rs b/crates/fuel-streams-core/src/fuel_core_types.rs index d42f0009..b5461427 100644 --- a/crates/fuel-streams-core/src/fuel_core_types.rs +++ b/crates/fuel-streams-core/src/fuel_core_types.rs @@ -1,5 +1,7 @@ -/// FuelCore Types -/// Allows flexilibity of aggregating and transforming them for different payload types +use fuel_core::state::{ + generic_database::GenericDatabase, + iterable_key_value_view::IterableKeyValueViewWrapper, +}; pub use fuel_core_client::client::schema::Tai64Timestamp as FuelCoreTai64Timestamp; pub use fuel_core_importer::ImporterResult as FuelCoreImporterResult; pub use fuel_core_types::{ @@ -29,7 +31,9 @@ pub use fuel_core_types::{ Input as FuelCoreInput, MessageId as FuelCoreMessageId, Output as FuelCoreOutput, + PanicInstruction as FuelCorePanicInstruction, Receipt as FuelCoreReceipt, + ScriptExecutionResult as FuelCoreScriptExecutionResult, StorageSlot as FuelCoreStorageSlot, Transaction as FuelCoreTransaction, TxId as FuelCoreTxId, @@ -52,3 +56,9 @@ pub use fuel_core_types::{ }, tai64::Tai64 as FuelCoreTai64, }; + +pub type OffchainDatabase = GenericDatabase< + IterableKeyValueViewWrapper< + fuel_core::fuel_core_graphql_api::storage::Column, + >, +>; diff --git a/crates/fuel-streams-core/src/inputs/types.rs b/crates/fuel-streams-core/src/inputs/types.rs index fcd5b01d..91ff8c1b 100644 --- a/crates/fuel-streams-core/src/inputs/types.rs +++ b/crates/fuel-streams-core/src/inputs/types.rs @@ -1,3 +1,5 @@ +use fuel_core_types::fuel_crypto; + use crate::types::*; // Input enum @@ -171,3 +173,24 @@ pub struct InputMessage { pub sender: Address, pub witness_index: u16, } + +impl InputMessage { + pub fn compute_message_id(&self) -> MessageId { + let hasher = fuel_crypto::Hasher::default() + .chain(self.sender.as_ref()) + .chain(self.recipient.as_ref()) + .chain(self.nonce.as_ref()) + .chain(self.amount.to_be_bytes()) + .chain(self.data.as_ref()); + + (*hasher.finalize()).into() + } + + pub fn computed_utxo_id(&self) -> UtxoId { + let message_id = self.compute_message_id(); + UtxoId { + tx_id: Bytes32::from(message_id), + output_index: 0, + } + } +} diff --git a/crates/fuel-streams-core/src/lib.rs b/crates/fuel-streams-core/src/lib.rs index 040bae8d..bea378e9 100644 --- a/crates/fuel-streams-core/src/lib.rs +++ b/crates/fuel-streams-core/src/lib.rs @@ -13,6 +13,7 @@ pub mod stream; pub mod subjects; +pub mod fuel_core_like; mod fuel_core_types; mod primitive_types; pub mod types; @@ -20,7 +21,14 @@ pub mod types; pub use stream::*; pub mod prelude { + #[allow(unused_imports)] pub use fuel_streams_macros::subject::*; - pub use crate::{nats::*, stream::*, subjects::*, types::*}; + pub use crate::{ + fuel_core_like::*, + nats::*, + stream::*, + subjects::*, + types::*, + }; } diff --git a/crates/fuel-streams-core/src/logs/types.rs b/crates/fuel-streams-core/src/logs/types.rs index 4fdb7473..927216d4 100644 --- a/crates/fuel-streams-core/src/logs/types.rs +++ b/crates/fuel-streams-core/src/logs/types.rs @@ -27,94 +27,30 @@ pub enum Log { }, } -impl From for Log { - fn from(value: FuelCoreReceipt) -> Self { +impl From for Log { + fn from(value: Receipt) -> Self { match value { - FuelCoreReceipt::Log { - id, - ra, - rb, - rc, - rd, - pc, - is, - } => Log::WithoutData { - id: id.into(), - ra, - rb, - rc, - rd, - pc, - is, + Receipt::Log(log) => Log::WithoutData { + id: log.id, + ra: log.ra, + rb: log.rb, + rc: log.rc, + rd: log.rd, + pc: log.pc, + is: log.is, }, - FuelCoreReceipt::LogData { - id, - ra, - rb, - ptr, - len, - digest, - pc, - is, - data, - } => Log::WithData { - id: id.into(), - ra, - rb, - ptr, - len, - digest: digest.into(), - pc, - is, - data, + Receipt::LogData(log) => Log::WithData { + id: log.id, + ra: log.ra, + rb: log.rb, + ptr: log.ptr, + len: log.len, + digest: log.digest, + pc: log.pc, + is: log.is, + data: log.data, }, _ => panic!("Invalid receipt type"), } } } - -/// Introduced majorly allow delegating serialization and deserialization to `fuel-core`'s Receipt -impl From for FuelCoreReceipt { - fn from(log: Log) -> FuelCoreReceipt { - match log { - Log::WithoutData { - id, - ra, - rb, - rc, - rd, - pc, - is, - } => FuelCoreReceipt::Log { - id: id.into(), - ra, - rb, - rc, - rd, - pc, - is, - }, - Log::WithData { - id, - ra, - rb, - ptr, - len, - digest, - pc, - is, - data, - } => FuelCoreReceipt::LogData { - id: id.into(), - ra, - rb, - ptr, - len, - digest: digest.into(), - pc, - is, - data, - }, - } - } -} diff --git a/crates/fuel-streams-core/src/nats/nats_client.rs b/crates/fuel-streams-core/src/nats/nats_client.rs index 3daae364..294e9a1d 100644 --- a/crates/fuel-streams-core/src/nats/nats_client.rs +++ b/crates/fuel-streams-core/src/nats/nats_client.rs @@ -64,7 +64,13 @@ impl NatsClient { source: e, } })?; - let jetstream = async_nats::jetstream::new(nats_client.to_owned()); + + let jetstream = match opts.domain.clone() { + None => async_nats::jetstream::new(nats_client.clone()), + Some(domain) => { + async_nats::jetstream::with_domain(nats_client.clone(), domain) + } + }; info!("Connected to NATS server at {}", url); Ok(Self { diff --git a/crates/fuel-streams-core/src/nats/nats_client_opts.rs b/crates/fuel-streams-core/src/nats/nats_client_opts.rs index 139ae32f..ffef16fa 100644 --- a/crates/fuel-streams-core/src/nats/nats_client_opts.rs +++ b/crates/fuel-streams-core/src/nats/nats_client_opts.rs @@ -72,6 +72,12 @@ pub struct NatsClientOpts { pub(crate) namespace: NatsNamespace, /// The timeout in seconds for NATS operations. pub(crate) timeout_secs: u64, + /// The domain to use for the NATS client. + pub(crate) domain: Option, + /// The user to use for the NATS client. + pub(crate) user: Option, + /// The password to use for the NATS client. + pub(crate) password: Option, } impl NatsClientOpts { @@ -81,6 +87,9 @@ impl NatsClientOpts { role: NatsUserRole::default(), namespace: NatsNamespace::default(), timeout_secs: 5, + domain: None, + user: None, + password: None, } } @@ -107,6 +116,27 @@ impl NatsClientOpts { } } + pub fn with_domain(self, domain: String) -> Self { + Self { + domain: Some(domain), + ..self + } + } + + pub fn with_user(self, user: String) -> Self { + Self { + user: Some(user), + ..self + } + } + + pub fn with_password(self, password: String) -> Self { + Self { + password: Some(password), + ..self + } + } + pub fn with_custom_url(self, url: String) -> Self { Self { url, ..self } } @@ -144,6 +174,11 @@ impl NatsClientOpts { } }; + let (user, pass) = match (self.user.clone(), self.password.clone()) { + (Some(user), Some(pass)) => (Some(user), Some(pass)), + _ => (user, pass), + }; + match (user, pass) { (Some(user), Some(pass)) => { ConnectOptions::with_user_and_password(user, pass) diff --git a/crates/fuel-streams-core/src/outputs/types.rs b/crates/fuel-streams-core/src/outputs/types.rs index 607bcd72..ddedd9a0 100644 --- a/crates/fuel-streams-core/src/outputs/types.rs +++ b/crates/fuel-streams-core/src/outputs/types.rs @@ -4,11 +4,11 @@ use crate::types::*; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(tag = "type")] pub enum Output { - Coin(CoinOutput), + Coin(OutputCoin), Contract(OutputContract), - Change(ChangeOutput), - Variable(VariableOutput), - ContractCreated(ContractCreated), + Change(OutputChange), + Variable(OutputVariable), + ContractCreated(OutputContractCreated), } impl From<&FuelCoreOutput> for Output { @@ -18,7 +18,7 @@ impl From<&FuelCoreOutput> for Output { amount, asset_id, to, - } => Output::Coin(CoinOutput { + } => Output::Coin(OutputCoin { amount: *amount, asset_id: asset_id.into(), to: to.into(), @@ -30,7 +30,7 @@ impl From<&FuelCoreOutput> for Output { amount, asset_id, to, - } => Output::Change(ChangeOutput { + } => Output::Change(OutputChange { amount: *amount, asset_id: asset_id.into(), to: to.into(), @@ -39,7 +39,7 @@ impl From<&FuelCoreOutput> for Output { amount, asset_id, to, - } => Output::Variable(VariableOutput { + } => Output::Variable(OutputVariable { amount: *amount, asset_id: asset_id.into(), to: to.into(), @@ -47,7 +47,7 @@ impl From<&FuelCoreOutput> for Output { FuelCoreOutput::ContractCreated { contract_id, state_root, - } => Output::ContractCreated(ContractCreated { + } => Output::ContractCreated(OutputContractCreated { contract_id: contract_id.into(), state_root: state_root.into(), }), @@ -57,7 +57,7 @@ impl From<&FuelCoreOutput> for Output { #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct CoinOutput { +pub struct OutputCoin { pub amount: u64, pub asset_id: AssetId, pub to: Address, @@ -65,7 +65,7 @@ pub struct CoinOutput { #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct ChangeOutput { +pub struct OutputChange { pub amount: u64, pub asset_id: AssetId, pub to: Address, @@ -73,7 +73,7 @@ pub struct ChangeOutput { #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct VariableOutput { +pub struct OutputVariable { pub amount: u64, pub asset_id: AssetId, pub to: Address, @@ -99,7 +99,7 @@ impl From<&FuelCoreOutputContract> for OutputContract { #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct ContractCreated { - contract_id: ContractId, - state_root: Bytes32, +pub struct OutputContractCreated { + pub contract_id: ContractId, + pub state_root: Bytes32, } diff --git a/crates/fuel-streams-core/src/primitive_types.rs b/crates/fuel-streams-core/src/primitive_types.rs index 997b4221..158f23af 100644 --- a/crates/fuel-streams-core/src/primitive_types.rs +++ b/crates/fuel-streams-core/src/primitive_types.rs @@ -1,4 +1,8 @@ -use fuel_core_types::fuel_types; +use fuel_core_types::{ + fuel_asm::RawInstruction, + fuel_tx::PanicReason, + fuel_types, +}; pub use serde::{Deserialize, Serialize}; use crate::fuel_core_types::*; @@ -158,6 +162,58 @@ generate_byte_type_wrapper!(Salt, fuel_types::Salt, 32); generate_byte_type_wrapper!(MessageId, fuel_types::MessageId, 32); generate_byte_type_wrapper!(BlockId, fuel_types::Bytes32, 32); generate_byte_type_wrapper!(Signature, fuel_types::Bytes64, 64); +generate_byte_type_wrapper!(TxId, fuel_types::TxId, 32); + +/// Implements bidirectional conversions between `Bytes32` and a given type. +/// +/// This macro generates implementations of the `From` trait to convert: +/// - From `Bytes32` to the target type +/// - From a reference to `Bytes32` to the target type +/// - From the target type to `Bytes32` +/// - From a reference of the target type to `Bytes32` +/// +/// The target type must be a 32-byte type that can be converted to/from `[u8; 32]`. +/// +/// # Example +/// ```ignore +/// impl_bytes32_conversions!(ContractId); +/// ``` +macro_rules! impl_bytes32_conversions { + ($type:ty) => { + impl From for $type { + fn from(value: Bytes32) -> Self { + let bytes: [u8; 32] = value.0.into(); + <$type>::from(bytes) + } + } + impl From<&Bytes32> for $type { + fn from(value: &Bytes32) -> Self { + value.clone().into() + } + } + impl From<$type> for Bytes32 { + fn from(value: $type) -> Self { + let bytes: [u8; 32] = value.0.into(); + Bytes32::from(bytes) + } + } + impl From<&$type> for Bytes32 { + fn from(value: &$type) -> Self { + value.clone().into() + } + } + }; +} + +impl_bytes32_conversions!(MessageId); +impl_bytes32_conversions!(ContractId); +impl_bytes32_conversions!(AssetId); +impl_bytes32_conversions!(Address); +impl_bytes32_conversions!(BlobId); +impl_bytes32_conversions!(Nonce); +impl_bytes32_conversions!(Salt); +impl_bytes32_conversions!(BlockId); +impl_bytes32_conversions!(TxId); impl From for BlockId { fn from(value: FuelCoreBlockId) -> Self { @@ -165,18 +221,6 @@ impl From for BlockId { } } -impl From for MessageId { - fn from(value: Bytes32) -> Self { - let bytes: [u8; 32] = value.0.into(); - MessageId::from(bytes) - } -} -impl From<&Bytes32> for MessageId { - fn from(value: &Bytes32) -> Self { - value.clone().into() - } -} - #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] pub struct HexString(pub Vec); impl_hex_serde!(HexString); @@ -186,13 +230,26 @@ impl From<&[u8]> for HexString { HexString(value.to_vec()) } } - +impl From for HexString { + fn from(value: Bytes32) -> Self { + Self::from(value.0.as_ref()) + } +} +impl TryFrom for Bytes32 { + type Error = String; + fn try_from(value: HexString) -> Result { + let bytes: [u8; 32] = value + .0 + .try_into() + .map_err(|_| "Invalid length for Bytes32".to_string())?; + Ok(Bytes32::from(bytes)) + } +} impl std::fmt::Display for HexString { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "0x{}", hex::encode(&self.0)) } } - impl std::str::FromStr for HexString { type Err = String; fn from_str(s: &str) -> Result { @@ -200,6 +257,16 @@ impl std::str::FromStr for HexString { hex::decode(s).map(HexString).map_err(|e| e.to_string()) } } +impl AsRef<[u8]> for HexString { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} +impl HexString { + pub fn zeroed() -> Self { + HexString(vec![0u8; 32]) + } +} #[derive( Debug, @@ -230,22 +297,17 @@ impl From for TxPointer { } #[derive( - Debug, - Default, - Copy, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Serialize, - Deserialize, + Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, )] #[serde(rename_all = "camelCase")] pub struct UtxoId { - tx_id: FuelCoreTxId, - output_index: u16, + pub tx_id: Bytes32, + pub output_index: u16, +} +impl From<&UtxoId> for HexString { + fn from(value: &UtxoId) -> Self { + value.to_owned().into() + } } impl From for UtxoId { fn from(value: FuelCoreUtxoId) -> Self { @@ -255,11 +317,67 @@ impl From for UtxoId { impl From<&FuelCoreUtxoId> for UtxoId { fn from(value: &FuelCoreUtxoId) -> Self { Self { - tx_id: *value.tx_id(), + tx_id: value.tx_id().into(), output_index: value.output_index(), } } } +impl From for HexString { + fn from(value: UtxoId) -> Self { + let mut bytes = Vec::with_capacity(34); + bytes.extend_from_slice(value.tx_id.0.as_ref()); + bytes.extend_from_slice(&value.output_index.to_be_bytes()); + HexString(bytes) + } +} + +#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] +pub struct PanicInstruction { + pub reason: PanicReason, + pub instruction: RawInstruction, +} +impl From for PanicInstruction { + fn from(value: FuelCorePanicInstruction) -> Self { + Self { + reason: value.reason().to_owned(), + instruction: value.instruction().to_owned(), + } + } +} + +#[derive( + Debug, + Copy, + Clone, + PartialEq, + Eq, + Hash, + Default, + serde::Serialize, + serde::Deserialize, +)] +#[repr(u64)] +pub enum ScriptExecutionResult { + Success, + Revert, + Panic, + // Generic failure case since any u64 is valid here + GenericFailure(u64), + #[default] + Unknown, +} +impl From for ScriptExecutionResult { + fn from(value: FuelCoreScriptExecutionResult) -> Self { + match value { + FuelCoreScriptExecutionResult::Success => Self::Success, + FuelCoreScriptExecutionResult::Revert => Self::Revert, + FuelCoreScriptExecutionResult::Panic => Self::Panic, + FuelCoreScriptExecutionResult::GenericFailure(value) => { + Self::GenericFailure(value) + } + } + } +} /// Macro to implement conversion from a type to `Bytes32`. /// diff --git a/crates/fuel-streams-core/src/receipts/types.rs b/crates/fuel-streams-core/src/receipts/types.rs index b32e654e..565185d8 100644 --- a/crates/fuel-streams-core/src/receipts/types.rs +++ b/crates/fuel-streams-core/src/receipts/types.rs @@ -1,106 +1,365 @@ +use fuel_core_types::fuel_asm::Word; +use serde::{self, Deserialize, Serialize}; + use crate::types::*; -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(tag = "type")] +pub enum Receipt { + Call(CallReceipt), + Return(ReturnReceipt), + ReturnData(ReturnDataReceipt), + Panic(PanicReceipt), + Revert(RevertReceipt), + Log(LogReceipt), + LogData(LogDataReceipt), + Transfer(TransferReceipt), + TransferOut(TransferOutReceipt), + ScriptResult(ScriptResultReceipt), + MessageOut(MessageOutReceipt), + Mint(MintReceipt), + Burn(BurnReceipt), +} + +// Individual Receipt Types +#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct CallReceipt { + pub id: ContractId, + pub to: ContractId, + pub amount: Word, + pub asset_id: AssetId, + pub gas: Word, + pub param1: Word, + pub param2: Word, + pub pc: Word, + pub is: Word, +} + +#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct Receipt { - pub amount: Option, - pub asset_id: Option, +pub struct ReturnReceipt { + pub id: ContractId, + pub val: Word, + pub pc: Word, + pub is: Word, +} + +#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ReturnDataReceipt { + pub id: ContractId, + pub ptr: Word, + pub len: Word, + pub digest: Bytes32, + pub pc: Word, + pub is: Word, + #[serde(skip_serializing_if = "Option::is_none")] + pub data: Option>, +} + +#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PanicReceipt { + pub id: ContractId, + pub reason: PanicInstruction, + pub pc: Word, + pub is: Word, + #[serde(skip_serializing_if = "Option::is_none")] pub contract_id: Option, - pub data: Option, - pub digest: Option, - pub gas: Option, - pub gas_used: Option, - pub id: Option, - pub is: Option, - pub len: Option, - pub nonce: Option, - pub param1: Option, - pub param2: Option, - pub pc: Option, - pub ptr: Option, - pub ra: Option, - pub rb: Option, - pub rc: Option, - pub rd: Option, - pub reason: Option, - pub receipt_type: ReceiptType, - pub recipient: Option
, - pub result: Option, - pub sender: Option
, - pub sub_id: Option, - pub to: Option, - pub to_address: Option
, - pub val: Option, } -impl From<&FuelCoreReceipt> for Receipt { - fn from(r: &FuelCoreReceipt) -> Self { - Receipt { - amount: r.amount().map(Into::into), - asset_id: r.asset_id().copied().map(Into::into), - contract_id: r.contract_id().map(Into::into), - data: r.data().map(Into::into), - digest: r.digest().copied().map(Into::into), - gas: r.gas().map(Into::into), - gas_used: r.gas_used().map(Into::into), - id: r.id().map(Into::into), - is: r.is().map(Into::into), - len: r.len().map(Into::into), - nonce: r.nonce().copied().map(Into::into), - param1: r.param1().map(Into::into), - param2: r.param2().map(Into::into), - pc: r.pc().map(Into::into), - ptr: r.ptr().map(Into::into), - ra: r.ra().map(Into::into), - rb: r.rb().map(Into::into), - rc: r.rc().map(Into::into), - rd: r.rd().map(Into::into), - reason: r.reason().map(Into::into), - receipt_type: r.into(), - recipient: r.recipient().copied().map(Into::into), - result: r.result().map(|r| FuelCoreWord::from(*r)), - sender: r.sender().copied().map(Into::into), - sub_id: r.sub_id().copied().map(Into::into), - to: r.to().copied().map(Into::into), - to_address: r.to_address().copied().map(Into::into), - val: r.val().map(Into::into), +#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RevertReceipt { + pub id: ContractId, + pub ra: Word, + pub pc: Word, + pub is: Word, +} + +#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct LogReceipt { + pub id: ContractId, + pub ra: Word, + pub rb: Word, + pub rc: Word, + pub rd: Word, + pub pc: Word, + pub is: Word, +} + +#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct LogDataReceipt { + pub id: ContractId, + pub ra: Word, + pub rb: Word, + pub ptr: Word, + pub len: Word, + pub digest: Bytes32, + pub pc: Word, + pub is: Word, + #[serde(skip_serializing_if = "Option::is_none")] + pub data: Option>, +} + +#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TransferReceipt { + pub id: ContractId, + pub to: ContractId, + pub amount: Word, + pub asset_id: AssetId, + pub pc: Word, + pub is: Word, +} + +#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TransferOutReceipt { + pub id: ContractId, + pub to: Address, + pub amount: Word, + pub asset_id: AssetId, + pub pc: Word, + pub is: Word, +} + +#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ScriptResultReceipt { + pub result: ScriptExecutionResult, + pub gas_used: Word, +} + +#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct MessageOutReceipt { + pub sender: Address, + pub recipient: Address, + pub amount: Word, + pub nonce: Nonce, + pub len: Word, + pub digest: Bytes32, + #[serde(skip_serializing_if = "Option::is_none")] + pub data: Option>, +} + +#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct MintReceipt { + pub sub_id: Bytes32, + pub contract_id: ContractId, + pub val: Word, + pub pc: Word, + pub is: Word, +} + +#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct BurnReceipt { + pub sub_id: Bytes32, + pub contract_id: ContractId, + pub val: Word, + pub pc: Word, + pub is: Word, +} + +impl From for Receipt { + fn from(value: FuelCoreReceipt) -> Self { + match value { + FuelCoreReceipt::Call { + id, + to, + amount, + asset_id, + gas, + param1, + param2, + pc, + is, + } => Self::Call(CallReceipt { + id: id.into(), + to: to.into(), + amount, + asset_id: asset_id.into(), + gas, + param1, + param2, + pc, + is, + }), + FuelCoreReceipt::Return { id, val, pc, is } => { + Self::Return(ReturnReceipt { + id: id.into(), + val, + pc, + is, + }) + } + FuelCoreReceipt::ReturnData { + id, + ptr, + len, + digest, + pc, + is, + data, + } => Self::ReturnData(ReturnDataReceipt { + id: id.into(), + ptr, + len, + digest: digest.into(), + pc, + is, + data, + }), + FuelCoreReceipt::Panic { + id, + reason, + pc, + is, + contract_id, + } => Self::Panic(PanicReceipt { + id: id.into(), + reason: reason.into(), + pc, + is, + contract_id: contract_id.map(|id| id.into()), + }), + FuelCoreReceipt::Revert { id, ra, pc, is } => { + Self::Revert(RevertReceipt { + id: id.into(), + ra, + pc, + is, + }) + } + FuelCoreReceipt::Log { + id, + ra, + rb, + rc, + rd, + pc, + is, + } => Self::Log(LogReceipt { + id: id.into(), + ra, + rb, + rc, + rd, + pc, + is, + }), + FuelCoreReceipt::LogData { + id, + ra, + rb, + ptr, + len, + digest, + pc, + is, + data, + } => Self::LogData(LogDataReceipt { + id: id.into(), + ra, + rb, + ptr, + len, + digest: digest.into(), + pc, + is, + data, + }), + FuelCoreReceipt::Transfer { + id, + to, + amount, + asset_id, + pc, + is, + } => Self::Transfer(TransferReceipt { + id: id.into(), + to: to.into(), + amount, + asset_id: asset_id.into(), + pc, + is, + }), + FuelCoreReceipt::TransferOut { + id, + to, + amount, + asset_id, + pc, + is, + } => Self::TransferOut(TransferOutReceipt { + id: id.into(), + to: to.into(), + amount, + asset_id: asset_id.into(), + pc, + is, + }), + FuelCoreReceipt::ScriptResult { result, gas_used } => { + Self::ScriptResult(ScriptResultReceipt { + result: result.into(), + gas_used, + }) + } + FuelCoreReceipt::MessageOut { + sender, + recipient, + amount, + nonce, + len, + digest, + data, + } => Self::MessageOut(MessageOutReceipt { + sender: sender.into(), + recipient: recipient.into(), + amount, + nonce: nonce.into(), + len, + digest: digest.into(), + data, + }), + FuelCoreReceipt::Mint { + sub_id, + contract_id, + val, + pc, + is, + } => Self::Mint(MintReceipt { + sub_id: sub_id.into(), + contract_id: contract_id.into(), + val, + pc, + is, + }), + FuelCoreReceipt::Burn { + sub_id, + contract_id, + val, + pc, + is, + } => Self::Burn(BurnReceipt { + sub_id: sub_id.into(), + contract_id: contract_id.into(), + val, + pc, + is, + }), } } } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub enum ReceiptType { - Burn, - Call, - Log, - LogData, - MessageOut, - Mint, - Panic, - Return, - ReturnData, - Revert, - ScriptResult, - Transfer, - TransferOut, -} - -impl From<&FuelCoreReceipt> for ReceiptType { - fn from(r: &FuelCoreReceipt) -> Self { - match r { - FuelCoreReceipt::Call { .. } => ReceiptType::Call, - FuelCoreReceipt::Return { .. } => ReceiptType::Return, - FuelCoreReceipt::ReturnData { .. } => ReceiptType::ReturnData, - FuelCoreReceipt::Panic { .. } => ReceiptType::Panic, - FuelCoreReceipt::Revert { .. } => ReceiptType::Revert, - FuelCoreReceipt::Log { .. } => ReceiptType::Log, - FuelCoreReceipt::LogData { .. } => ReceiptType::LogData, - FuelCoreReceipt::Transfer { .. } => ReceiptType::Transfer, - FuelCoreReceipt::TransferOut { .. } => ReceiptType::TransferOut, - FuelCoreReceipt::ScriptResult { .. } => ReceiptType::ScriptResult, - FuelCoreReceipt::MessageOut { .. } => ReceiptType::MessageOut, - FuelCoreReceipt::Mint { .. } => ReceiptType::Mint, - FuelCoreReceipt::Burn { .. } => ReceiptType::Burn, - } +impl From<&FuelCoreReceipt> for Receipt { + fn from(value: &FuelCoreReceipt) -> Self { + value.clone().into() } } diff --git a/crates/fuel-streams-publisher/src/publisher/fuel_streams.rs b/crates/fuel-streams-core/src/stream/fuel_streams.rs similarity index 87% rename from crates/fuel-streams-publisher/src/publisher/fuel_streams.rs rename to crates/fuel-streams-core/src/stream/fuel_streams.rs index 6900c82a..c7e8ba08 100644 --- a/crates/fuel-streams-publisher/src/publisher/fuel_streams.rs +++ b/crates/fuel-streams-core/src/stream/fuel_streams.rs @@ -1,9 +1,10 @@ +use std::sync::Arc; + use async_nats::{jetstream::stream::State as StreamState, RequestErrorKind}; -use fuel_streams::types::Log; -use fuel_streams_core::prelude::*; + +use crate::prelude::*; #[derive(Clone, Debug)] -/// Streams we currently support publishing to. pub struct FuelStreams { pub transactions: Stream, pub blocks: Stream, @@ -14,7 +15,6 @@ pub struct FuelStreams { pub logs: Stream, } -#[cfg_attr(test, mockall::automock)] impl FuelStreams { pub async fn new(nats_client: &NatsClient) -> Self { Self { @@ -27,6 +27,19 @@ impl FuelStreams { logs: Stream::::new(nats_client).await, } } + + pub async fn setup_all( + core_client: &NatsClient, + publisher_client: &NatsClient, + ) -> (Self, Self) { + let core_stream = Self::new(core_client).await; + let publisher_stream = Self::new(publisher_client).await; + (core_stream, publisher_stream) + } + + pub fn arc(self) -> Arc { + Arc::new(self) + } } #[async_trait::async_trait] @@ -72,7 +85,7 @@ pub trait FuelStreamsExt: Sync + Send { &self, ) -> Result, StreamState)>, RequestErrorKind>; - #[cfg(feature = "test-helpers")] + #[cfg(any(test, feature = "test-helpers"))] async fn is_empty(&self) -> bool; } @@ -101,10 +114,10 @@ impl FuelStreamsExt for FuelStreams { } async fn get_last_published_block(&self) -> anyhow::Result> { - Ok(self - .blocks + self.blocks .get_last_published(BlocksSubject::WILDCARD) - .await?) + .await + .map_err(|e| e.into()) } async fn get_consumers_and_state( @@ -121,7 +134,7 @@ impl FuelStreamsExt for FuelStreams { ]) } - #[cfg(feature = "test-helpers")] + #[cfg(any(test, feature = "test-helpers"))] async fn is_empty(&self) -> bool { self.blocks.is_empty(BlocksSubject::WILDCARD).await && self diff --git a/crates/fuel-streams-core/src/stream/mod.rs b/crates/fuel-streams-core/src/stream/mod.rs index 4ea63aff..a204e8d1 100644 --- a/crates/fuel-streams-core/src/stream/mod.rs +++ b/crates/fuel-streams-core/src/stream/mod.rs @@ -1,7 +1,9 @@ mod error; +mod fuel_streams; mod stream_encoding; mod stream_impl; pub use error::*; +pub use fuel_streams::*; pub use stream_encoding::*; pub use stream_impl::*; diff --git a/crates/fuel-streams-core/src/stream/stream_impl.rs b/crates/fuel-streams-core/src/stream/stream_impl.rs index c3b7e855..e2d690ed 100644 --- a/crates/fuel-streams-core/src/stream/stream_impl.rs +++ b/crates/fuel-streams-core/src/stream/stream_impl.rs @@ -1,6 +1,6 @@ #[cfg(any(test, feature = "test-helpers"))] use std::pin::Pin; -use std::{fmt::Debug, sync::Arc, time::Duration}; +use std::{fmt::Debug, sync::Arc}; use async_nats::{ jetstream::{ @@ -128,17 +128,17 @@ impl Stream { pub async fn new(client: &NatsClient) -> Self { let namespace = &client.namespace; let bucket_name = namespace.stream_name(S::NAME); + + let config = kv::Config { + bucket: bucket_name.to_owned(), + storage: stream::StorageType::File, + history: 1, + compression: true, + ..Default::default() + }; + let store = client - .get_or_create_kv_store(kv::Config { - bucket: bucket_name.to_owned(), - storage: stream::StorageType::File, - history: 1, - compression: true, - max_age: Duration::from_secs( - FUEL_BLOCK_TIME_SECS * MAX_RETENTION_BLOCKS, - ), - ..Default::default() - }) + .get_or_create_kv_store(config) .await .expect("Streams must be created"); @@ -291,7 +291,6 @@ impl Stream { wildcard: &str, ) -> Result, StreamError> { let subject_name = &Self::prefix_filter_subject(wildcard); - let message = self .store .stream @@ -301,7 +300,6 @@ impl Stream { match message { Ok(message) => { let payload = S::decode(message.payload.to_vec()).await; - Ok(Some(payload)) } Err(error) => match &error.kind() { @@ -345,6 +343,10 @@ impl Stream { pub fn store(&self) -> &kv::Store { &self.store } + + pub fn arc(&self) -> Arc { + Arc::new(self.to_owned()) + } } /// Configuration for subscribing to a consumer. diff --git a/crates/fuel-streams-core/src/transactions/types.rs b/crates/fuel-streams-core/src/transactions/types.rs index fe6233b5..adeb64fc 100644 --- a/crates/fuel-streams-core/src/transactions/types.rs +++ b/crates/fuel-streams-core/src/transactions/types.rs @@ -1,3 +1,4 @@ +pub use fuel_core_client::client::types::TransactionStatus as ClientTransactionStatus; use fuel_core_types::fuel_tx; use crate::types::*; @@ -405,7 +406,7 @@ impl Transaction { tx_pointer, upgrade_purpose, witnesses, - receipts: receipts.iter().map(Into::into).collect(), + receipts: receipts.iter().map(|r| r.to_owned().into()).collect(), } } } @@ -502,6 +503,31 @@ impl From<&FuelCoreTransactionStatus> for TransactionStatus { } } +impl From<&ClientTransactionStatus> for TransactionStatus { + fn from(value: &ClientTransactionStatus) -> Self { + match value { + ClientTransactionStatus::Failure { .. } => { + TransactionStatus::Failed + } + ClientTransactionStatus::Submitted { .. } => { + TransactionStatus::Submitted + } + ClientTransactionStatus::SqueezedOut { .. } => { + TransactionStatus::SqueezedOut + } + ClientTransactionStatus::Success { .. } => { + TransactionStatus::Success + } + } + } +} + +impl From for TransactionStatus { + fn from(value: ClientTransactionStatus) -> Self { + (&value).into() + } +} + pub trait FuelCoreTransactionExt { fn inputs(&self) -> &[FuelCoreInput]; fn outputs(&self) -> &Vec; diff --git a/crates/fuel-streams-core/src/types.rs b/crates/fuel-streams-core/src/types.rs index 9b9c16fb..4eb3a874 100644 --- a/crates/fuel-streams-core/src/types.rs +++ b/crates/fuel-streams-core/src/types.rs @@ -16,4 +16,5 @@ pub use crate::{ // ------------------------------------------------------------------------ // General // ------------------------------------------------------------------------ -pub type BoxedResult = Result>; +pub type BoxedError = Box; +pub type BoxedResult = Result; diff --git a/crates/fuel-streams-core/src/utxos/subjects.rs b/crates/fuel-streams-core/src/utxos/subjects.rs index 6238f49e..2d89d4c7 100644 --- a/crates/fuel-streams-core/src/utxos/subjects.rs +++ b/crates/fuel-streams-core/src/utxos/subjects.rs @@ -16,12 +16,12 @@ use crate::types::*; /// # use fuel_streams_core::types::*; /// # use fuel_streams_macros::subject::*; /// let subject = UtxosSubject { -/// hash: Some(MessageId::from([1u8; 32])), +/// utxo_id: Some(HexString::zeroed()), /// utxo_type: Some(UtxoType::Message), /// }; /// assert_eq!( /// subject.parse(), -/// "utxos.message.0x0101010101010101010101010101010101010101010101010101010101010101" +/// "utxos.message.0x0000000000000000000000000000000000000000000000000000000000000000" /// ); /// ``` /// @@ -40,10 +40,10 @@ use crate::types::*; /// # use fuel_streams_core::types::*; /// # use fuel_streams_macros::subject::*; /// let wildcard = UtxosSubject::wildcard( -/// Some(MessageId::from([1u8; 32])), +/// Some(HexString::zeroed()), /// None, /// ); -/// assert_eq!(wildcard, "utxos.*.0x0101010101010101010101010101010101010101010101010101010101010101"); +/// assert_eq!(wildcard, "utxos.*.0x0000000000000000000000000000000000000000000000000000000000000000"); /// ``` /// /// Using the builder pattern: @@ -53,16 +53,16 @@ use crate::types::*; /// # use fuel_streams_core::types::*; /// # use fuel_streams_macros::subject::*; /// let subject = UtxosSubject::new() -/// .with_hash(Some(MessageId::from([1u8; 32]))) +/// .with_utxo_id(Some(HexString::zeroed())) /// .with_utxo_type(Some(UtxoType::Message)); -/// assert_eq!(subject.parse(), "utxos.message.0x0101010101010101010101010101010101010101010101010101010101010101"); +/// assert_eq!(subject.parse(), "utxos.message.0x0000000000000000000000000000000000000000000000000000000000000000"); /// ``` #[derive(Subject, Debug, Clone, Default)] #[subject_wildcard = "utxos.>"] -#[subject_format = "utxos.{utxo_type}.{hash}"] +#[subject_format = "utxos.{utxo_type}.{utxo_id}"] pub struct UtxosSubject { - pub hash: Option, + pub utxo_id: Option, pub utxo_type: Option, } @@ -80,7 +80,7 @@ mod tests { #[test] fn test_utxos_message_subject_creation() { let utxo_subject = UtxosSubject::new() - .with_hash(Some(MessageId::zeroed())) + .with_utxo_id(Some(HexString::zeroed())) .with_utxo_type(Some(UtxoType::Message)); assert_eq!( utxo_subject.to_string(), @@ -91,7 +91,7 @@ mod tests { #[test] fn test_utxos_coin_subject_creation() { let utxo_subject = UtxosSubject::new() - .with_hash(Some(MessageId::zeroed())) + .with_utxo_id(Some(HexString::zeroed())) .with_utxo_type(Some(UtxoType::Coin)); assert_eq!( utxo_subject.to_string(), @@ -102,7 +102,7 @@ mod tests { #[test] fn test_utxos_contract_subject_creation() { let utxo_subject = UtxosSubject::new() - .with_hash(Some(MessageId::zeroed())) + .with_utxo_id(Some(HexString::zeroed())) .with_utxo_type(Some(UtxoType::Contract)); assert_eq!( utxo_subject.to_string(), diff --git a/crates/fuel-streams-core/src/utxos/types.rs b/crates/fuel-streams-core/src/utxos/types.rs index 2e067f29..1fd8daec 100644 --- a/crates/fuel-streams-core/src/utxos/types.rs +++ b/crates/fuel-streams-core/src/utxos/types.rs @@ -7,7 +7,7 @@ pub struct Utxo { pub sender: Option
, pub recipient: Option
, pub nonce: Option, - pub data: Option>, + pub data: Option, pub amount: Option, pub tx_id: Bytes32, } diff --git a/crates/fuel-streams-executors/Cargo.toml b/crates/fuel-streams-executors/Cargo.toml new file mode 100644 index 00000000..7b70773d --- /dev/null +++ b/crates/fuel-streams-executors/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "fuel-streams-executors" +description = "Executors for Fuel Streams entities" +authors = { workspace = true } +keywords = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +version = { workspace = true } +rust-version = { workspace = true } +publish = false + +[dependencies] +anyhow = { workspace = true } +async-nats = { workspace = true } +fuel-core = { workspace = true } +fuel-streams-core = { workspace = true, features = ["test-helpers"] } +futures = { workspace = true } +num_cpus = { workspace = true } +rayon = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +sha2 = { workspace = true } +thiserror = { workspace = true } +tokio = { workspace = true } +tracing = { workspace = true } + +[features] +default = [] +test-helpers = [] diff --git a/crates/fuel-streams-executors/src/blocks.rs b/crates/fuel-streams-executors/src/blocks.rs new file mode 100644 index 00000000..b24ce9d6 --- /dev/null +++ b/crates/fuel-streams-executors/src/blocks.rs @@ -0,0 +1,81 @@ +use std::{sync::Arc, time::Instant}; + +use fuel_streams_core::prelude::*; +use futures::{future::try_join_all, stream::FuturesUnordered}; +use tokio::task::JoinHandle; + +use crate::*; + +impl Executor { + pub fn process(&self) -> JoinHandle> { + let metadata = self.metadata(); + let block = self.block(); + let block_height = (*metadata.block_height).clone(); + let block_producer = (*metadata.block_producer).clone(); + let packet = PublishPacket::::new( + block.to_owned(), + BlocksSubject { + height: Some(block_height), + producer: Some(block_producer), + } + .arc(), + ); + self.publish(&packet) + } + + pub async fn process_all( + payload: Arc, + fuel_streams: &Arc, + ) -> Result<(), ExecutorError> { + let start_time = Instant::now(); + let metadata = Arc::new(payload.metadata().clone()); + + let block_stream = fuel_streams.blocks().arc(); + let tx_stream = fuel_streams.transactions().arc(); + let input_stream = fuel_streams.inputs().arc(); + let output_stream = fuel_streams.outputs().arc(); + let receipt_stream = fuel_streams.receipts().arc(); + let log_stream = fuel_streams.logs().arc(); + let utxo_stream = fuel_streams.utxos().arc(); + + let block_executor = Executor::new(&payload, &block_stream); + let tx_executor = Executor::new(&payload, &tx_stream); + let input_executor = Executor::new(&payload, &input_stream); + let output_executor = Executor::new(&payload, &output_stream); + let receipt_executor = Executor::new(&payload, &receipt_stream); + let log_executor = Executor::new(&payload, &log_stream); + let utxo_executor = Executor::new(&payload, &utxo_stream); + + let transactions = payload.transactions.to_owned(); + let tx_tasks = + transactions + .iter() + .enumerate() + .flat_map(|tx_item @ (_, tx)| { + vec![ + tx_executor.process(tx_item), + input_executor.process(tx), + output_executor.process(tx), + receipt_executor.process(tx), + log_executor.process(tx), + utxo_executor.process(tx), + ] + }); + + let block_task = block_executor.process(); + let all_tasks = std::iter::once(block_task) + .chain(tx_tasks.into_iter().flatten()) + .collect::>(); + + try_join_all(all_tasks).await?; + + let elapsed = start_time.elapsed(); + let height = metadata.block_height.clone(); + tracing::info!( + "Published streams for BlockHeight: {height} in {:?}", + elapsed + ); + + Ok(()) + } +} diff --git a/crates/fuel-streams-executors/src/inputs.rs b/crates/fuel-streams-executors/src/inputs.rs new file mode 100644 index 00000000..0c201b3b --- /dev/null +++ b/crates/fuel-streams-executors/src/inputs.rs @@ -0,0 +1,129 @@ +use std::sync::Arc; + +use fuel_streams_core::prelude::*; +use rayon::prelude::*; +use tokio::task::JoinHandle; + +use crate::*; + +impl Executor { + pub fn process( + &self, + tx: &Transaction, + ) -> Vec>> { + let tx_id = tx.id.clone(); + let packets = tx + .inputs + .par_iter() + .enumerate() + .flat_map(move |(index, input)| { + let main_subject = main_subject(input, tx_id.clone(), index); + let identifier_subjects = + identifiers(input, &tx_id, index as u8) + .into_par_iter() + .map(|identifier| identifier.into()) + .map(|subject: InputsByIdSubject| subject.arc()) + .collect::>(); + + let mut packets = vec![input.to_packet(main_subject)]; + packets.extend( + identifier_subjects + .into_iter() + .map(|subject| input.to_packet(subject)), + ); + + packets + }) + .collect::>(); + + packets.iter().map(|packet| self.publish(packet)).collect() + } +} + +fn main_subject( + input: &Input, + tx_id: Bytes32, + index: usize, +) -> Arc { + match input { + Input::Contract(contract) => InputsContractSubject { + tx_id: Some(tx_id), + index: Some(index), + contract_id: Some(contract.contract_id.to_owned().into()), + } + .arc(), + Input::Coin(coin) => InputsCoinSubject { + tx_id: Some(tx_id), + index: Some(index), + owner: Some(coin.owner.to_owned()), + asset_id: Some(coin.asset_id.to_owned()), + } + .arc(), + Input::Message(message) => InputsMessageSubject { + tx_id: Some(tx_id), + index: Some(index), + sender: Some(message.sender.to_owned()), + recipient: Some(message.recipient.to_owned()), + } + .arc(), + } +} + +pub fn identifiers( + input: &Input, + tx_id: &Bytes32, + index: u8, +) -> Vec { + let mut identifiers = match input { + Input::Coin(coin) => { + vec![ + Identifier::Address( + tx_id.to_owned(), + index, + coin.owner.to_owned().into(), + ), + Identifier::AssetID( + tx_id.to_owned(), + index, + coin.asset_id.to_owned().into(), + ), + ] + } + Input::Message(message) => { + vec![ + Identifier::Address( + tx_id.to_owned(), + index, + message.sender.to_owned().into(), + ), + Identifier::Address( + tx_id.to_owned(), + index, + message.recipient.to_owned().into(), + ), + ] + } + Input::Contract(contract) => { + vec![Identifier::ContractID( + tx_id.to_owned(), + index, + contract.contract_id.to_owned(), + )] + } + }; + + match input { + Input::Coin(InputCoin { predicate, .. }) + | Input::Message(InputMessage { predicate, .. }) => { + let predicate_tag = super::sha256(&predicate.0); + identifiers.push(Identifier::PredicateID( + tx_id.to_owned(), + index, + predicate_tag, + )); + } + _ => {} + }; + + identifiers +} diff --git a/crates/fuel-streams-executors/src/lib.rs b/crates/fuel-streams-executors/src/lib.rs new file mode 100644 index 00000000..1fa507f9 --- /dev/null +++ b/crates/fuel-streams-executors/src/lib.rs @@ -0,0 +1,250 @@ +pub mod blocks; +pub mod inputs; +pub mod logs; +pub mod outputs; +pub mod receipts; +pub mod transactions; +pub mod utxos; + +use std::{ + env, + marker::PhantomData, + sync::{Arc, LazyLock}, +}; + +use async_nats::jetstream::context::Publish; +use fuel_streams_core::prelude::*; +use serde::{Deserialize, Serialize}; +use sha2::{Digest, Sha256}; +use tokio::task::JoinHandle; + +pub static PUBLISHER_MAX_THREADS: LazyLock = LazyLock::new(|| { + let available_cpus = num_cpus::get(); + let default_threads = (available_cpus / 3).max(1); // Use 1/3 of CPUs, minimum 1 + + env::var("PUBLISHER_MAX_THREADS") + .ok() + .and_then(|val| val.parse().ok()) + .unwrap_or(default_threads) +}); + +pub fn sha256(bytes: &[u8]) -> Bytes32 { + let mut sha256 = Sha256::new(); + sha256.update(bytes); + let bytes: [u8; 32] = sha256 + .finalize() + .as_slice() + .try_into() + .expect("Must be 32 bytes"); + + bytes.into() +} + +#[derive(Debug, thiserror::Error)] +pub enum ExecutorError { + #[error("Failed to publish: {0}")] + PublishFailed(String), + #[error("Failed to acquire semaphore: {0}")] + SemaphoreError(#[from] tokio::sync::AcquireError), + #[error("Failed to serialize block payload: {0}")] + Serialization(#[from] serde_json::Error), + #[error("Failed to fetch transaction status: {0}")] + TransactionStatus(String), + #[error("Failed to access offchain database")] + OffchainDatabase(#[from] anyhow::Error), + #[error("Failed to join tasks: {0}")] + JoinError(#[from] tokio::task::JoinError), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Metadata { + pub chain_id: Arc, + pub base_asset_id: Arc, + pub block_producer: Arc
, + pub block_height: Arc, + pub consensus: Arc, +} + +impl Metadata { + pub fn new( + fuel_core: &Arc, + sealed_block: &FuelCoreSealedBlock, + ) -> Self { + let block = sealed_block.entity.clone(); + let consensus = sealed_block.consensus.clone(); + let height = *block.header().consensus().height; + let producer = + consensus.block_producer(&block.id()).unwrap_or_default(); + Self { + chain_id: Arc::new(*fuel_core.chain_id()), + base_asset_id: Arc::new(*fuel_core.base_asset_id()), + block_producer: Arc::new(producer.into()), + block_height: Arc::new(height.into()), + consensus: Arc::new(consensus.into()), + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct BlockPayload { + pub block: Block, + pub transactions: Vec, + metadata: Metadata, +} + +impl BlockPayload { + pub fn new( + fuel_core: Arc, + sealed_block: &FuelCoreSealedBlock, + metadata: &Metadata, + ) -> Result { + let block = sealed_block.entity.clone(); + let txs = Self::txs_from_fuelcore( + fuel_core.to_owned(), + sealed_block, + metadata, + )?; + let txs_ids = txs.iter().map(|i| i.id.clone()).collect(); + let block_height = block.header().height(); + let consensus = fuel_core.get_consensus(block_height)?; + let block = Block::new(&block, consensus.into(), txs_ids); + Ok(Self { + block, + transactions: txs, + metadata: metadata.to_owned(), + }) + } + + pub fn encode(&self) -> Result { + serde_json::to_string(self).map_err(ExecutorError::from) + } + + pub fn decode(json: &str) -> Result { + serde_json::from_str(json).map_err(ExecutorError::from) + } + + pub fn tx_ids(&self) -> Vec { + self.transactions + .iter() + .map(|tx| tx.id.clone()) + .collect::>() + } + + pub fn message_id(&self) -> String { + let height = self.metadata.block_height.clone(); + format!("block_{height}") + } + + pub fn subject(&self) -> String { + let producer = self.metadata.block_producer.clone(); + let height = self.metadata.block_height.clone(); + format!("block_submitted.{producer}.{height}") + } + + pub fn metadata(&self) -> &Metadata { + &self.metadata + } + + pub fn block_height(&self) -> u32 { + self.block.height + } + + pub fn arc(&self) -> Arc { + Arc::new(self.clone()) + } + + pub fn txs_from_fuelcore( + fuel_core: Arc, + sealed_block: &FuelCoreSealedBlock, + metadata: &Metadata, + ) -> Result, ExecutorError> { + let mut transactions: Vec = vec![]; + let blocks_txs = sealed_block.entity.transactions_vec(); + for tx_item in blocks_txs.iter() { + let tx_id = tx_item.id(&metadata.chain_id); + let receipts = fuel_core.get_receipts(&tx_id)?.unwrap_or_default(); + let tx_status = fuel_core.get_tx_status(&tx_id)?; + let tx_status: TransactionStatus = match tx_status { + Some(status) => (&status).into(), + _ => TransactionStatus::None, + }; + let new_transaction = Transaction::new( + &tx_id.into(), + tx_item, + &tx_status, + &metadata.base_asset_id, + &receipts, + ); + transactions.push(new_transaction); + } + Ok(transactions) + } +} + +impl TryFrom for Publish { + type Error = ExecutorError; + fn try_from(payload: BlockPayload) -> Result { + let message_id = payload.message_id(); + Ok(Publish::build() + .message_id(message_id) + .payload(payload.encode()?.into())) + } +} + +pub struct Executor { + pub stream: Arc>, + payload: Arc, + __marker: PhantomData, +} + +impl Executor { + pub fn new(payload: &Arc, stream: &Arc>) -> Self { + Self { + payload: payload.to_owned(), + stream: stream.to_owned(), + __marker: PhantomData, + } + } + + fn publish( + &self, + packet: &PublishPacket, + // _opts: &Arc, + ) -> JoinHandle> { + let payload = Arc::clone(&packet.payload); + let subject = Arc::clone(&packet.subject); + let wildcard = packet.subject.parse(); + let stream = Arc::clone(&self.stream); + let max_threads = *PUBLISHER_MAX_THREADS; + let semaphore = Arc::new(tokio::sync::Semaphore::new(max_threads)); + let permit = Arc::clone(&semaphore); + + // TODO: add telemetry back again + tokio::spawn(async move { + let _permit = permit.acquire().await?; + match stream.publish(&*subject, &payload).await { + Ok(_) => { + tracing::info!( + "Successfully published for stream: {wildcard}" + ); + Ok(()) + } + Err(e) => Err(ExecutorError::PublishFailed(e.to_string())), + } + }) + } + + pub fn payload(&self) -> Arc { + Arc::clone(&self.payload) + } + pub fn metadata(&self) -> &Metadata { + &self.payload.metadata + } + pub fn block(&self) -> &Block { + &self.payload.block + } + pub fn block_height(&self) -> BlockHeight { + let height = self.block().height; + BlockHeight::from(height) + } +} diff --git a/crates/fuel-streams-executors/src/logs.rs b/crates/fuel-streams-executors/src/logs.rs new file mode 100644 index 00000000..f4ac0308 --- /dev/null +++ b/crates/fuel-streams-executors/src/logs.rs @@ -0,0 +1,38 @@ +use fuel_streams_core::prelude::*; +use rayon::prelude::*; +use tokio::task::JoinHandle; + +use crate::*; + +impl Executor { + pub fn process( + &self, + tx: &Transaction, + ) -> Vec>> { + let block_height = self.block_height(); + let tx_id = tx.id.clone(); + let receipts = tx.receipts.clone(); + let packets = receipts + .par_iter() + .enumerate() + .filter_map(|(index, receipt)| match receipt { + Receipt::Log(LogReceipt { id, .. }) + | Receipt::LogData(LogDataReceipt { id, .. }) => { + Some(PublishPacket::new( + receipt.to_owned().into(), + LogsSubject { + block_height: Some(block_height.clone()), + tx_id: Some(tx_id.to_owned()), + receipt_index: Some(index), + log_id: Some(id.into()), + } + .arc(), + )) + } + _ => None, + }) + .collect::>(); + + packets.iter().map(|packet| self.publish(packet)).collect() + } +} diff --git a/crates/fuel-streams-executors/src/outputs.rs b/crates/fuel-streams-executors/src/outputs.rs new file mode 100644 index 00000000..48e9baa8 --- /dev/null +++ b/crates/fuel-streams-executors/src/outputs.rs @@ -0,0 +1,155 @@ +use std::sync::Arc; + +use fuel_streams_core::prelude::*; +use rayon::prelude::*; +use tokio::task::JoinHandle; + +use crate::*; + +impl Executor { + pub fn process( + &self, + tx: &Transaction, + ) -> Vec>> { + let tx_id = tx.id.clone(); + let packets: Vec> = tx + .outputs + .par_iter() + .enumerate() + .flat_map(|(index, output)| { + let main_subject = main_subject(output, tx, &tx_id, index); + let identifier_subjects = + identifiers(output, tx, &tx_id, index as u8) + .into_par_iter() + .map(|identifier| identifier.into()) + .map(|subject: OutputsByIdSubject| subject.arc()) + .collect::>(); + + let mut packets = vec![output.to_packet(main_subject)]; + packets.extend( + identifier_subjects + .into_iter() + .map(|subject| output.to_packet(subject)), + ); + + packets + }) + .collect(); + + packets.iter().map(|packet| self.publish(packet)).collect() + } +} + +fn main_subject( + output: &Output, + transaction: &Transaction, + tx_id: &Bytes32, + index: usize, +) -> Arc { + match output { + Output::Coin(OutputCoin { to, asset_id, .. }) => OutputsCoinSubject { + tx_id: Some(tx_id.to_owned()), + index: Some(index as u16), + to: Some(to.to_owned()), + asset_id: Some(asset_id.to_owned()), + } + .arc(), + Output::Contract(contract) => { + let contract_id = + match find_output_contract_id(transaction, contract) { + Some(contract_id) => contract_id, + None => { + tracing::warn!( + "Contract ID not found for output: {:?}", + output + ); + + Default::default() + } + }; + + OutputsContractSubject { + tx_id: Some(tx_id.to_owned()), + index: Some(index as u16), + contract_id: Some(contract_id), + } + .arc() + } + Output::Change(OutputChange { to, asset_id, .. }) => { + OutputsChangeSubject { + tx_id: Some(tx_id.to_owned()), + index: Some(index as u16), + to: Some(to.to_owned()), + asset_id: Some(asset_id.to_owned()), + } + .arc() + } + Output::Variable(OutputVariable { to, asset_id, .. }) => { + OutputsVariableSubject { + tx_id: Some(tx_id.to_owned()), + index: Some(index as u16), + to: Some(to.to_owned()), + asset_id: Some(asset_id.to_owned()), + } + .arc() + } + Output::ContractCreated(OutputContractCreated { + contract_id, .. + }) => OutputsContractCreatedSubject { + tx_id: Some(tx_id.to_owned()), + index: Some(index as u16), + contract_id: Some(contract_id.to_owned()), + } + .arc(), + } +} + +pub fn identifiers( + output: &Output, + tx: &Transaction, + tx_id: &Bytes32, + index: u8, +) -> Vec { + match output { + Output::Change(OutputChange { to, asset_id, .. }) + | Output::Variable(OutputVariable { to, asset_id, .. }) + | Output::Coin(OutputCoin { to, asset_id, .. }) => { + vec![ + Identifier::Address(tx_id.to_owned(), index, to.into()), + Identifier::AssetID(tx_id.to_owned(), index, asset_id.into()), + ] + } + Output::Contract(contract) => find_output_contract_id(tx, contract) + .map(|contract_id| { + vec![Identifier::ContractID( + tx_id.to_owned(), + index, + contract_id.into(), + )] + }) + .unwrap_or_default(), + Output::ContractCreated(OutputContractCreated { + contract_id, .. + }) => { + vec![Identifier::ContractID( + tx_id.to_owned(), + index, + contract_id.into(), + )] + } + } +} + +pub fn find_output_contract_id( + tx: &Transaction, + contract: &OutputContract, +) -> Option { + let input_index = contract.input_index as usize; + tx.inputs.get(input_index).and_then(|input| { + if let Input::Contract(input_contract) = input { + Some(input_contract.contract_id.to_owned().into()) + } else { + None + } + }) +} diff --git a/crates/fuel-streams-executors/src/receipts.rs b/crates/fuel-streams-executors/src/receipts.rs new file mode 100644 index 00000000..c99f03fc --- /dev/null +++ b/crates/fuel-streams-executors/src/receipts.rs @@ -0,0 +1,238 @@ +use std::sync::Arc; + +use fuel_streams_core::prelude::*; +use rayon::prelude::*; +use tokio::task::JoinHandle; + +use crate::*; + +impl Executor { + pub fn process( + &self, + tx: &Transaction, + ) -> Vec>> { + let tx_id = tx.id.clone(); + let receipts = tx.receipts.clone(); + let packets: Vec> = receipts + .par_iter() + .enumerate() + .flat_map(|(index, receipt)| { + let main_subject = main_subject(receipt, &tx_id, index); + let identifier_subjects = + identifiers(receipt, &tx_id, index as u8) + .into_par_iter() + .map(|identifier| identifier.into()) + .map(|subject: ReceiptsByIdSubject| subject.arc()) + .collect::>(); + + let receipt: Receipt = receipt.to_owned(); + let mut packets = vec![receipt.to_packet(main_subject)]; + packets.extend( + identifier_subjects + .into_iter() + .map(|subject| receipt.to_packet(subject)), + ); + + packets + }) + .collect(); + + packets.iter().map(|packet| self.publish(packet)).collect() + } +} + +fn main_subject( + receipt: &Receipt, + tx_id: &Bytes32, + index: usize, +) -> Arc { + match receipt { + Receipt::Call(CallReceipt { + id: from, + to, + asset_id, + .. + }) => ReceiptsCallSubject { + tx_id: Some(tx_id.to_owned()), + index: Some(index), + from: Some(from.to_owned()), + to: Some(to.to_owned()), + asset_id: Some(asset_id.to_owned()), + } + .arc(), + Receipt::Return(ReturnReceipt { id, .. }) => ReceiptsReturnSubject { + tx_id: Some(tx_id.to_owned()), + index: Some(index), + id: Some(id.to_owned()), + } + .arc(), + Receipt::ReturnData(ReturnDataReceipt { id, .. }) => { + ReceiptsReturnDataSubject { + tx_id: Some(tx_id.to_owned()), + index: Some(index), + id: Some(id.to_owned()), + } + .arc() + } + Receipt::Panic(PanicReceipt { id, .. }) => ReceiptsPanicSubject { + tx_id: Some(tx_id.to_owned()), + index: Some(index), + id: Some(id.to_owned()), + } + .arc(), + Receipt::Revert(RevertReceipt { id, .. }) => ReceiptsRevertSubject { + tx_id: Some(tx_id.to_owned()), + index: Some(index), + id: Some(id.to_owned()), + } + .arc(), + Receipt::Log(LogReceipt { id, .. }) => ReceiptsLogSubject { + tx_id: Some(tx_id.to_owned()), + index: Some(index), + id: Some(id.to_owned()), + } + .arc(), + Receipt::LogData(LogDataReceipt { id, .. }) => ReceiptsLogDataSubject { + tx_id: Some(tx_id.to_owned()), + index: Some(index), + id: Some(id.to_owned()), + } + .arc(), + Receipt::Transfer(TransferReceipt { + id: from, + to, + asset_id, + .. + }) => ReceiptsTransferSubject { + tx_id: Some(tx_id.to_owned()), + index: Some(index), + from: Some(from.to_owned()), + to: Some(to.to_owned()), + asset_id: Some(asset_id.to_owned()), + } + .arc(), + + Receipt::TransferOut(TransferOutReceipt { + id: from, + to, + asset_id, + .. + }) => ReceiptsTransferOutSubject { + tx_id: Some(tx_id.to_owned()), + index: Some(index), + from: Some(from.to_owned()), + to: Some(to.to_owned()), + asset_id: Some(asset_id.to_owned()), + } + .arc(), + + Receipt::ScriptResult(ScriptResultReceipt { .. }) => { + ReceiptsScriptResultSubject { + tx_id: Some(tx_id.to_owned()), + index: Some(index), + } + .arc() + } + Receipt::MessageOut(MessageOutReceipt { + sender, recipient, .. + }) => ReceiptsMessageOutSubject { + tx_id: Some(tx_id.to_owned()), + index: Some(index), + sender: Some(sender.to_owned()), + recipient: Some(recipient.to_owned()), + } + .arc(), + Receipt::Mint(MintReceipt { + contract_id, + sub_id, + .. + }) => ReceiptsMintSubject { + tx_id: Some(tx_id.to_owned()), + index: Some(index), + contract_id: Some(contract_id.to_owned()), + sub_id: Some((*sub_id).to_owned()), + } + .arc(), + Receipt::Burn(BurnReceipt { + contract_id, + sub_id, + .. + }) => ReceiptsBurnSubject { + tx_id: Some(tx_id.to_owned()), + index: Some(index), + contract_id: Some(contract_id.to_owned()), + sub_id: Some((*sub_id).to_owned()), + } + .arc(), + } +} + +pub fn identifiers( + receipt: &Receipt, + tx_id: &Bytes32, + index: u8, +) -> Vec { + match receipt { + Receipt::Call(CallReceipt { + id: from, + to, + asset_id, + .. + }) => { + vec![ + Identifier::ContractID(tx_id.to_owned(), index, from.into()), + Identifier::ContractID(tx_id.to_owned(), index, to.into()), + Identifier::AssetID(tx_id.to_owned(), index, asset_id.into()), + ] + } + Receipt::Return(ReturnReceipt { id, .. }) + | Receipt::ReturnData(ReturnDataReceipt { id, .. }) + | Receipt::Panic(PanicReceipt { id, .. }) + | Receipt::Revert(RevertReceipt { id, .. }) + | Receipt::Log(LogReceipt { id, .. }) + | Receipt::LogData(LogDataReceipt { id, .. }) => { + vec![Identifier::ContractID(tx_id.to_owned(), index, id.into())] + } + Receipt::Transfer(TransferReceipt { + id: from, + to, + asset_id, + .. + }) => { + vec![ + Identifier::ContractID(tx_id.to_owned(), index, from.into()), + Identifier::ContractID(tx_id.to_owned(), index, to.into()), + Identifier::AssetID(tx_id.to_owned(), index, asset_id.into()), + ] + } + Receipt::TransferOut(TransferOutReceipt { + id: from, + to, + asset_id, + .. + }) => { + vec![ + Identifier::ContractID(tx_id.to_owned(), index, from.into()), + Identifier::ContractID(tx_id.to_owned(), index, to.into()), + Identifier::AssetID(tx_id.to_owned(), index, asset_id.into()), + ] + } + Receipt::MessageOut(MessageOutReceipt { + sender, recipient, .. + }) => { + vec![ + Identifier::Address(tx_id.to_owned(), index, sender.into()), + Identifier::Address(tx_id.to_owned(), index, recipient.into()), + ] + } + Receipt::Mint(MintReceipt { contract_id, .. }) + | Receipt::Burn(BurnReceipt { contract_id, .. }) => { + vec![Identifier::ContractID( + tx_id.to_owned(), + index, + contract_id.into(), + )] + } + _ => Vec::new(), + } +} diff --git a/crates/fuel-streams-executors/src/transactions.rs b/crates/fuel-streams-executors/src/transactions.rs new file mode 100644 index 00000000..76c42f28 --- /dev/null +++ b/crates/fuel-streams-executors/src/transactions.rs @@ -0,0 +1,100 @@ +use fuel_streams_core::prelude::*; +use rayon::prelude::*; +use tokio::task::JoinHandle; + +use crate::*; + +impl Executor { + pub fn process( + &self, + tx_item: (usize, &Transaction), + ) -> Vec>> { + let block_height = self.block_height(); + packets_from_tx(tx_item, &block_height) + .iter() + .map(|packet| self.publish(packet)) + .collect() + } +} + +fn packets_from_tx( + (index, tx): (usize, &Transaction), + block_height: &BlockHeight, +) -> Vec> { + let tx_id = tx.id.clone(); + let tx_status = tx.status.clone(); + let receipts = tx.receipts.clone(); + let main_subject = TransactionsSubject { + block_height: Some(block_height.to_owned()), + index: Some(index), + tx_id: Some(tx_id.to_owned()), + status: Some(tx_status.to_owned()), + kind: Some(tx.kind.to_owned()), + } + .arc(); + + let mut packets = vec![tx.to_packet(main_subject)]; + packets.extend( + identifiers(tx, &tx.kind, &tx_id, index as u8) + .into_par_iter() + .map(|identifier| identifier.into()) + .map(|subject: TransactionsByIdSubject| subject.arc()) + .map(|subject| tx.to_packet(subject)) + .collect::>(), + ); + + let packets_from_inputs: Vec> = tx + .inputs + .par_iter() + .flat_map(|input| { + inputs::identifiers(input, &tx_id, index as u8) + .into_par_iter() + .map(|identifier| identifier.into()) + .map(|subject: TransactionsByIdSubject| subject.arc()) + .map(|subject| tx.to_packet(subject)) + }) + .collect(); + packets.extend(packets_from_inputs); + + let packets_from_outputs: Vec> = tx + .outputs + .par_iter() + .flat_map(|output| { + outputs::identifiers(output, tx, &tx_id, index as u8) + .into_par_iter() + .map(|identifier| identifier.into()) + .map(|subject: TransactionsByIdSubject| subject.arc()) + .map(|subject| tx.to_packet(subject)) + }) + .collect(); + packets.extend(packets_from_outputs); + + let packets_from_receipts: Vec> = receipts + .par_iter() + .flat_map(|receipt| { + receipts::identifiers(receipt, &tx_id, index as u8) + .into_par_iter() + .map(|identifier| identifier.into()) + .map(|subject: TransactionsByIdSubject| subject.arc()) + .map(|subject| tx.to_packet(subject)) + }) + .collect(); + packets.extend(packets_from_receipts); + packets +} + +fn identifiers( + tx: &Transaction, + kind: &TransactionKind, + tx_id: &Bytes32, + index: u8, +) -> Vec { + match kind { + TransactionKind::Script => { + let script_data = &tx.script_data.to_owned().unwrap_or_default().0; + let script_tag = sha256(script_data); + vec![Identifier::ScriptID(tx_id.to_owned(), index, script_tag)] + } + _ => Vec::new(), + } +} diff --git a/crates/fuel-streams-executors/src/utxos.rs b/crates/fuel-streams-executors/src/utxos.rs new file mode 100644 index 00000000..81fdaaf2 --- /dev/null +++ b/crates/fuel-streams-executors/src/utxos.rs @@ -0,0 +1,85 @@ +use fuel_streams_core::prelude::*; +use rayon::prelude::*; +use tokio::task::JoinHandle; + +use crate::*; + +impl Executor { + pub fn process( + &self, + tx: &Transaction, + ) -> Vec>> { + let tx_id = tx.id.clone(); + let packets = tx + .inputs + .par_iter() + .filter_map(|input| utxo_packet(input, &tx_id)) + .collect::>(); + + packets + .into_iter() + .map(|packet| self.publish(&packet)) + .collect() + } +} + +fn utxo_packet(input: &Input, tx_id: &Bytes32) -> Option> { + match input { + Input::Contract(InputContract { utxo_id, .. }) => { + let utxo = Utxo { + utxo_id: utxo_id.to_owned(), + tx_id: tx_id.to_owned(), + ..Default::default() + }; + let subject = UtxosSubject { + utxo_type: Some(UtxoType::Contract), + utxo_id: Some(utxo_id.into()), + } + .arc(); + Some(utxo.to_packet(subject)) + } + Input::Coin(InputCoin { + utxo_id, amount, .. + }) => { + let utxo = Utxo { + utxo_id: utxo_id.to_owned(), + amount: Some(*amount), + tx_id: tx_id.to_owned(), + ..Default::default() + }; + let subject = UtxosSubject { + utxo_type: Some(UtxoType::Coin), + utxo_id: Some(utxo_id.into()), + } + .arc(); + Some(utxo.to_packet(subject)) + } + Input::Message( + input @ InputMessage { + amount, + nonce, + recipient, + sender, + data, + .. + }, + ) => { + let utxo_id = input.computed_utxo_id(); + let utxo = Utxo { + tx_id: tx_id.to_owned(), + utxo_id: utxo_id.to_owned(), + sender: Some(sender.to_owned()), + recipient: Some(recipient.to_owned()), + nonce: Some(nonce.to_owned()), + amount: Some(*amount), + data: Some(data.to_owned()), + }; + let subject = UtxosSubject { + utxo_type: Some(UtxoType::Message), + utxo_id: None, + } + .arc(); + Some(utxo.to_packet(subject)) + } + } +} diff --git a/crates/fuel-streams-publisher/Cargo.toml b/crates/fuel-streams-publisher/Cargo.toml index 3982fc93..6466a81e 100644 --- a/crates/fuel-streams-publisher/Cargo.toml +++ b/crates/fuel-streams-publisher/Cargo.toml @@ -24,25 +24,28 @@ derive_more = { version = "1.0", features = ["full"] } displaydoc = { workspace = true } dotenvy = { workspace = true } elasticsearch = "8.15.0-alpha.1" -fuel-core = { workspace = true } -fuel-core-bin = { workspace = true } -fuel-core-importer = { workspace = true } -fuel-core-services = { workspace = true } -fuel-core-storage = { workspace = true } -fuel-core-types = { workspace = true } -fuel-streams = { workspace = true, features = ["test-helpers"] } +fuel-core = { workspace = true, default-features = false, features = [ + "p2p", + "relayer", + "rocksdb", + "test-helpers", +] } +fuel-core-bin = { workspace = true, default-features = false, features = [ + "p2p", + "relayer", + "rocksdb", +] } +fuel-core-services = { workspace = true, default-features = false, features = ["test-helpers"] } fuel-streams-core = { workspace = true, features = ["test-helpers"] } +fuel-streams-executors = { workspace = true, features = ["test-helpers"] } futures = { workspace = true } -num_cpus = "1.16" parking_lot = { version = "0.12", features = ["serde"] } prometheus = { version = "0.13", features = ["process"] } rand = { workspace = true } -rayon = "1.10.0" rust_decimal = { version = "1.13" } serde = { workspace = true } serde_json = { workspace = true } serde_prometheus = { version = "0.2" } -sha2 = { workspace = true } sysinfo = { version = "0.29" } thiserror = "2.0" tokio = { workspace = true } diff --git a/crates/fuel-streams-publisher/src/lib.rs b/crates/fuel-streams-publisher/src/lib.rs index dbbb3cc0..e2ba33f7 100644 --- a/crates/fuel-streams-publisher/src/lib.rs +++ b/crates/fuel-streams-publisher/src/lib.rs @@ -2,21 +2,8 @@ pub mod cli; pub mod publisher; pub mod server; pub mod telemetry; - -use std::{env, sync::LazyLock}; - pub use publisher::*; -pub static PUBLISHER_MAX_THREADS: LazyLock = LazyLock::new(|| { - let available_cpus = num_cpus::get(); - let default_threads = (available_cpus / 3).max(1); // Use 1/3 of CPUs, minimum 1 - - env::var("PUBLISHER_MAX_THREADS") - .ok() - .and_then(|val| val.parse().ok()) - .unwrap_or(default_threads) -}); - #[cfg(test)] #[macro_use] extern crate assert_matches; diff --git a/crates/fuel-streams-publisher/src/main.rs b/crates/fuel-streams-publisher/src/main.rs index db5c5366..b78b40be 100644 --- a/crates/fuel-streams-publisher/src/main.rs +++ b/crates/fuel-streams-publisher/src/main.rs @@ -4,13 +4,12 @@ use std::{ }; use clap::Parser; +use fuel_streams_core::prelude::*; use fuel_streams_publisher::{ cli::Cli, publisher::shutdown::ShutdownController, server::{http::create_web_server, state::ServerState}, telemetry::Telemetry, - FuelCore, - FuelCoreLike, }; #[tokio::main] diff --git a/crates/fuel-streams-publisher/src/publisher/blocks_streams.rs b/crates/fuel-streams-publisher/src/publisher/blocks_streams.rs index a40c0e00..eb222cd2 100644 --- a/crates/fuel-streams-publisher/src/publisher/blocks_streams.rs +++ b/crates/fuel-streams-publisher/src/publisher/blocks_streams.rs @@ -8,12 +8,10 @@ use futures::{ }; use tokio_stream::wrappers::BroadcastStream; -use crate::{fuel_core_like::FuelCoreLike, fuel_streams::FuelStreamsExt}; - pub fn build_blocks_stream<'a>( fuel_streams: &'a Arc, fuel_core: &'a Arc, - max_retained_blocks: u64, + max_retained_blocks: u32, ) -> BoxStream<'a, anyhow::Result> { #[derive(Debug, Default, Clone)] struct State { @@ -51,7 +49,7 @@ pub fn build_blocks_stream<'a>( let fuel_core = fuel_core.clone(); move |height| { - fuel_core.get_sealed_block_by_height(height as u32) + fuel_core.get_sealed_block_by_height(height) } }) .map(Ok) @@ -90,17 +88,17 @@ pub fn build_blocks_stream<'a>( async fn get_last_published_block_height( fuel_streams: Arc, - latest_block_height: u64, - max_retained_blocks: u64, -) -> anyhow::Result { + latest_block_height: u32, + max_retained_blocks: u32, +) -> anyhow::Result { let max_last_published_block_height = - max(0, latest_block_height as i64 - max_retained_blocks as i64) as u64; + max(0, latest_block_height as i32 - max_retained_blocks as i32) as u32; Ok(fuel_streams .get_last_published_block() .await? - .map(|block| block.height.into()) - .map(|block_height: u64| { + .map(|block| block.height) + .map(|block_height: u32| { max(block_height, max_last_published_block_height) }) .unwrap_or(max_last_published_block_height)) @@ -322,13 +320,14 @@ mod tests { #[async_trait::async_trait] impl FuelCoreLike for FuelCoreLike { - fn get_latest_block_height(&self) -> anyhow::Result; + fn get_latest_block_height(&self) -> anyhow::Result; fn get_sealed_block_by_height(&self, height: u32) -> FuelCoreSealedBlock; fn blocks_subscription(&self) -> broadcast::Receiver; async fn start(&self) -> anyhow::Result<()>; fn is_started(&self) -> bool; async fn await_synced_at_least_once(&self, historical: bool) -> anyhow::Result<()>; async fn stop(&self); + fn fuel_service(&self) -> &fuel_core_bin::FuelService; fn base_asset_id(&self) -> &FuelCoreAssetId; fn chain_id(&self) -> &FuelCoreChainId; fn database(&self) -> &CombinedDatabase; @@ -340,6 +339,10 @@ mod tests { &self, tx_id: &FuelCoreBytes32, ) -> anyhow::Result>>; + fn get_tx_status( + &self, + tx_id: &FuelCoreBytes32, + ) -> anyhow::Result>; } } diff --git a/crates/fuel-streams-publisher/src/publisher/mod.rs b/crates/fuel-streams-publisher/src/publisher/mod.rs index 4a7df81f..6851b301 100644 --- a/crates/fuel-streams-publisher/src/publisher/mod.rs +++ b/crates/fuel-streams-publisher/src/publisher/mod.rs @@ -1,6 +1,3 @@ -pub mod fuel_core_like; -pub mod fuel_streams; -pub mod payloads; pub mod shutdown; mod blocks_streams; @@ -9,17 +6,13 @@ use std::sync::Arc; use anyhow::Context; use blocks_streams::build_blocks_stream; -pub use fuel_core_like::{FuelCore, FuelCoreLike}; -pub use fuel_streams::{FuelStreams, FuelStreamsExt}; use fuel_streams_core::prelude::*; -use futures::{future::try_join_all, stream::FuturesUnordered, StreamExt}; -use tokio::sync::Semaphore; +use fuel_streams_executors::*; +use futures::StreamExt; use super::{ - payloads::blocks, shutdown::{ShutdownToken, GRACEFUL_SHUTDOWN_TIMEOUT}, telemetry::Telemetry, - PUBLISHER_MAX_THREADS, }; #[derive(Clone)] @@ -99,7 +92,7 @@ impl Publisher { } } - const MAX_RETAINED_BLOCKS: u64 = 100; + const MAX_RETAINED_BLOCKS: u32 = 100; pub async fn run( &self, shutdown_token: ShutdownToken, @@ -112,7 +105,6 @@ impl Publisher { .await?; tracing::info!("FuelCore has synced successfully!"); - tracing::info!("Publishing started..."); let mut blocks_stream = build_blocks_stream( @@ -130,7 +122,7 @@ impl Publisher { let fuel_core = &self.fuel_core; let (block, block_producer) = - fuel_core.get_block_and_producer(sealed_block); + fuel_core.get_block_and_producer(sealed_block.to_owned()); // TODO: Avoid awaiting Offchain DB sync for all streams by grouping in their own service fuel_core @@ -138,7 +130,7 @@ impl Publisher { .await .context("Failed to await Offchain DB sync")?; - if let Err(err) = self.publish(&block, &block_producer).await { + if let Err(err) = self.publish(sealed_block).await { tracing::error!("Failed to publish block data: {}", err); self.telemetry.record_failed_publishing(self.fuel_core.chain_id(), &block_producer); } @@ -155,131 +147,20 @@ impl Publisher { } tracing::info!("Publishing stopped successfully!"); - Ok(()) } async fn publish( &self, - block: &FuelCoreBlock, - block_producer: &Address, + sealed_block: FuelCoreSealedBlock, ) -> anyhow::Result<()> { - let start_time = std::time::Instant::now(); - - let semaphore = Arc::new(Semaphore::new(*PUBLISHER_MAX_THREADS)); - let chain_id = Arc::new(*self.fuel_core.chain_id()); - let base_asset_id = Arc::new(*self.fuel_core.base_asset_id()); - let block_producer = Arc::new(block_producer.clone()); - let block_height = block.header().consensus().height; - let txs = block.transactions(); - let transaction_ids = txs - .iter() - .map(|tx| tx.id(&chain_id).into()) - .collect::>(); - - let consensus: Consensus = - self.fuel_core.get_consensus(&block_height)?.into(); - - let fuel_core = &*self.fuel_core; - let offchain_database = fuel_core.offchain_database()?; - - let fuel_streams = &*self.fuel_streams; - let blocks_stream = Arc::new(fuel_streams.blocks().to_owned()); - let opts = &Arc::new(PublishOpts { - semaphore, - chain_id, - base_asset_id, - block_producer: Arc::clone(&block_producer), - block_height: Arc::new(block_height.into()), - telemetry: self.telemetry.clone(), - consensus: Arc::new(consensus), - offchain_database, - }); - - let publish_tasks = payloads::transactions::publish_all_tasks( - txs, - fuel_streams, - opts, - fuel_core, - )? - .into_iter() - .chain(std::iter::once(blocks::publish_task( - block, - blocks_stream, - opts, - transaction_ids, - ))) - .collect::>(); - - try_join_all(publish_tasks).await?; - - let elapsed = start_time.elapsed(); - tracing::info!( - "Published streams for BlockHeight: {} in {:?}", - *block_height, - elapsed - ); - + let metadata = Metadata::new(&self.fuel_core, &sealed_block); + let payload = Arc::new(BlockPayload::new( + Arc::clone(&self.fuel_core), + &sealed_block, + &metadata, + )?); + Executor::::process_all(payload, &self.fuel_streams).await?; Ok(()) } } - -use tokio::task::JoinHandle; - -use crate::fuel_core_like::OffchainDatabase; - -#[derive(Clone)] -pub struct PublishOpts { - pub semaphore: Arc, - pub chain_id: Arc, - pub base_asset_id: Arc, - pub block_producer: Arc
, - pub block_height: Arc, - pub telemetry: Arc, - pub consensus: Arc, - pub offchain_database: Arc, -} - -pub fn publish( - packet: &PublishPacket, - stream: Arc>, - opts: &Arc, -) -> JoinHandle> { - let opts = Arc::clone(opts); - let payload = Arc::clone(&packet.payload); - let subject = Arc::clone(&packet.subject); - let telemetry = Arc::clone(&opts.telemetry); - let wildcard = packet.subject.wildcard(); - - tokio::spawn(async move { - let _permit = opts.semaphore.acquire().await?; - - match stream.publish(&*subject, &payload).await { - Ok(published_data_size) => { - telemetry.log_info(&format!( - "Successfully published for stream: {}", - wildcard - )); - telemetry.update_publisher_success_metrics( - wildcard, - published_data_size, - &opts.chain_id, - &opts.block_producer, - ); - - Ok(()) - } - Err(e) => { - telemetry.log_error(&e.to_string()); - telemetry.update_publisher_error_metrics( - wildcard, - &opts.chain_id, - &opts.block_producer, - &e.to_string(), - ); - - anyhow::bail!("Failed to publish: {}", e.to_string()) - } - } - }) -} diff --git a/crates/fuel-streams-publisher/src/publisher/payloads/blocks.rs b/crates/fuel-streams-publisher/src/publisher/payloads/blocks.rs deleted file mode 100644 index 5e59f728..00000000 --- a/crates/fuel-streams-publisher/src/publisher/payloads/blocks.rs +++ /dev/null @@ -1,29 +0,0 @@ -use std::sync::Arc; - -use fuel_streams_core::prelude::*; -use tokio::task::JoinHandle; - -use crate::{publish, PublishOpts}; - -pub fn publish_task( - block: &FuelCoreBlock, - stream: Arc>, - opts: &Arc, - transaction_ids: Vec, -) -> JoinHandle> { - let block_height = (*opts.block_height).clone(); - let block_producer = (*opts.block_producer).clone(); - let consensus = (*opts.consensus).clone(); - - let block = Block::new(block, consensus, transaction_ids); - let packet = PublishPacket::new( - block, - BlocksSubject { - height: Some(block_height), - producer: Some(block_producer), - } - .arc(), - ); - - publish(&packet, stream, opts) -} diff --git a/crates/fuel-streams-publisher/src/publisher/payloads/inputs.rs b/crates/fuel-streams-publisher/src/publisher/payloads/inputs.rs deleted file mode 100644 index 88048d54..00000000 --- a/crates/fuel-streams-publisher/src/publisher/payloads/inputs.rs +++ /dev/null @@ -1,178 +0,0 @@ -use std::sync::Arc; - -use fuel_core_types::fuel_tx::input::{ - coin::{CoinPredicate, CoinSigned}, - message::{ - MessageCoinPredicate, - MessageCoinSigned, - MessageDataPredicate, - MessageDataSigned, - }, -}; -use fuel_streams_core::prelude::*; -use rayon::prelude::*; -use tokio::task::JoinHandle; - -use crate::{publish, PublishOpts}; - -pub fn publish_tasks( - tx: &FuelCoreTransaction, - tx_id: &Bytes32, - stream: &Stream, - opts: &Arc, -) -> Vec>> { - let packets = tx - .inputs() - .par_iter() - .enumerate() - .flat_map(move |(index, input)| { - let main_subject = main_subject(input, tx_id.clone(), index); - let identifier_subjects = identifiers(input, tx_id, index as u8) - .into_par_iter() - .map(|identifier| identifier.into()) - .map(|subject: InputsByIdSubject| subject.arc()) - .collect::>(); - - let input: Input = input.into(); - - let mut packets = vec![input.to_packet(main_subject)]; - packets.extend( - identifier_subjects - .into_iter() - .map(|subject| input.to_packet(subject)), - ); - - packets - }) - .collect::>(); - - packets - .iter() - .map(|packet| publish(packet, Arc::new(stream.to_owned()), opts)) - .collect() -} - -fn main_subject( - input: &FuelCoreInput, - tx_id: Bytes32, - index: usize, -) -> Arc { - match input { - FuelCoreInput::Contract(contract) => { - let contract_id = contract.contract_id; - - InputsContractSubject { - tx_id: Some(tx_id), - index: Some(index), - contract_id: Some(contract_id.into()), - } - .arc() - } - FuelCoreInput::CoinSigned(CoinSigned { - owner, asset_id, .. - }) - | FuelCoreInput::CoinPredicate(CoinPredicate { - owner, asset_id, .. - }) => InputsCoinSubject { - tx_id: Some(tx_id), - index: Some(index), - owner: Some(owner.into()), - asset_id: Some(asset_id.into()), - } - .arc(), - FuelCoreInput::MessageCoinSigned(MessageCoinSigned { - sender, - recipient, - .. - }) - | FuelCoreInput::MessageCoinPredicate(MessageCoinPredicate { - sender, - recipient, - .. - }) - | FuelCoreInput::MessageDataSigned(MessageDataSigned { - sender, - recipient, - .. - }) - | FuelCoreInput::MessageDataPredicate(MessageDataPredicate { - sender, - recipient, - .. - }) => InputsMessageSubject { - tx_id: Some(tx_id), - index: Some(index), - sender: Some(sender.into()), - recipient: Some(recipient.into()), - } - .arc(), - } -} - -pub fn identifiers( - input: &FuelCoreInput, - tx_id: &Bytes32, - index: u8, -) -> Vec { - let mut identifiers = match input { - FuelCoreInput::CoinSigned(CoinSigned { - owner, asset_id, .. - }) => { - vec![ - Identifier::Address(tx_id.to_owned(), index, owner.into()), - Identifier::AssetID(tx_id.to_owned(), index, asset_id.into()), - ] - } - FuelCoreInput::CoinPredicate(CoinPredicate { - owner, asset_id, .. - }) => { - vec![ - Identifier::Address(tx_id.to_owned(), index, owner.into()), - Identifier::AssetID(tx_id.to_owned(), index, asset_id.into()), - ] - } - FuelCoreInput::MessageCoinSigned(MessageCoinSigned { - sender, - recipient, - .. - }) - | FuelCoreInput::MessageCoinPredicate(MessageCoinPredicate { - sender, - recipient, - .. - }) - | FuelCoreInput::MessageDataSigned(MessageDataSigned { - sender, - recipient, - .. - }) - | FuelCoreInput::MessageDataPredicate(MessageDataPredicate { - sender, - recipient, - .. - }) => { - vec![ - Identifier::Address(tx_id.to_owned(), index, sender.into()), - Identifier::Address(tx_id.to_owned(), index, recipient.into()), - ] - } - FuelCoreInput::Contract(contract) => { - vec![Identifier::ContractID( - tx_id.to_owned(), - index, - contract.contract_id.into(), - )] - } - }; - - if let Some((predicate_bytecode, _, _)) = input.predicate() { - let predicate_tag = super::sha256(predicate_bytecode); - identifiers.push(Identifier::PredicateID( - tx_id.to_owned(), - index, - predicate_tag, - )); - } - - identifiers -} diff --git a/crates/fuel-streams-publisher/src/publisher/payloads/logs.rs b/crates/fuel-streams-publisher/src/publisher/payloads/logs.rs deleted file mode 100644 index d443c1fc..00000000 --- a/crates/fuel-streams-publisher/src/publisher/payloads/logs.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::sync::Arc; - -use fuel_streams_core::prelude::*; -use rayon::prelude::*; -use tokio::task::JoinHandle; - -use crate::{publish, PublishOpts}; - -pub fn publish_tasks( - tx_id: &Bytes32, - stream: &Stream, - opts: &Arc, - receipts: &Vec, -) -> Vec>> { - let block_height = (*opts.block_height).clone(); - let packets = receipts - .par_iter() - .enumerate() - .filter_map(|(index, receipt)| match receipt { - FuelCoreReceipt::Log { id, .. } - | FuelCoreReceipt::LogData { id, .. } => Some(PublishPacket::new( - receipt.to_owned().into(), - LogsSubject { - block_height: Some(block_height.clone()), - tx_id: Some(tx_id.to_owned()), - receipt_index: Some(index), - log_id: Some((*id).into()), - } - .arc(), - )), - _ => None, - }) - .collect::>(); - - packets - .iter() - .map(|packet| publish(packet, Arc::new(stream.to_owned()), opts)) - .collect() -} diff --git a/crates/fuel-streams-publisher/src/publisher/payloads/mod.rs b/crates/fuel-streams-publisher/src/publisher/payloads/mod.rs deleted file mode 100644 index ac0ce74a..00000000 --- a/crates/fuel-streams-publisher/src/publisher/payloads/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -pub mod blocks; -pub mod inputs; -pub mod logs; -pub mod outputs; -pub mod receipts; -pub mod transactions; -pub mod utxos; - -use fuel_streams_core::prelude::Bytes32; -use sha2::{Digest, Sha256}; - -pub fn sha256(bytes: &[u8]) -> Bytes32 { - let mut sha256 = Sha256::new(); - sha256.update(bytes); - let bytes: [u8; 32] = sha256 - .finalize() - .as_slice() - .try_into() - .expect("Must be 32 bytes"); - - bytes.into() -} diff --git a/crates/fuel-streams-publisher/src/publisher/payloads/outputs.rs b/crates/fuel-streams-publisher/src/publisher/payloads/outputs.rs deleted file mode 100644 index 0a61a974..00000000 --- a/crates/fuel-streams-publisher/src/publisher/payloads/outputs.rs +++ /dev/null @@ -1,161 +0,0 @@ -use std::sync::Arc; - -use fuel_streams_core::prelude::*; -use rayon::prelude::*; -use tokio::task::JoinHandle; - -use crate::{publish, PublishOpts}; - -pub fn publish_tasks( - tx: &FuelCoreTransaction, - tx_id: &Bytes32, - stream: &Stream, - opts: &Arc, -) -> Vec>> { - let packets: Vec> = tx - .outputs() - .par_iter() - .enumerate() - .flat_map(|(index, output)| { - let main_subject = main_subject(output, tx, tx_id, index); - let identifier_subjects = - identifiers(output, tx, tx_id, index as u8) - .into_par_iter() - .map(|identifier| identifier.into()) - .map(|subject: OutputsByIdSubject| subject.arc()) - .collect::>(); - - let output: Output = output.into(); - - let mut packets = vec![output.to_packet(main_subject)]; - packets.extend( - identifier_subjects - .into_iter() - .map(|subject| output.to_packet(subject)), - ); - - packets - }) - .collect(); - - packets - .iter() - .map(|packet| publish(packet, Arc::new(stream.to_owned()), opts)) - .collect() -} - -fn main_subject( - output: &FuelCoreOutput, - transaction: &FuelCoreTransaction, - tx_id: &Bytes32, - index: usize, -) -> Arc { - match output { - FuelCoreOutput::Coin { to, asset_id, .. } => OutputsCoinSubject { - tx_id: Some(tx_id.to_owned()), - index: Some(index as u16), - to: Some((*to).into()), - asset_id: Some((*asset_id).into()), - } - .arc(), - - FuelCoreOutput::Contract(contract) => { - let contract_id = - match find_output_contract_id(transaction, contract) { - Some(contract_id) => contract_id, - None => { - tracing::warn!( - "Contract ID not found for output: {:?}", - output - ); - - Default::default() - } - }; - - OutputsContractSubject { - tx_id: Some(tx_id.to_owned()), - index: Some(index as u16), - contract_id: Some(contract_id.into()), - } - .arc() - } - - FuelCoreOutput::Change { to, asset_id, .. } => OutputsChangeSubject { - tx_id: Some(tx_id.to_owned()), - index: Some(index as u16), - to: Some((*to).into()), - asset_id: Some((*asset_id).into()), - } - .arc(), - - FuelCoreOutput::Variable { to, asset_id, .. } => { - OutputsVariableSubject { - tx_id: Some(tx_id.to_owned()), - index: Some(index as u16), - to: Some((*to).into()), - asset_id: Some((*asset_id).into()), - } - .arc() - } - - FuelCoreOutput::ContractCreated { contract_id, .. } => { - OutputsContractCreatedSubject { - tx_id: Some(tx_id.to_owned()), - index: Some(index as u16), - contract_id: Some((*contract_id).into()), - } - .arc() - } - } -} - -pub fn identifiers( - output: &FuelCoreOutput, - tx: &FuelCoreTransaction, - tx_id: &Bytes32, - index: u8, -) -> Vec { - match output { - FuelCoreOutput::Change { to, asset_id, .. } - | FuelCoreOutput::Variable { to, asset_id, .. } - | FuelCoreOutput::Coin { to, asset_id, .. } => { - vec![ - Identifier::Address(tx_id.to_owned(), index, to.into()), - Identifier::AssetID(tx_id.to_owned(), index, asset_id.into()), - ] - } - FuelCoreOutput::Contract(contract) => { - find_output_contract_id(tx, contract) - .map(|contract_id| { - vec![Identifier::ContractID( - tx_id.to_owned(), - index, - contract_id.into(), - )] - }) - .unwrap_or_default() - } - FuelCoreOutput::ContractCreated { contract_id, .. } => { - vec![Identifier::ContractID( - tx_id.to_owned(), - index, - contract_id.into(), - )] - } - } -} - -pub fn find_output_contract_id( - tx: &FuelCoreTransaction, - contract: &FuelCoreOutputContract, -) -> Option { - let input_index = contract.input_index as usize; - tx.inputs().get(input_index).and_then(|input| { - if let FuelCoreInput::Contract(input_contract) = input { - Some(input_contract.contract_id) - } else { - None - } - }) -} diff --git a/crates/fuel-streams-publisher/src/publisher/payloads/receipts.rs b/crates/fuel-streams-publisher/src/publisher/payloads/receipts.rs deleted file mode 100644 index e0936f5f..00000000 --- a/crates/fuel-streams-publisher/src/publisher/payloads/receipts.rs +++ /dev/null @@ -1,235 +0,0 @@ -use std::sync::Arc; - -use fuel_streams_core::prelude::*; -use rayon::prelude::*; -use tokio::task::JoinHandle; - -use crate::{publish, PublishOpts}; - -pub fn publish_tasks( - tx_id: &Bytes32, - stream: &Stream, - opts: &Arc, - receipts: &Vec, -) -> Vec>> { - let packets: Vec> = receipts - .par_iter() - .enumerate() - .flat_map(|(index, receipt)| { - let main_subject = main_subject(receipt, tx_id, index); - let identifier_subjects = identifiers(receipt, tx_id, index as u8) - .into_par_iter() - .map(|identifier| identifier.into()) - .map(|subject: ReceiptsByIdSubject| subject.arc()) - .collect::>(); - - let receipt: Receipt = receipt.into(); - - let mut packets = vec![receipt.to_packet(main_subject)]; - packets.extend( - identifier_subjects - .into_iter() - .map(|subject| receipt.to_packet(subject)), - ); - - packets - }) - .collect(); - - packets - .iter() - .map(|packet| publish(packet, Arc::new(stream.to_owned()), opts)) - .collect() -} - -fn main_subject( - receipt: &FuelCoreReceipt, - tx_id: &Bytes32, - index: usize, -) -> Arc { - match receipt { - FuelCoreReceipt::Call { - id: from, - to, - asset_id, - .. - } => ReceiptsCallSubject { - tx_id: Some(tx_id.to_owned()), - index: Some(index), - from: Some(from.into()), - to: Some(to.into()), - asset_id: Some(asset_id.into()), - } - .arc(), - FuelCoreReceipt::Return { id, .. } => ReceiptsReturnSubject { - tx_id: Some(tx_id.to_owned()), - index: Some(index), - id: Some(id.into()), - } - .arc(), - FuelCoreReceipt::ReturnData { id, .. } => ReceiptsReturnDataSubject { - tx_id: Some(tx_id.to_owned()), - index: Some(index), - id: Some(id.into()), - } - .arc(), - FuelCoreReceipt::Panic { id, .. } => ReceiptsPanicSubject { - tx_id: Some(tx_id.to_owned()), - index: Some(index), - id: Some(id.into()), - } - .arc(), - FuelCoreReceipt::Revert { id, .. } => ReceiptsRevertSubject { - tx_id: Some(tx_id.to_owned()), - index: Some(index), - id: Some(id.into()), - } - .arc(), - FuelCoreReceipt::Log { id, .. } => ReceiptsLogSubject { - tx_id: Some(tx_id.to_owned()), - index: Some(index), - id: Some(id.into()), - } - .arc(), - FuelCoreReceipt::LogData { id, .. } => ReceiptsLogDataSubject { - tx_id: Some(tx_id.to_owned()), - index: Some(index), - id: Some(id.into()), - } - .arc(), - FuelCoreReceipt::Transfer { - id: from, - to, - asset_id, - .. - } => ReceiptsTransferSubject { - tx_id: Some(tx_id.to_owned()), - index: Some(index), - from: Some(from.into()), - to: Some(to.into()), - asset_id: Some(asset_id.into()), - } - .arc(), - - FuelCoreReceipt::TransferOut { - id: from, - to, - asset_id, - .. - } => ReceiptsTransferOutSubject { - tx_id: Some(tx_id.to_owned()), - index: Some(index), - from: Some(from.into()), - to: Some(to.into()), - asset_id: Some(asset_id.into()), - } - .arc(), - - FuelCoreReceipt::ScriptResult { .. } => ReceiptsScriptResultSubject { - tx_id: Some(tx_id.to_owned()), - index: Some(index), - } - .arc(), - FuelCoreReceipt::MessageOut { - sender, recipient, .. - } => ReceiptsMessageOutSubject { - tx_id: Some(tx_id.to_owned()), - index: Some(index), - sender: Some(sender.into()), - recipient: Some(recipient.into()), - } - .arc(), - FuelCoreReceipt::Mint { - contract_id, - sub_id, - .. - } => ReceiptsMintSubject { - tx_id: Some(tx_id.to_owned()), - index: Some(index), - contract_id: Some(contract_id.into()), - sub_id: Some((*sub_id).into()), - } - .arc(), - FuelCoreReceipt::Burn { - contract_id, - sub_id, - .. - } => ReceiptsBurnSubject { - tx_id: Some(tx_id.to_owned()), - index: Some(index), - contract_id: Some(contract_id.into()), - sub_id: Some((*sub_id).into()), - } - .arc(), - } -} - -pub fn identifiers( - receipt: &FuelCoreReceipt, - tx_id: &Bytes32, - index: u8, -) -> Vec { - match receipt { - FuelCoreReceipt::Call { - id: from, - to, - asset_id, - .. - } => { - vec![ - Identifier::ContractID(tx_id.to_owned(), index, from.into()), - Identifier::ContractID(tx_id.to_owned(), index, to.into()), - Identifier::AssetID(tx_id.to_owned(), index, asset_id.into()), - ] - } - FuelCoreReceipt::Return { id, .. } - | FuelCoreReceipt::ReturnData { id, .. } - | FuelCoreReceipt::Panic { id, .. } - | FuelCoreReceipt::Revert { id, .. } - | FuelCoreReceipt::Log { id, .. } - | FuelCoreReceipt::LogData { id, .. } => { - vec![Identifier::ContractID(tx_id.to_owned(), index, id.into())] - } - FuelCoreReceipt::Transfer { - id: from, - to, - asset_id, - .. - } => { - vec![ - Identifier::ContractID(tx_id.to_owned(), index, from.into()), - Identifier::ContractID(tx_id.to_owned(), index, to.into()), - Identifier::AssetID(tx_id.to_owned(), index, asset_id.into()), - ] - } - FuelCoreReceipt::TransferOut { - id: from, - to, - asset_id, - .. - } => { - vec![ - Identifier::ContractID(tx_id.to_owned(), index, from.into()), - Identifier::ContractID(tx_id.to_owned(), index, to.into()), - Identifier::AssetID(tx_id.to_owned(), index, asset_id.into()), - ] - } - FuelCoreReceipt::MessageOut { - sender, recipient, .. - } => { - vec![ - Identifier::Address(tx_id.to_owned(), index, sender.into()), - Identifier::Address(tx_id.to_owned(), index, recipient.into()), - ] - } - FuelCoreReceipt::Mint { contract_id, .. } - | FuelCoreReceipt::Burn { contract_id, .. } => { - vec![Identifier::ContractID( - tx_id.to_owned(), - index, - contract_id.into(), - )] - } - _ => Vec::new(), - } -} diff --git a/crates/fuel-streams-publisher/src/publisher/payloads/transactions.rs b/crates/fuel-streams-publisher/src/publisher/payloads/transactions.rs deleted file mode 100644 index fc97edc6..00000000 --- a/crates/fuel-streams-publisher/src/publisher/payloads/transactions.rs +++ /dev/null @@ -1,177 +0,0 @@ -use std::sync::Arc; - -use fuel_core_types::fuel_tx::field::ScriptData; -use fuel_streams_core::prelude::*; -use rayon::prelude::*; -use tokio::task::JoinHandle; - -use super::{ - inputs::{self, publish_tasks as publish_inputs}, - logs::publish_tasks as publish_logs, - outputs::{self, publish_tasks as publish_outputs}, - receipts::{self, publish_tasks as publish_receipts}, - sha256, - utxos::publish_tasks as publish_utxos, -}; -use crate::{publish, FuelCoreLike, FuelStreamsExt, PublishOpts}; - -pub fn publish_all_tasks( - transactions: &[FuelCoreTransaction], - fuel_streams: &dyn FuelStreamsExt, - opts: &Arc, - fuel_core: &dyn FuelCoreLike, -) -> anyhow::Result>>> { - let offchain_database = Arc::clone(&opts.offchain_database); - let mut tasks = vec![]; - - for tx_item @ (_, tx) in transactions.iter().enumerate() { - let tx_id = tx.id(&opts.chain_id); - let tx_status: TransactionStatus = offchain_database - .get_tx_status(&tx_id)? - .map(|status| (&status).into()) - .unwrap_or_default(); - - let receipts = fuel_core.get_receipts(&tx_id)?.unwrap_or_default(); - - let tx_id = tx_id.into(); - - tasks.extend(publish_tasks( - tx_item, - &tx_id, - &tx_status, - fuel_streams.transactions(), - opts, - &receipts, - )); - tasks.extend(publish_inputs(tx, &tx_id, fuel_streams.inputs(), opts)); - tasks.extend(publish_outputs(tx, &tx_id, fuel_streams.outputs(), opts)); - tasks.extend(publish_receipts( - &tx_id, - fuel_streams.receipts(), - opts, - &receipts, - )); - tasks.extend(publish_outputs(tx, &tx_id, fuel_streams.outputs(), opts)); - tasks.extend(publish_logs( - &tx_id, - fuel_streams.logs(), - opts, - &receipts, - )); - tasks.extend(publish_utxos(tx, &tx_id, fuel_streams.utxos(), opts)); - } - - Ok(tasks) -} - -fn publish_tasks( - tx_item: (usize, &FuelCoreTransaction), - tx_id: &Bytes32, - tx_status: &TransactionStatus, - stream: &Stream, - opts: &Arc, - receipts: &Vec, -) -> Vec>> { - let block_height = &opts.block_height; - let base_asset_id = &opts.base_asset_id; - - packets_from_tx( - tx_item, - tx_id, - tx_status, - base_asset_id, - block_height, - receipts, - ) - .iter() - .map(|packet| publish(packet, Arc::new(stream.to_owned()), opts)) - .collect() -} - -fn packets_from_tx( - (index, tx): (usize, &FuelCoreTransaction), - tx_id: &Bytes32, - tx_status: &TransactionStatus, - base_asset_id: &FuelCoreAssetId, - block_height: &BlockHeight, - receipts: &Vec, -) -> Vec> { - let main_subject = TransactionsSubject { - block_height: Some(block_height.to_owned()), - index: Some(index), - tx_id: Some(tx_id.to_owned()), - status: Some(tx_status.to_owned()), - kind: Some(tx.into()), - } - .arc(); - - let transaction = - Transaction::new(tx_id, tx, tx_status, base_asset_id, receipts); - let mut packets = vec![transaction.to_packet(main_subject)]; - - packets.extend( - identifiers(tx, tx_id, index as u8) - .into_par_iter() - .map(|identifier| identifier.into()) - .map(|subject: TransactionsByIdSubject| subject.arc()) - .map(|subject| transaction.to_packet(subject)) - .collect::>(), - ); - - let packets_from_inputs: Vec> = tx - .inputs() - .par_iter() - .flat_map(|input| { - inputs::identifiers(input, tx_id, index as u8) - .into_par_iter() - .map(|identifier| identifier.into()) - .map(|subject: TransactionsByIdSubject| subject.arc()) - .map(|subject| transaction.to_packet(subject)) - }) - .collect(); - - packets.extend(packets_from_inputs); - - let packets_from_outputs: Vec> = tx - .outputs() - .par_iter() - .flat_map(|output| { - outputs::identifiers(output, tx, tx_id, index as u8) - .into_par_iter() - .map(|identifier| identifier.into()) - .map(|subject: TransactionsByIdSubject| subject.arc()) - .map(|subject| transaction.to_packet(subject)) - }) - .collect(); - - packets.extend(packets_from_outputs); - - let packets_from_receipts: Vec> = receipts - .par_iter() - .flat_map(|receipt| { - receipts::identifiers(receipt, tx_id, index as u8) - .into_par_iter() - .map(|identifier| identifier.into()) - .map(|subject: TransactionsByIdSubject| subject.arc()) - .map(|subject| transaction.to_packet(subject)) - }) - .collect(); - - packets.extend(packets_from_receipts); - - packets -} - -fn identifiers( - tx: &FuelCoreTransaction, - tx_id: &Bytes32, - index: u8, -) -> Vec { - match tx { - FuelCoreTransaction::Script(tx) => { - let script_tag = sha256(tx.script_data()); - vec![Identifier::ScriptID(tx_id.to_owned(), index, script_tag)] - } - _ => Vec::new(), - } -} diff --git a/crates/fuel-streams-publisher/src/publisher/payloads/utxos.rs b/crates/fuel-streams-publisher/src/publisher/payloads/utxos.rs deleted file mode 100644 index 0e4d1f89..00000000 --- a/crates/fuel-streams-publisher/src/publisher/payloads/utxos.rs +++ /dev/null @@ -1,145 +0,0 @@ -use std::sync::Arc; - -use fuel_core_types::fuel_tx::{ - input::{ - coin::{CoinPredicate, CoinSigned}, - contract::Contract, - message::{ - compute_message_id, - MessageCoinPredicate, - MessageCoinSigned, - MessageDataPredicate, - MessageDataSigned, - }, - }, - UtxoId, -}; -use fuel_streams_core::prelude::*; -use rayon::prelude::*; -use tokio::task::JoinHandle; - -use crate::{publish, PublishOpts}; - -pub fn publish_tasks( - tx: &FuelCoreTransaction, - tx_id: &Bytes32, - stream: &Stream, - opts: &Arc, -) -> Vec>> { - let packets = tx - .inputs() - .par_iter() - .filter_map(|input| utxo_packet(input, tx_id, input.utxo_id().cloned())) - .collect::>(); - - packets - .into_iter() - .map(|packet| publish(&packet, Arc::new(stream.to_owned()), opts)) - .collect() -} - -fn utxo_packet( - input: &FuelCoreInput, - tx_id: &Bytes32, - utxo_id: Option, -) -> Option> { - utxo_id?; - let utxo_id = utxo_id.expect("safe to unwrap utxo"); - - match input { - FuelCoreInput::Contract(Contract { utxo_id, .. }) => { - let utxo = Utxo { - utxo_id: utxo_id.into(), - tx_id: tx_id.to_owned(), - ..Default::default() - }; - - let subject = UtxosSubject { - utxo_type: Some(UtxoType::Contract), - hash: Some(tx_id.to_owned().into()), - } - .arc(); - - Some(utxo.to_packet(subject)) - } - FuelCoreInput::CoinSigned(CoinSigned { - utxo_id, amount, .. - }) - | FuelCoreInput::CoinPredicate(CoinPredicate { - utxo_id, amount, .. - }) => { - let utxo = Utxo { - utxo_id: utxo_id.into(), - amount: Some(*amount), - tx_id: tx_id.to_owned(), - ..Default::default() - }; - - let subject = UtxosSubject { - utxo_type: Some(UtxoType::Coin), - hash: Some(tx_id.to_owned().into()), - } - .arc(); - - Some(utxo.to_packet(subject)) - } - message @ (FuelCoreInput::MessageCoinSigned(MessageCoinSigned { - amount, - nonce, - recipient, - sender, - .. - }) - | FuelCoreInput::MessageCoinPredicate( - MessageCoinPredicate { - amount, - nonce, - recipient, - sender, - .. - }, - ) - | FuelCoreInput::MessageDataSigned(MessageDataSigned { - amount, - nonce, - recipient, - sender, - .. - }) - | FuelCoreInput::MessageDataPredicate( - MessageDataPredicate { - amount, - nonce, - recipient, - sender, - .. - }, - )) => { - let (data, hash) = if let Some(data) = message.input_data() { - let hash: MessageId = - compute_message_id(sender, recipient, nonce, *amount, data) - .into(); - (Some(data.to_vec()), hash) - } else { - (None, tx_id.to_owned().into()) - }; - - let utxo = Utxo { - utxo_id: utxo_id.into(), - sender: Some(sender.into()), - recipient: Some(recipient.into()), - nonce: Some(nonce.into()), - amount: Some(*amount), - tx_id: tx_id.to_owned(), - data, - }; - let subject = UtxosSubject { - utxo_type: Some(UtxoType::Message), - hash: Some(hash), - } - .arc(); - - Some(utxo.to_packet(subject)) - } - } -} diff --git a/crates/fuel-streams-publisher/src/server/http.rs b/crates/fuel-streams-publisher/src/server/http.rs index 32d0ec73..c86eea36 100644 --- a/crates/fuel-streams-publisher/src/server/http.rs +++ b/crates/fuel-streams-publisher/src/server/http.rs @@ -58,7 +58,6 @@ pub fn create_web_server( } #[cfg(test)] -#[cfg(feature = "test-helpers")] mod tests { use std::time::Duration; @@ -66,11 +65,11 @@ mod tests { use fuel_core::service::Config; use fuel_core_bin::FuelService; use fuel_core_services::State; + use fuel_streams_core::fuel_core_like::FuelCore; use crate::{ server::state::{HealthResponse, ServerState}, telemetry::Telemetry, - FuelCore, Publisher, }; diff --git a/crates/fuel-streams-publisher/src/telemetry/system.rs b/crates/fuel-streams-publisher/src/telemetry/system.rs index ec0f14eb..bae499a0 100644 --- a/crates/fuel-streams-publisher/src/telemetry/system.rs +++ b/crates/fuel-streams-publisher/src/telemetry/system.rs @@ -572,26 +572,20 @@ mod tests { kernel_version: "kernel-version".to_string(), uptime: 123456, }, - disk: vec![( - PathBuf::from("disk1"), - Disk { - size: 1000, - free: 877, - usage: Decimal::new(1234, 2), - }, - )] + disk: vec![(PathBuf::from("disk1"), Disk { + size: 1000, + free: 877, + usage: Decimal::new(1234, 2), + })] .into_iter() .collect(), cpu_physical_core_count: 1, cpu_count: 1, - cpu: vec![( - 1, - Cpu { - name: "cpu1".to_string(), - frequency: 12345, - usage: Decimal::new(1234, 2), - }, - )] + cpu: vec![(1, Cpu { + name: "cpu1".to_string(), + frequency: 12345, + usage: Decimal::new(1234, 2), + })] .into_iter() .collect(), }, @@ -600,35 +594,32 @@ mod tests { let output = serde_prometheus::to_string(&metrics, None, &[]) .expect("prometheus"); - assert_eq!( - output.trim_end().split('\n').collect::>(), - vec![ - r#"system_application_pid 0"#, - r#"system_application_name{path = "process"} 1"#, - r#"system_application_cpu_usage 12.34"#, - r#"system_application_size{type = "memory"} 1000"#, - r#"system_application_free{type = "memory"} 877"#, - r#"system_application_usage{type = "memory"} 12.34"#, - r#"system_memory_size{type = "system"} 1000"#, - r#"system_memory_free{type = "system"} 877"#, - r#"system_memory_usage{type = "system"} 12.34"#, - r#"system_memory_size{type = "swap"} 1000"#, - r#"system_memory_free{type = "swap"} 877"#, - r#"system_memory_usage{type = "swap"} 12.34"#, - r#"system_load_average_1 1.2"#, - r#"system_load_average_5 2.3"#, - r#"system_load_average_15 3.4"#, - r#"system_host_os_version{path = "os-version"} 1"#, - r#"system_host_kernel_version{path = "kernel-version"} 1"#, - r#"system_host_uptime 123456"#, - r#"system_disk_size{path = "disk1"} 1000"#, - r#"system_disk_free{path = "disk1"} 877"#, - r#"system_disk_usage{path = "disk1"} 12.34"#, - r#"system_cpu_physical_core_count 1"#, - r#"system_cpu_count 1"#, - r#"system_cpu_frequency{id = "1"} 12345"#, - r#"system_cpu_usage{id = "1"} 12.34"#, - ] - ) + assert_eq!(output.trim_end().split('\n').collect::>(), vec![ + r#"system_application_pid 0"#, + r#"system_application_name{path = "process"} 1"#, + r#"system_application_cpu_usage 12.34"#, + r#"system_application_size{type = "memory"} 1000"#, + r#"system_application_free{type = "memory"} 877"#, + r#"system_application_usage{type = "memory"} 12.34"#, + r#"system_memory_size{type = "system"} 1000"#, + r#"system_memory_free{type = "system"} 877"#, + r#"system_memory_usage{type = "system"} 12.34"#, + r#"system_memory_size{type = "swap"} 1000"#, + r#"system_memory_free{type = "swap"} 877"#, + r#"system_memory_usage{type = "swap"} 12.34"#, + r#"system_load_average_1 1.2"#, + r#"system_load_average_5 2.3"#, + r#"system_load_average_15 3.4"#, + r#"system_host_os_version{path = "os-version"} 1"#, + r#"system_host_kernel_version{path = "kernel-version"} 1"#, + r#"system_host_uptime 123456"#, + r#"system_disk_size{path = "disk1"} 1000"#, + r#"system_disk_free{path = "disk1"} 877"#, + r#"system_disk_usage{path = "disk1"} 12.34"#, + r#"system_cpu_physical_core_count 1"#, + r#"system_cpu_count 1"#, + r#"system_cpu_frequency{id = "1"} 12345"#, + r#"system_cpu_usage{id = "1"} 12.34"#, + ]) } } diff --git a/crates/sv-consumer/Cargo.toml b/crates/sv-consumer/Cargo.toml new file mode 100644 index 00000000..ed27f473 --- /dev/null +++ b/crates/sv-consumer/Cargo.toml @@ -0,0 +1,48 @@ +[package] +name = "sv-consumer" +description = "Service that consumers new blocks from the emitter" +authors = { workspace = true } +keywords = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +version = { workspace = true } +rust-version = { workspace = true } +publish = false + +[[bin]] +name = "sv-consumer" +path = "src/main.rs" + +[dependencies] +anyhow = { workspace = true } +async-nats = { workspace = true } +clap = { workspace = true } +fuel-core = { workspace = true, default-features = false, features = ["p2p", "relayer", "rocksdb"] } +fuel-streams-core = { workspace = true, features = ["test-helpers"] } +fuel-streams-executors = { workspace = true, features = ["test-helpers"] } +futures = { workspace = true } +serde_json = { workspace = true } +sv-emitter = { workspace = true } +thiserror = { workspace = true } +tokio = { workspace = true } +tokio-util = "0.7.13" +tracing = { workspace = true } +tracing-subscriber = { workspace = true, features = ["local-time"] } + +[features] +default = [] +test-helpers = [] + +[target.x86_64-unknown-linux-gnu.dependencies] +openssl = { version = "0.10.68", features = ["vendored"] } + +[target.x86_64-unknown-linux-musl.dependencies] +openssl = { version = "0.10.68", features = ["vendored"] } + +[target.aarch64-unknown-linux-gnu.dependencies] +openssl = { version = "0.10.68", features = ["vendored"] } + +[target.aarch64-unknown-linux-musl.dependencies] +openssl = { version = "0.10.68", features = ["vendored"] } diff --git a/crates/sv-consumer/src/cli.rs b/crates/sv-consumer/src/cli.rs new file mode 100644 index 00000000..2f893567 --- /dev/null +++ b/crates/sv-consumer/src/cli.rs @@ -0,0 +1,22 @@ +use clap::Parser; + +#[derive(Clone, Parser)] +pub struct Cli { + /// Fuel Network to connect to. + #[arg( + long, + value_name = "NATS_CORE_URL", + env = "NATS_CORE_URL", + default_value = "localhost:4222", + help = "NATS Core URL to connect to." + )] + pub nats_core_url: String, + #[arg( + long, + value_name = "NATS_PUBLISHER_URL", + env = "NATS_PUBLISHER_URL", + default_value = "localhost:4222", + help = "NATS Publisher URL to connect to." + )] + pub nats_publisher_url: String, +} diff --git a/crates/sv-consumer/src/lib.rs b/crates/sv-consumer/src/lib.rs new file mode 100644 index 00000000..ddf67e02 --- /dev/null +++ b/crates/sv-consumer/src/lib.rs @@ -0,0 +1,31 @@ +use std::sync::Arc; + +use fuel_streams_core::prelude::*; + +pub mod cli; + +#[derive(Debug, Clone, Default)] +pub enum Client { + #[default] + Core, + Publisher, +} + +impl Client { + pub fn url(&self, cli: &cli::Cli) -> String { + match self { + Client::Core => cli.nats_core_url.clone(), + Client::Publisher => cli.nats_publisher_url.clone(), + } + } + pub async fn create( + &self, + cli: &cli::Cli, + ) -> Result, NatsError> { + let url = self.url(cli); + let opts = NatsClientOpts::admin_opts(None) + .with_custom_url(url) + .with_domain("CORE".to_string()); + Ok(Arc::new(NatsClient::connect(&opts).await?)) + } +} diff --git a/crates/sv-consumer/src/main.rs b/crates/sv-consumer/src/main.rs new file mode 100644 index 00000000..d764048e --- /dev/null +++ b/crates/sv-consumer/src/main.rs @@ -0,0 +1,134 @@ +use std::{sync::Arc, time::Duration}; + +use async_nats::jetstream::{ + consumer::{ + pull::{BatchErrorKind, Config as ConsumerConfig}, + Consumer, + }, + context::CreateStreamErrorKind, + stream::{ConsumerErrorKind, RetentionPolicy}, +}; +use clap::Parser; +use fuel_streams_core::prelude::*; +use fuel_streams_executors::*; +use futures::StreamExt; +use sv_consumer::{cli::Cli, Client}; +use sv_emitter::shutdown::ShutdownController; +use tokio_util::sync::CancellationToken; +use tracing_subscriber::fmt::time; + +#[derive(thiserror::Error, Debug)] +pub enum ConsumerError { + #[error("Failed to receive batch of messages from NATS: {0}")] + BatchStream(#[from] async_nats::error::Error), + + #[error("Failed to create stream: {0}")] + CreateStream(#[from] async_nats::error::Error), + + #[error("Failed to create consumer: {0}")] + CreateConsumer(#[from] async_nats::error::Error), + + #[error("Failed to connect to NATS client: {0}")] + NatsClient(#[from] NatsError), + + #[error("Failed to communicate with NATS server: {0}")] + Nats(#[from] async_nats::Error), + + #[error("Failed to deserialize block payload from message: {0}")] + Deserialization(#[from] serde_json::Error), + + #[error("Failed to publish block to stream: {0}")] + Publish(#[from] ExecutorError), + + #[error("Failed to decode UTF-8: {0}")] + Utf8(#[from] std::str::Utf8Error), +} + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + // Initialize tracing subscriber + tracing_subscriber::fmt() + .with_env_filter("sv_consumer=trace,fuel_streams_executors=trace") + .with_timer(time::LocalTime::rfc_3339()) + .with_target(false) + .with_thread_ids(false) + .with_file(true) + .with_line_number(true) + .with_level(true) + .init(); + + let cli = Cli::parse(); + let shutdown = Arc::new(ShutdownController::new()); + shutdown.clone().spawn_signal_handler(); + + tracing::info!("Consumer started. Waiting for messages..."); + tokio::select! { + result = async { + process_messages(&cli, shutdown.token()) + .await + } => { + result?; + tracing::info!("Processing complete"); + } + _ = shutdown.wait_for_shutdown() => { + tracing::info!("Shutdown signal received"); + } + }; + + tracing::info!("Shutdown complete"); + Ok(()) +} + +async fn setup_nats( + cli: &Cli, +) -> Result< + (Arc, Arc, Consumer), + ConsumerError, +> { + let core_client = Client::Core.create(cli).await?; + let publisher_client = Client::Publisher.create(cli).await?; + let stream_name = publisher_client.namespace.stream_name("block_importer"); + let stream = publisher_client + .jetstream + .get_or_create_stream(async_nats::jetstream::stream::Config { + name: stream_name, + subjects: vec!["block_submitted.>".to_string()], + retention: RetentionPolicy::WorkQueue, + duplicate_window: Duration::from_secs(1), + allow_rollup: true, + ..Default::default() + }) + .await?; + + let consumer = stream + .get_or_create_consumer("block_importer", ConsumerConfig { + durable_name: Some("block_importer".to_string()), + ack_policy: AckPolicy::Explicit, + ..Default::default() + }) + .await?; + + Ok((core_client, publisher_client, consumer)) +} + +async fn process_messages( + cli: &Cli, + token: &CancellationToken, +) -> Result<(), ConsumerError> { + let (core_client, publisher_client, consumer) = setup_nats(cli).await?; + let (_, publisher_stream) = + FuelStreams::setup_all(&core_client, &publisher_client).await; + let fuel_streams: Arc = publisher_stream.arc(); + while !token.is_cancelled() { + let messages = consumer.fetch().max_messages(100).messages().await?; + tokio::pin!(messages); + while let Some(msg) = messages.next().await { + let msg = msg?; + let msg_str = std::str::from_utf8(&msg.payload)?; + let payload = Arc::new(BlockPayload::decode(msg_str)?); + Executor::::process_all(payload, &fuel_streams).await?; + msg.ack().await?; + } + } + Ok(()) +} diff --git a/crates/sv-emitter/Cargo.lock b/crates/sv-emitter/Cargo.lock new file mode 100644 index 00000000..046abc4a --- /dev/null +++ b/crates/sv-emitter/Cargo.lock @@ -0,0 +1,7553 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "asn1-rs" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ad1373757efa0f70ec53939aabc7152e1591cb485208052993070ac8d2429d" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7378575ff571966e99a744addeff0bff98b8ada0dedf1956d59e634db95eaac1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "asn1_der" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "155a5a185e42c6b77ac7b88a15143d930a9e9727a5b7b77eed417404ab15c247" + +[[package]] +name = "async-graphql" +version = "4.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9ed522678d412d77effe47b3c82314ac36952a35e6e852093dd48287c421f80" +dependencies = [ + "async-graphql-derive", + "async-graphql-parser", + "async-graphql-value", + "async-stream", + "async-trait", + "base64 0.13.1", + "bytes", + "fnv", + "futures-util", + "http", + "indexmap 1.9.3", + "mime", + "multer", + "num-traits", + "once_cell", + "pin-project-lite", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "static_assertions", + "tempfile", + "thiserror", + "tracing", + "tracing-futures", +] + +[[package]] +name = "async-graphql-derive" +version = "4.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c121a894495d7d3fc3d4e15e0a9843e422e4d1d9e3c514d8062a1c94b35b005d" +dependencies = [ + "Inflector", + "async-graphql-parser", + "darling 0.14.4", + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", + "thiserror", +] + +[[package]] +name = "async-graphql-parser" +version = "4.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b6c386f398145c6180206c1869c2279f5a3d45db5be4e0266148c6ac5c6ad68" +dependencies = [ + "async-graphql-value", + "pest", + "serde", + "serde_json", +] + +[[package]] +name = "async-graphql-value" +version = "4.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a941b499fead4a3fb5392cabf42446566d18c86313f69f2deab69560394d65f" +dependencies = [ + "bytes", + "indexmap 1.9.3", + "serde", + "serde_json", +] + +[[package]] +name = "async-io" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" +dependencies = [ + "async-lock", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-lock" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-nats" +version = "0.35.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab8df97cb8fc4a884af29ab383e9292ea0939cfcdd7d2a17179086dc6c427e7f" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures", + "memchr", + "nkeys", + "nuid", + "once_cell", + "portable-atomic", + "rand", + "regex", + "ring 0.17.8", + "rustls-native-certs", + "rustls-pemfile 2.1.2", + "rustls-webpki 0.102.4", + "serde", + "serde_json", + "serde_nanos", + "serde_repr", + "thiserror", + "time", + "tokio", + "tokio-rustls 0.26.0", + "tracing", + "tryhard", + "url", +] + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "async-trait" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "async_io_stream" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" +dependencies = [ + "futures", + "pharos", + "rustc_version", +] + +[[package]] +name = "asynchronous-codec" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4057f2c32adbb2fc158e22fb38433c8e9bbf76b75a4732c7c0cbaf695fb65568" +dependencies = [ + "bytes", + "futures-sink", + "futures-util", + "memchr", + "pin-project-lite", +] + +[[package]] +name = "asynchronous-codec" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a860072022177f903e59730004fb5dc13db9275b79bb2aef7ba8ce831956c233" +dependencies = [ + "bytes", + "futures-sink", + "futures-util", + "memchr", + "pin-project-lite", +] + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "attohttpc" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9a9bf8b79a749ee0b911b91b671cc2b6c670bdbc7e3dfd537576ddc94bb2a2" +dependencies = [ + "http", + "log", + "url", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "auto_impl" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "axum" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acee9fd5073ab6b045a275b3e709c163dd36c90685219cb21804a147b58dba43" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-http", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e5939e02c56fecd5c017c37df4238c0a839fa76b7f97acdd7efb804fd181cc" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "serde", +] + +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bindgen" +version = "0.65.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.66", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +dependencies = [ + "serde", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "sha2 0.10.8", + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +dependencies = [ + "serde", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "camino" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cc" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" +dependencies = [ + "jobserver", + "libc", + "once_cell", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "serde", + "windows-targets 0.52.5", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +dependencies = [ + "atty", + "bitflags 1.3.2", + "clap_derive 3.2.25", + "clap_lex 0.2.4", + "indexmap 1.9.3", + "once_cell", + "strsim 0.10.0", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +dependencies = [ + "clap_builder", + "clap_derive 4.5.4", +] + +[[package]] +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +dependencies = [ + "anstream", + "anstyle", + "clap_lex 0.7.0", + "strsim 0.11.1", +] + +[[package]] +name = "clap_derive" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" +dependencies = [ + "heck 0.4.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "clap_derive" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + +[[package]] +name = "coins-bip32" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b6be4a5df2098cd811f3194f64ddb96c267606bffd9689ac7b0160097b01ad3" +dependencies = [ + "bs58", + "coins-core", + "digest 0.10.7", + "hmac 0.12.1", + "k256", + "serde", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "coins-bip39" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8fba409ce3dc04f7d804074039eb68b960b0829161f8e06c95fea3f122528" +dependencies = [ + "bitvec", + "coins-bip32", + "hmac 0.12.1", + "once_cell", + "pbkdf2", + "rand", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "coins-core" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5286a0843c21f8367f7be734f89df9b822e0321d8bcce8d6e735aadff7d74979" +dependencies = [ + "base64 0.21.7", + "bech32", + "bs58", + "digest 0.10.7", + "generic-array", + "hex", + "ripemd", + "serde", + "serde_derive", + "sha2 0.10.8", + "sha3", + "thiserror", +] + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.52.0", +] + +[[package]] +name = "const-hex" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "proptest", + "serde", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const_format" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + +[[package]] +name = "cpp_demangle" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8227005286ec39567949b33df9896bcadfa6051bccca2488129f108ca23119" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "cranelift-bforest" +version = "0.105.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "496c993b62bdfbe9b4c518b8b3e1fdba9f89ef89fcccc050ab61d91dfba9fbaf" +dependencies = [ + "cranelift-entity", +] + +[[package]] +name = "cranelift-codegen" +version = "0.105.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b922abb6be41fc383f5e9da65b58d32d0d0a32c87dfe3bbbcb61a09119506c" +dependencies = [ + "bumpalo", + "cranelift-bforest", + "cranelift-codegen-meta", + "cranelift-codegen-shared", + "cranelift-control", + "cranelift-entity", + "cranelift-isle", + "gimli", + "hashbrown 0.14.5", + "log", + "regalloc2", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-codegen-meta" +version = "0.105.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634c2ed9ef8a04ca42535a3e2e7917e4b551f2f306f4df2d935a6e71e346c167" +dependencies = [ + "cranelift-codegen-shared", +] + +[[package]] +name = "cranelift-codegen-shared" +version = "0.105.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00cde1425b4da28bb0d5ff010030ea9cc9be7aded342ae099b394284f17cefce" + +[[package]] +name = "cranelift-control" +version = "0.105.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1622125c99f1864aaf44e57971770c4a918d081d4b4af0bb597bdf624660ed66" +dependencies = [ + "arbitrary", +] + +[[package]] +name = "cranelift-entity" +version = "0.105.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea97887aca1c0cbe7f8513874dc3603e9744fb1cfa78840ca8897bd2766bd35b" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "cranelift-frontend" +version = "0.105.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cdade4c14183fe41482071ed77d6a38cb95a17c7a0a05e629152e6292c4f8cb" +dependencies = [ + "cranelift-codegen", + "log", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-isle" +version = "0.105.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbbe4d3ad7bd4bf4a8d916c8460b441cf92417f5cdeacce4dd1d96eee70b18a2" + +[[package]] +name = "cranelift-native" +version = "0.105.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c46be4ed1fc8f36df4e2a442b8c30a39d8c03c1868182978f4c04ba2c25c9d4f" +dependencies = [ + "cranelift-codegen", + "libc", + "target-lexicon", +] + +[[package]] +name = "cranelift-wasm" +version = "0.105.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d4c4a785a7866da89d20df159e3c4f96a5f14feb83b1f5998cfd5fe2e74d06" +dependencies = [ + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "itertools 0.10.5", + "log", + "smallvec", + "wasmparser", + "wasmtime-types", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "critical-section" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core 0.14.4", + "darling_macro 0.14.4", +] + +[[package]] +name = "darling" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +dependencies = [ + "darling_core 0.20.9", + "darling_macro 0.20.9", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 1.0.109", +] + +[[package]] +name = "darling_core" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.11.1", + "syn 2.0.66", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core 0.14.4", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +dependencies = [ + "darling_core 0.20.9", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "data-encoding" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" + +[[package]] +name = "data-encoding-macro" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1559b6cba622276d6d63706db152618eeb15b89b3e4041446b05876e352e639" +dependencies = [ + "data-encoding", + "data-encoding-macro-internal", +] + +[[package]] +name = "data-encoding-macro-internal" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "332d754c0af53bc87c108fed664d121ecf59207ec4196041f04d6ab9002ad33f" +dependencies = [ + "data-encoding", + "syn 1.0.109", +] + +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "uuid", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "der-parser" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "directories-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "dtoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand_core", + "serde", + "sha2 0.10.8", + "signature", + "subtle", + "zeroize", +] + +[[package]] +name = "either" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enr" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a3d8dc56e02f954cac8eb489772c552c473346fc34f67412bb6244fd647f7e4" +dependencies = [ + "base64 0.21.7", + "bytes", + "hex", + "k256", + "log", + "rand", + "rlp", + "serde", + "sha3", + "zeroize", +] + +[[package]] +name = "enum-as-inner" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "enum-iterator" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fd242f399be1da0a5354aa462d57b4ab2b4ee0683cc552f7c007d2d12d36e94" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "ethabi" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" +dependencies = [ + "ethereum-types", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "tiny-keccak", +] + +[[package]] +name = "ethereum-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "primitive-types", + "scale-info", + "uint", +] + +[[package]] +name = "ethers-contract" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fceafa3578c836eeb874af87abacfb041f92b4da0a78a5edd042564b8ecdaaa" +dependencies = [ + "const-hex", + "ethers-contract-abigen", + "ethers-contract-derive", + "ethers-core", + "futures-util", + "once_cell", + "pin-project", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "ethers-contract-abigen" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04ba01fbc2331a38c429eb95d4a570166781f14290ef9fdb144278a90b5a739b" +dependencies = [ + "Inflector", + "const-hex", + "dunce", + "ethers-core", + "eyre", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "serde", + "serde_json", + "syn 2.0.66", + "toml 0.8.13", + "walkdir", +] + +[[package]] +name = "ethers-contract-derive" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87689dcabc0051cde10caaade298f9e9093d65f6125c14575db3fd8c669a168f" +dependencies = [ + "Inflector", + "const-hex", + "ethers-contract-abigen", + "ethers-core", + "proc-macro2", + "quote", + "serde_json", + "syn 2.0.66", +] + +[[package]] +name = "ethers-core" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d80cc6ad30b14a48ab786523af33b37f28a8623fc06afd55324816ef18fb1f" +dependencies = [ + "arrayvec", + "bytes", + "cargo_metadata", + "chrono", + "const-hex", + "elliptic-curve", + "ethabi", + "generic-array", + "k256", + "num_enum", + "once_cell", + "open-fastrlp", + "rand", + "rlp", + "serde", + "serde_json", + "strum 0.26.2", + "syn 2.0.66", + "tempfile", + "thiserror", + "tiny-keccak", + "unicode-xid", +] + +[[package]] +name = "ethers-providers" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6434c9a33891f1effc9c75472e12666db2fa5a0fec4b29af6221680a6fe83ab2" +dependencies = [ + "async-trait", + "auto_impl", + "base64 0.21.7", + "bytes", + "const-hex", + "enr", + "ethers-core", + "futures-channel", + "futures-core", + "futures-timer", + "futures-util", + "hashers", + "http", + "instant", + "jsonwebtoken", + "once_cell", + "pin-project", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-tungstenite", + "tracing", + "tracing-futures", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "ws_stream_wasm", +] + +[[package]] +name = "ethnum" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" + +[[package]] +name = "event-listener" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "findshlibs" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40b9e59cd0f7e0806cca4be089683ecb6434e602038df21fe6bf6711b2f07f64" +dependencies = [ + "cc", + "lazy_static", + "libc", + "winapi", +] + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fuel-asm" +version = "0.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42df651415e443094f86102473b7f9fa23633ab6c3c98dd3f713adde251acf0f" +dependencies = [ + "bitflags 2.5.0", + "fuel-types", + "serde", + "strum 0.24.1", +] + +[[package]] +name = "fuel-core" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b030e12851d70598e12722886b899e28884d168367fc20d9a809951dd599004" +dependencies = [ + "anyhow", + "async-graphql", + "async-trait", + "axum", + "clap 4.5.4", + "derive_more", + "enum-iterator", + "fuel-core-chain-config", + "fuel-core-consensus-module", + "fuel-core-database", + "fuel-core-executor", + "fuel-core-importer", + "fuel-core-metrics", + "fuel-core-p2p", + "fuel-core-poa", + "fuel-core-producer", + "fuel-core-relayer", + "fuel-core-services", + "fuel-core-storage", + "fuel-core-sync", + "fuel-core-txpool", + "fuel-core-types", + "fuel-core-upgradable-executor", + "futures", + "hex", + "hyper", + "indicatif", + "itertools 0.12.1", + "num_cpus", + "rand", + "rocksdb", + "serde", + "serde_json", + "strum 0.25.0", + "strum_macros 0.25.3", + "tempfile", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "tower-http", + "tracing", + "uuid", +] + +[[package]] +name = "fuel-core-bin" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f5ff2b6ce36b11e79f338b22fe436962d8d587b60a8d751c6bef2b7cb5d89bb" +dependencies = [ + "anyhow", + "async-trait", + "clap 4.5.4", + "const_format", + "dirs", + "dotenvy", + "fuel-core", + "fuel-core-chain-config", + "fuel-core-types", + "hex", + "humantime", + "pyroscope", + "pyroscope_pprofrs", + "serde_json", + "tikv-jemallocator", + "tokio", + "tokio-util", + "tracing", + "tracing-subscriber", + "url", +] + +[[package]] +name = "fuel-core-chain-config" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d202fe1dfeb98882bdc5a0206a58e469d76fd09d952c4050bb979102bd690398" +dependencies = [ + "anyhow", + "bech32", + "derivative", + "fuel-core-storage", + "fuel-core-types", + "itertools 0.12.1", + "postcard", + "serde", + "serde_json", + "serde_with", + "tracing", +] + +[[package]] +name = "fuel-core-consensus-module" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f99179c08972efffe7628f0ff8d59028218b126347a6f9eba86f71e20966eeb" +dependencies = [ + "anyhow", + "fuel-core-chain-config", + "fuel-core-poa", + "fuel-core-storage", + "fuel-core-types", +] + +[[package]] +name = "fuel-core-database" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5b1fd08a72609ebf0c8106359a37a4b205055be15e9f4fc30a4c0b5f0644c6b" +dependencies = [ + "anyhow", + "derive_more", + "fuel-core-storage", + "fuel-core-types", +] + +[[package]] +name = "fuel-core-executor" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f98d89798007bc781d56e02681144683f5c645ee0725e7717e38694e8e5e31d" +dependencies = [ + "anyhow", + "fuel-core-storage", + "fuel-core-types", + "hex", + "parking_lot", + "serde", + "tracing", +] + +[[package]] +name = "fuel-core-importer" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51837a53f2d8b78a701aee61b99c7f1873f23e864f01f4b4d0644a06e1f7c41" +dependencies = [ + "anyhow", + "derive_more", + "fuel-core-metrics", + "fuel-core-storage", + "fuel-core-types", + "tokio", + "tokio-rayon", + "tracing", +] + +[[package]] +name = "fuel-core-metrics" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bacc62bc4fec2fe6a818a1a7145b892bd486d69266190ca8dd31a036a3a327b7" +dependencies = [ + "axum", + "once_cell", + "pin-project-lite", + "prometheus-client", + "regex", + "tracing", +] + +[[package]] +name = "fuel-streams-publisher" +version = "0.26.0" +dependencies = [ + "anyhow", + "async-nats", + "clap 4.5.4", + "fuel-core", + "fuel-core-bin", + "fuel-core-services", + "fuel-core-types", + "serde_json", + "tokio", + "tracing", +] + +[[package]] +name = "fuel-core-p2p" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6496068f0f5736f9e51bba8f8bb04cb83f68df2f6142e410fe62854b47621b3" +dependencies = [ + "anyhow", + "async-trait", + "fuel-core-chain-config", + "fuel-core-metrics", + "fuel-core-services", + "fuel-core-storage", + "fuel-core-types", + "futures", + "hex", + "ip_network", + "libp2p", + "libp2p-mplex", + "postcard", + "prometheus-client", + "quick-protobuf", + "quick-protobuf-codec", + "rand", + "serde", + "serde_with", + "sha2 0.10.8", + "thiserror", + "tokio", + "tracing", + "void", +] + +[[package]] +name = "fuel-core-poa" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68d189ecd635688ddc896b44c8497b29c04bb4a3719a24eea0ca9691a6f76d5e" +dependencies = [ + "anyhow", + "async-trait", + "fuel-core-chain-config", + "fuel-core-services", + "fuel-core-storage", + "fuel-core-types", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "fuel-core-producer" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d2901a7ba2c0e724bbb88a3111fdb9844f5faf9f0bd4005944f61f093730b4d" +dependencies = [ + "anyhow", + "async-trait", + "derive_more", + "fuel-core-storage", + "fuel-core-types", + "tokio", + "tokio-rayon", + "tracing", +] + +[[package]] +name = "fuel-core-relayer" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da1aa686ec4a05b77f4c4dfae68e6f17701b5bc21a49a8a505c6d9dc6dcf9183" +dependencies = [ + "anyhow", + "async-trait", + "enum-iterator", + "ethers-contract", + "ethers-core", + "ethers-providers", + "fuel-core-services", + "fuel-core-storage", + "fuel-core-types", + "futures", + "once_cell", + "strum 0.25.0", + "strum_macros 0.25.3", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "fuel-core-services" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf2ab4d3931b8cafdb2e69fe8ca97918a168d74c73c070481ca0e552cc37bb93" +dependencies = [ + "anyhow", + "async-trait", + "fuel-core-metrics", + "futures", + "parking_lot", + "tokio", + "tracing", +] + +[[package]] +name = "fuel-core-storage" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e039c1c6ebef314c74c34728e1f2199dcf9ede041d6f5c6e11479517c8f4d320" +dependencies = [ + "anyhow", + "derive_more", + "enum-iterator", + "fuel-core-types", + "fuel-vm", + "impl-tools", + "itertools 0.12.1", + "num_enum", + "paste", + "postcard", + "primitive-types", + "serde", + "strum 0.25.0", + "strum_macros 0.25.3", +] + +[[package]] +name = "fuel-core-sync" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7059ee4c3dbf1e9340d7cd88eccf2e10c631306d8038ab20160e6434deb79c1b" +dependencies = [ + "anyhow", + "async-trait", + "fuel-core-services", + "fuel-core-types", + "futures", + "rand", + "tokio", + "tracing", +] + +[[package]] +name = "fuel-core-txpool" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985684e2d67d5018e9227a4f9ed79cac02b23b207e457ee95833ab047769c2ac" +dependencies = [ + "anyhow", + "async-trait", + "fuel-core-metrics", + "fuel-core-services", + "fuel-core-storage", + "fuel-core-types", + "futures", + "parking_lot", + "tokio", + "tokio-rayon", + "tokio-stream", + "tracing", +] + +[[package]] +name = "fuel-core-types" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf038dd8df8d3aa665a13295c9ef888ba8118600cccdf8fb4587410e0e102fdf" +dependencies = [ + "anyhow", + "bs58", + "derivative", + "derive_more", + "fuel-vm", + "secrecy", + "serde", + "tai64", + "thiserror", + "zeroize", +] + +[[package]] +name = "fuel-core-upgradable-executor" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc54c84a7dc13f76930761ebca391b167caa096dc2bdb2413b5a2400bf65f99d" +dependencies = [ + "anyhow", + "fuel-core-executor", + "fuel-core-storage", + "fuel-core-types", + "fuel-core-wasm-executor", + "parking_lot", + "postcard", + "tracing", + "wasmtime", +] + +[[package]] +name = "fuel-core-wasm-executor" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a201e4fa5f94efb36cda172947875483d90a88b060cb9c6f9a496313d171aae8" +dependencies = [ + "anyhow", + "fuel-core-executor", + "fuel-core-storage", + "fuel-core-types", + "postcard", + "serde", +] + +[[package]] +name = "fuel-crypto" +version = "0.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71cef93970fb8a26d3a683ae211833c6bbf391066887f501bd5859f29992b59a" +dependencies = [ + "coins-bip32", + "coins-bip39", + "ecdsa", + "ed25519-dalek", + "fuel-types", + "k256", + "lazy_static", + "p256", + "rand", + "secp256k1", + "serde", + "sha2 0.10.8", + "zeroize", +] + +[[package]] +name = "fuel-derive" +version = "0.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b85e8e508b26d088262075fcfe9921b7009c931fef1cc55fe1dafb116c99884" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "synstructure", +] + +[[package]] +name = "fuel-merkle" +version = "0.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5198b4eab5a19b0034971da88199dae7dd61806ebd8df366d6af1f17cda2e151" +dependencies = [ + "derive_more", + "digest 0.10.7", + "fuel-storage", + "hashbrown 0.13.2", + "hex", + "serde", + "sha2 0.10.8", +] + +[[package]] +name = "fuel-storage" +version = "0.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa738e9c244f3f312af09faef108ec9a285f02afcefbc579c19c242cea742dd0" + +[[package]] +name = "fuel-tx" +version = "0.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e4b4ea79ffe711af7bbf363b25f383fc6e481e652cf55a5ef8b5a458fcf4ef9" +dependencies = [ + "bitflags 2.5.0", + "derivative", + "derive_more", + "fuel-asm", + "fuel-crypto", + "fuel-merkle", + "fuel-types", + "hashbrown 0.14.5", + "itertools 0.10.5", + "postcard", + "rand", + "serde", + "serde_json", + "strum 0.24.1", + "strum_macros 0.24.3", +] + +[[package]] +name = "fuel-types" +version = "0.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "455cf5275d96f6907e81ed1825c4e6a9dd79f7c1c37a4e15134562f83024c7e7" +dependencies = [ + "fuel-derive", + "hex", + "serde", +] + +[[package]] +name = "fuel-vm" +version = "0.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8811f949db8ce61cc68dcf81644047df4ee23be55879efcfe9f1aa5adc378965" +dependencies = [ + "async-trait", + "backtrace", + "bitflags 2.5.0", + "derivative", + "derive_more", + "ethnum", + "fuel-asm", + "fuel-crypto", + "fuel-merkle", + "fuel-storage", + "fuel-tx", + "fuel-types", + "hashbrown 0.14.5", + "itertools 0.10.5", + "libm", + "paste", + "percent-encoding", + "primitive-types", + "serde", + "serde_with", + "sha3", + "static_assertions", + "strum 0.24.1", + "tai64", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-bounded" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e2774cc104e198ef3d3e1ff4ab40f86fa3245d6cb6a3a46174f21463cee173" +dependencies = [ + "futures-timer", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "futures-rustls" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd3cf68c183738046838e300353e4716c674dc5e56890de4826801a6622a28" +dependencies = [ + "futures-io", + "rustls 0.21.12", +] + +[[package]] +name = "futures-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" +dependencies = [ + "futures-io", + "rustls 0.23.8", + "rustls-pki-types", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-ticker" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9763058047f713632a52e916cc7f6a4b3fc6e9fc1ff8c5b1dc49e5a89041682e" +dependencies = [ + "futures", + "futures-timer", + "instant", +] + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" +dependencies = [ + "gloo-timers", + "send_wrapper 0.4.0", +] + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +dependencies = [ + "fallible-iterator", + "indexmap 2.2.6", + "stable_deref_trait", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", + "serde", +] + +[[package]] +name = "hashers" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2bca93b15ea5a746f220e56587f71e73c6165eab783df9e26590069953e3c30" +dependencies = [ + "fxhash", +] + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version", + "serde", + "spin 0.9.8", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[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.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "hex_fmt" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" + +[[package]] +name = "hickory-proto" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07698b8420e2f0d6447a436ba999ec85d8fbf2a398bbd737b82cac4a2e96e512" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.4.0", + "ipnet", + "once_cell", + "rand", + "socket2", + "thiserror", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "hickory-resolver" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28757f23aa75c98f254cf0405e6d8c25b831b32921b050a66692427679b1f243" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-proto", + "ipconfig", + "lru-cache", + "once_cell", + "parking_lot", + "rand", + "resolv-conf", + "smallvec", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac 0.12.1", +] + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array", + "hmac 0.8.1", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "http-range-header" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" + +[[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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[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.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +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-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls 0.21.12", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core 0.52.0", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "if-addrs" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cabb0019d51a643781ff15c9c8a3e5dedc365c47211270f4e8f82812fedd8f0a" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "if-watch" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6b0422c86d7ce0e97169cc42e04ae643caf278874a7a3c87b8150a220dc7e1e" +dependencies = [ + "async-io", + "core-foundation", + "fnv", + "futures", + "if-addrs", + "ipnet", + "log", + "rtnetlink", + "system-configuration", + "tokio", + "windows", +] + +[[package]] +name = "igd-next" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "064d90fec10d541084e7b39ead8875a5a80d9114a2b18791565253bae25f49e4" +dependencies = [ + "async-trait", + "attohttpc", + "bytes", + "futures", + "http", + "hyper", + "log", + "rand", + "tokio", + "url", + "xmltree", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-tools" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82c305b1081f1a99fda262883c788e50ab57d36c00830bdd7e0a82894ad965c" +dependencies = [ + "autocfg", + "impl-tools-lib", + "proc-macro-error", + "syn 2.0.66", +] + +[[package]] +name = "impl-tools-lib" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85d3946d886eaab0702fa0c6585adcced581513223fa9df7ccfabbd9fa331a88" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.5", + "serde", +] + +[[package]] +name = "indicatif" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ip_network" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1" + +[[package]] +name = "ipconfig" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +dependencies = [ + "socket2", + "widestring", + "windows-sys 0.48.0", + "winreg", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "jobserver" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" + +[[package]] +name = "jsonwebtoken" +version = "8.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" +dependencies = [ + "base64 0.21.7", + "pem 1.1.1", + "ring 0.16.20", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2 0.10.8", + "signature", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libflate" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ff4ae71b685bbad2f2f391fe74f6b7659a34871c08b210fdc039e43bee07d18" +dependencies = [ + "adler32", + "crc32fast", + "libflate_lz77", +] + +[[package]] +name = "libflate_lz77" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a52d3a8bfc85f250440e4424db7d857e241a3aebbbe301f3eb606ab15c39acbf" +dependencies = [ + "rle-decode-fast", +] + +[[package]] +name = "libloading" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +dependencies = [ + "cfg-if", + "windows-targets 0.52.5", +] + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libp2p" +version = "0.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681fb3f183edfbedd7a57d32ebe5dcdc0b9f94061185acf3c30249349cc6fc99" +dependencies = [ + "bytes", + "either", + "futures", + "futures-timer", + "getrandom", + "instant", + "libp2p-allow-block-list", + "libp2p-connection-limits", + "libp2p-core", + "libp2p-dns", + "libp2p-gossipsub", + "libp2p-identify", + "libp2p-identity", + "libp2p-kad", + "libp2p-mdns", + "libp2p-metrics", + "libp2p-noise", + "libp2p-quic", + "libp2p-request-response", + "libp2p-swarm", + "libp2p-tcp", + "libp2p-upnp", + "libp2p-websocket", + "libp2p-yamux", + "multiaddr", + "pin-project", + "rw-stream-sink", + "thiserror", +] + +[[package]] +name = "libp2p-allow-block-list" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "107b238b794cb83ab53b74ad5dcf7cca3200899b72fe662840cfb52f5b0a32e6" +dependencies = [ + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "void", +] + +[[package]] +name = "libp2p-connection-limits" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7cd50a78ccfada14de94cbacd3ce4b0138157f376870f13d3a8422cd075b4fd" +dependencies = [ + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "void", +] + +[[package]] +name = "libp2p-core" +version = "0.41.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8130a8269e65a2554d55131c770bdf4bcd94d2b8d4efb24ca23699be65066c05" +dependencies = [ + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "libp2p-identity", + "multiaddr", + "multihash", + "multistream-select", + "once_cell", + "parking_lot", + "pin-project", + "quick-protobuf", + "rand", + "rw-stream-sink", + "smallvec", + "thiserror", + "tracing", + "unsigned-varint 0.8.0", + "void", +] + +[[package]] +name = "libp2p-dns" +version = "0.41.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d17cbcf7160ff35c3e8e560de4a068fe9d6cb777ea72840e48eb76ff9576c4b6" +dependencies = [ + "async-trait", + "futures", + "hickory-resolver", + "libp2p-core", + "libp2p-identity", + "parking_lot", + "smallvec", + "tracing", +] + +[[package]] +name = "libp2p-gossipsub" +version = "0.46.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d665144a616dadebdc5fff186b1233488cdcd8bfb1223218ff084b6d052c94f7" +dependencies = [ + "asynchronous-codec 0.7.0", + "base64 0.21.7", + "byteorder", + "bytes", + "either", + "fnv", + "futures", + "futures-ticker", + "getrandom", + "hex_fmt", + "instant", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "prometheus-client", + "quick-protobuf", + "quick-protobuf-codec", + "rand", + "regex", + "sha2 0.10.8", + "smallvec", + "tracing", + "void", +] + +[[package]] +name = "libp2p-identify" +version = "0.44.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5d635ebea5ca0c3c3e77d414ae9b67eccf2a822be06091b9c1a0d13029a1e2f" +dependencies = [ + "asynchronous-codec 0.7.0", + "either", + "futures", + "futures-bounded", + "futures-timer", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "lru", + "quick-protobuf", + "quick-protobuf-codec", + "smallvec", + "thiserror", + "tracing", + "void", +] + +[[package]] +name = "libp2p-identity" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "999ec70441b2fb35355076726a6bc466c932e9bdc66f6a11c6c0aa17c7ab9be0" +dependencies = [ + "asn1_der", + "bs58", + "ed25519-dalek", + "hkdf", + "libsecp256k1", + "multihash", + "quick-protobuf", + "rand", + "sha2 0.10.8", + "thiserror", + "tracing", + "zeroize", +] + +[[package]] +name = "libp2p-kad" +version = "0.45.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc5767727d062c4eac74dd812c998f0e488008e82cce9c33b463d38423f9ad2" +dependencies = [ + "arrayvec", + "asynchronous-codec 0.7.0", + "bytes", + "either", + "fnv", + "futures", + "futures-bounded", + "futures-timer", + "instant", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "quick-protobuf", + "quick-protobuf-codec", + "rand", + "sha2 0.10.8", + "smallvec", + "thiserror", + "tracing", + "uint", + "void", +] + +[[package]] +name = "libp2p-mdns" +version = "0.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49007d9a339b3e1d7eeebc4d67c05dbf23d300b7d091193ec2d3f26802d7faf2" +dependencies = [ + "data-encoding", + "futures", + "hickory-proto", + "if-watch", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "rand", + "smallvec", + "socket2", + "tokio", + "tracing", + "void", +] + +[[package]] +name = "libp2p-metrics" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdac91ae4f291046a3b2660c039a2830c931f84df2ee227989af92f7692d3357" +dependencies = [ + "futures", + "instant", + "libp2p-core", + "libp2p-gossipsub", + "libp2p-identify", + "libp2p-identity", + "libp2p-kad", + "libp2p-swarm", + "pin-project", + "prometheus-client", +] + +[[package]] +name = "libp2p-mplex" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e895765e27e30217b25f7cb7ac4686dad1ff80bf2fdeffd1d898566900a924" +dependencies = [ + "asynchronous-codec 0.6.2", + "bytes", + "futures", + "libp2p-core", + "libp2p-identity", + "nohash-hasher", + "parking_lot", + "rand", + "smallvec", + "tracing", + "unsigned-varint 0.7.2", +] + +[[package]] +name = "libp2p-noise" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecd0545ce077f6ea5434bcb76e8d0fe942693b4380aaad0d34a358c2bd05793" +dependencies = [ + "asynchronous-codec 0.7.0", + "bytes", + "curve25519-dalek", + "futures", + "libp2p-core", + "libp2p-identity", + "multiaddr", + "multihash", + "once_cell", + "quick-protobuf", + "rand", + "sha2 0.10.8", + "snow", + "static_assertions", + "thiserror", + "tracing", + "x25519-dalek", + "zeroize", +] + +[[package]] +name = "libp2p-quic" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c67296ad4e092e23f92aea3d2bdb6f24eab79c0929ed816dfb460ea2f4567d2b" +dependencies = [ + "bytes", + "futures", + "futures-timer", + "if-watch", + "libp2p-core", + "libp2p-identity", + "libp2p-tls", + "parking_lot", + "quinn", + "rand", + "ring 0.17.8", + "rustls 0.23.8", + "socket2", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "libp2p-request-response" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6946e5456240b3173187cc37a17cb40c3cd1f7138c76e2c773e0d792a42a8de1" +dependencies = [ + "async-trait", + "futures", + "futures-bounded", + "futures-timer", + "instant", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "rand", + "smallvec", + "tracing", + "void", +] + +[[package]] +name = "libp2p-swarm" +version = "0.44.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80cae6cb75f89dbca53862f9ebe0b9f463aa7b302762fcfaafb9e51dcc9b0f7e" +dependencies = [ + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm-derive", + "lru", + "multistream-select", + "once_cell", + "rand", + "smallvec", + "tokio", + "tracing", + "void", +] + +[[package]] +name = "libp2p-swarm-derive" +version = "0.34.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5daceb9dd908417b6dfcfe8e94098bc4aac54500c282e78120b885dadc09b999" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "libp2p-tcp" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2460fc2748919adff99ecbc1aab296e4579e41f374fb164149bd2c9e529d4c" +dependencies = [ + "futures", + "futures-timer", + "if-watch", + "libc", + "libp2p-core", + "libp2p-identity", + "socket2", + "tokio", + "tracing", +] + +[[package]] +name = "libp2p-tls" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "251b17aebdd29df7e8f80e4d94b782fae42e934c49086e1a81ba23b60a8314f2" +dependencies = [ + "futures", + "futures-rustls 0.26.0", + "libp2p-core", + "libp2p-identity", + "rcgen", + "ring 0.17.8", + "rustls 0.23.8", + "rustls-webpki 0.101.7", + "thiserror", + "x509-parser", + "yasna", +] + +[[package]] +name = "libp2p-upnp" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccf04b0e3ff3de52d07d5fd6c3b061d0e7f908ffc683c32d9638caedce86fc8" +dependencies = [ + "futures", + "futures-timer", + "igd-next", + "libp2p-core", + "libp2p-swarm", + "tokio", + "tracing", + "void", +] + +[[package]] +name = "libp2p-websocket" +version = "0.43.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4846d51afd08180e164291c3754ba30dd4fbac6fac65571be56403c16431a5e" +dependencies = [ + "either", + "futures", + "futures-rustls 0.24.0", + "libp2p-core", + "libp2p-identity", + "parking_lot", + "pin-project-lite", + "rw-stream-sink", + "soketto", + "tracing", + "url", + "webpki-roots", +] + +[[package]] +name = "libp2p-yamux" +version = "0.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200cbe50349a44760927d50b431d77bed79b9c0a3959de1af8d24a63434b71e5" +dependencies = [ + "either", + "futures", + "libp2p-core", + "thiserror", + "tracing", + "yamux 0.12.1", + "yamux 0.13.2", +] + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.5.0", + "libc", +] + +[[package]] +name = "librocksdb-sys" +version = "0.11.0+8.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e" +dependencies = [ + "bindgen", + "bzip2-sys", + "cc", + "glob", + "libc", + "libz-sys", + "lz4-sys", +] + +[[package]] +name = "libsecp256k1" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" +dependencies = [ + "arrayref", + "base64 0.13.1", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libz-sys" +version = "1.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "lru" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "lz4-sys" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matchit" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "memfd" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" +dependencies = [ + "rustix", +] + +[[package]] +name = "memmap2" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "multer" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http", + "httparse", + "log", + "memchr", + "mime", + "spin 0.9.8", + "version_check", +] + +[[package]] +name = "multiaddr" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b852bc02a2da5feed68cd14fa50d0774b92790a5bdbfa932a813926c8472070" +dependencies = [ + "arrayref", + "byteorder", + "data-encoding", + "libp2p-identity", + "multibase", + "multihash", + "percent-encoding", + "serde", + "static_assertions", + "unsigned-varint 0.7.2", + "url", +] + +[[package]] +name = "multibase" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" +dependencies = [ + "base-x", + "data-encoding", + "data-encoding-macro", +] + +[[package]] +name = "multihash" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "076d548d76a0e2a0d4ab471d0b1c36c577786dfc4471242035d97a12a735c492" +dependencies = [ + "core2", + "unsigned-varint 0.7.2", +] + +[[package]] +name = "multistream-select" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea0df8e5eec2298a62b326ee4f0d7fe1a6b90a09dfcf9df37b38f947a8c42f19" +dependencies = [ + "bytes", + "futures", + "log", + "pin-project", + "smallvec", + "unsigned-varint 0.7.2", +] + +[[package]] +name = "names" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bddcd3bf5144b6392de80e04c347cd7fab2508f6df16a85fc496ecd5cec39bc" +dependencies = [ + "clap 3.2.25", + "rand", +] + +[[package]] +name = "netlink-packet-core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "345b8ab5bd4e71a2986663e88c56856699d060e78e152e6e9d7966fcd5491297" +dependencies = [ + "anyhow", + "byteorder", + "libc", + "netlink-packet-utils", +] + +[[package]] +name = "netlink-packet-route" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9ea4302b9759a7a88242299225ea3688e63c85ea136371bb6cf94fd674efaab" +dependencies = [ + "anyhow", + "bitflags 1.3.2", + "byteorder", + "libc", + "netlink-packet-core", + "netlink-packet-utils", +] + +[[package]] +name = "netlink-packet-utils" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ede8a08c71ad5a95cdd0e4e52facd37190977039a4704eb82a283f713747d34" +dependencies = [ + "anyhow", + "byteorder", + "paste", + "thiserror", +] + +[[package]] +name = "netlink-proto" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65b4b14489ab424703c092062176d52ba55485a89c076b4f9db05092b7223aa6" +dependencies = [ + "bytes", + "futures", + "log", + "netlink-packet-core", + "netlink-sys", + "thiserror", + "tokio", +] + +[[package]] +name = "netlink-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "416060d346fbaf1f23f9512963e3e878f1a78e707cb699ba9215761754244307" +dependencies = [ + "bytes", + "futures", + "libc", + "log", + "tokio", +] + +[[package]] +name = "nix" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", +] + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", +] + +[[package]] +name = "nkeys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc522a19199a0795776406619aa6aa78e1e55690fbeb3181b8db5265fd0e89ce" +dependencies = [ + "data-encoding", + "ed25519", + "ed25519-dalek", + "getrandom", + "log", + "rand", + "signatory", +] + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "nuid" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc895af95856f929163a0aa20c26a78d26bfdc839f51b9d5aa7a5b79e52b7e83" +dependencies = [ + "rand", +] + +[[package]] +name = "num-bigint" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.9", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +dependencies = [ + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "crc32fast", + "hashbrown 0.14.5", + "indexmap 2.2.6", + "memchr", +] + +[[package]] +name = "oid-registry" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c958dd45046245b9c3c2547369bb634eb461670b2e7e0de552905801a648d1d" +dependencies = [ + "asn1-rs", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "open-fastrlp" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", + "ethereum-types", + "open-fastrlp-derive", +] + +[[package]] +name = "open-fastrlp-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" +dependencies = [ + "bytes", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "os_str_bytes" +version = "6.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2 0.10.8", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" +dependencies = [ + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.5", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest 0.10.7", + "hmac 0.12.1", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "pem" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" +dependencies = [ + "base64 0.22.1", + "serde", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pharos" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" +dependencies = [ + "futures", + "rustc_version", +] + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "platforms" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" + +[[package]] +name = "polling" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645493cf344456ef24219d02a768cf1fb92ddf8c92161679ae3d91b91a637be3" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.3.9", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + +[[package]] +name = "postcard" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" +dependencies = [ + "cobs", + "embedded-io", + "heapless", + "serde", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "pprof" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978385d59daf9269189d052ca8a84c1acfd0715c0599a5d5188d4acc078ca46a" +dependencies = [ + "backtrace", + "cfg-if", + "findshlibs", + "libc", + "log", + "nix 0.26.4", + "once_cell", + "parking_lot", + "smallvec", + "symbolic-demangle", + "tempfile", + "thiserror", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettyplease" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +dependencies = [ + "proc-macro2", + "syn 2.0.66", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", +] + +[[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 1.0.109", + "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.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prometheus-client" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ca959da22a332509f2a73ae9e5f23f9dcfc31fd3a54d71f159495bd5909baa" +dependencies = [ + "dtoa", + "itoa", + "parking_lot", + "prometheus-client-derive-encode", +] + +[[package]] +name = "prometheus-client-derive-encode" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "proptest" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +dependencies = [ + "bitflags 2.5.0", + "lazy_static", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax 0.8.3", + "unarray", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools 0.10.5", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "psm" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +dependencies = [ + "cc", +] + +[[package]] +name = "pyroscope" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac8a53ce01af1087eaeee6ce7c4fbf50ea4040ab1825c0115c4bafa039644ba9" +dependencies = [ + "json", + "libc", + "libflate", + "log", + "names", + "prost", + "reqwest", + "thiserror", + "url", + "winapi", +] + +[[package]] +name = "pyroscope_pprofrs" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f010b2a981a7f8449a650f25f309e520b5206ea2d89512dcb146aaa5518ff4" +dependencies = [ + "log", + "pprof", + "pyroscope", + "thiserror", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-protobuf" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" +dependencies = [ + "byteorder", +] + +[[package]] +name = "quick-protobuf-codec" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15a0580ab32b169745d7a39db2ba969226ca16738931be152a3209b409de2474" +dependencies = [ + "asynchronous-codec 0.7.0", + "bytes", + "quick-protobuf", + "thiserror", + "unsigned-varint 0.8.0", +] + +[[package]] +name = "quinn" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904e3d3ba178131798c6d9375db2b13b34337d489b089fc5ba0825a2ff1bee73" +dependencies = [ + "bytes", + "futures-io", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls 0.23.8", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e974563a4b1c2206bbc61191ca4da9c22e4308b4c455e8906751cc7828393f08" +dependencies = [ + "bytes", + "rand", + "ring 0.17.8", + "rustc-hash", + "rustls 0.23.8", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + +[[package]] +name = "quinn-udp" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4f0def2590301f4f667db5a77f9694fb004f82796dc1a8b1508fafa3d0e8b72" +dependencies = [ + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rcgen" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52c4f3084aa3bc7dfbba4eff4fab2a54db4324965d8872ab933565e6fbd83bc6" +dependencies = [ + "pem 3.0.4", + "ring 0.16.20", + "time", + "yasna", +] + +[[package]] +name = "redox_syscall" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +dependencies = [ + "bitflags 2.5.0", +] + +[[package]] +name = "redox_users" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regalloc2" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6" +dependencies = [ + "hashbrown 0.13.2", + "log", + "rustc-hash", + "slice-group-by", + "smallvec", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.21.12", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-rustls 0.24.1", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "winreg", +] + +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac 0.12.1", + "subtle", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "rle-decode-fast" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rlp-derive", + "rustc-hex", +] + +[[package]] +name = "rlp-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rocksdb" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe" +dependencies = [ + "libc", + "librocksdb-sys", +] + +[[package]] +name = "rtnetlink" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322c53fd76a18698f1c27381d58091de3a043d356aa5bd0d510608b565f469a0" +dependencies = [ + "futures", + "log", + "netlink-packet-route", + "netlink-proto", + "nix 0.24.3", + "thiserror", + "tokio", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring 0.17.8", + "rustls-webpki 0.101.7", + "sct", +] + +[[package]] +name = "rustls" +version = "0.23.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79adb16721f56eb2d843e67676896a61ce7a0fa622dc18d3e372477a029d2740" +dependencies = [ + "once_cell", + "ring 0.17.8", + "rustls-pki-types", + "rustls-webpki 0.102.4", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" +dependencies = [ + "openssl-probe", + "rustls-pemfile 2.1.2", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64 0.22.1", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "rustls-webpki" +version = "0.102.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +dependencies = [ + "ring 0.17.8", + "rustls-pki-types", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "rw-stream-sink" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8c9026ff5d2f23da5e45bbc283f156383001bfb09c4e44256d02c1a685fe9a1" +dependencies = [ + "futures", + "pin-project", + "static_assertions", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scale-info" +version = "2.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" +dependencies = [ + "cfg-if", + "derive_more", + "parity-scale-codec", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" +dependencies = [ + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4124a35fe33ae14259c490fd70fa199a32b9ce9502f2ee6bc4f81ec06fa65894" +dependencies = [ + "rand", + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" +dependencies = [ + "cc", +] + +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" +dependencies = [ + "bitflags 2.5.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +dependencies = [ + "serde", +] + +[[package]] +name = "send_wrapper" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + +[[package]] +name = "serde" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "serde_json" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_nanos" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a93142f0367a4cc53ae0fead1bcda39e85beccfad3dcd717656cacab94b12985" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "serde_spanned" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +dependencies = [ + "serde", +] + +[[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 = "serde_with" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.2.6", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" +dependencies = [ + "darling 0.20.9", + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "signatory" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1e303f8205714074f6068773f0e29527e0453937fe837c9717d066635b65f31" +dependencies = [ + "pkcs8", + "rand_core", + "signature", + "zeroize", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core", +] + +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "snow" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "850948bee068e713b8ab860fe1adc4d109676ab4c3b621fd8147f06b261f2f85" +dependencies = [ + "aes-gcm", + "blake2", + "chacha20poly1305", + "curve25519-dalek", + "rand_core", + "ring 0.17.8", + "rustc_version", + "sha2 0.10.8", + "subtle", +] + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "soketto" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +dependencies = [ + "base64 0.13.1", + "bytes", + "futures", + "httparse", + "log", + "rand", + "sha-1", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sptr" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros 0.24.3", +] + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros 0.25.3", +] + +[[package]] +name = "strum" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +dependencies = [ + "strum_macros 0.26.2", +] + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.66", +] + +[[package]] +name = "strum_macros" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.66", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "symbolic-common" +version = "12.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cccfffbc6bb3bb2d3a26cd2077f4d055f6808d266f9d4d158797a4c60510dfe" +dependencies = [ + "debugid", + "memmap2", + "stable_deref_trait", + "uuid", +] + +[[package]] +name = "symbolic-demangle" +version = "12.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a99812da4020a67e76c4eb41f08c87364c14170495ff780f30dd519c221a68" +dependencies = [ + "cpp_demangle", + "rustc-demangle", + "symbolic-common", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tai64" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed7401421025f4132e6c1f7af5e7f8287383969f36e6628016cd509b8d3da9dc" +dependencies = [ + "serde", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "target-lexicon" +version = "0.12.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" + +[[package]] +name = "thiserror" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tikv-jemalloc-sys" +version = "0.5.4+5.3.0-patched" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9402443cb8fd499b6f327e40565234ff34dbda27460c5b47db0db77443dd85d1" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "tikv-jemallocator" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965fe0c26be5c56c94e38ba547249074803efd52adfb66de62107d95aab3eaca" +dependencies = [ + "libc", + "tikv-jemalloc-sys", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "tokio-rayon" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cf33a76e0b1dd03b778f83244137bd59887abf25c0e87bc3e7071105f457693" +dependencies = [ + "rayon", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls 0.23.8", + "rustls-pki-types", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "rustls 0.21.12", + "tokio", + "tokio-rustls 0.24.1", + "tungstenite", + "webpki-roots", +] + +[[package]] +name = "tokio-util" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml" +version = "0.8.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.13", +] + +[[package]] +name = "toml_datetime" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c" +dependencies = [ + "indexmap 2.2.6", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.6.9", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" +dependencies = [ + "bitflags 1.3.2", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-range-header", + "pin-project-lite", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[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.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "futures", + "futures-task", + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tryhard" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9f0a709784e86923586cff0d872dba54cd2d2e116b3bc57587d15737cfce9d" +dependencies = [ + "futures", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand", + "rustls 0.21.12", + "sha1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-width" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "unsigned-varint" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" +dependencies = [ + "asynchronous-codec 0.6.2", + "bytes", +] + +[[package]] +name = "unsigned-varint" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna 0.5.0", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +dependencies = [ + "getrandom", +] + +[[package]] +name = "valuable" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "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.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.66", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "wasm-encoder" +version = "0.41.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "972f97a5d8318f908dded23594188a90bcd09365986b1163e66d70170e5287ae" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasmparser" +version = "0.121.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" +dependencies = [ + "bitflags 2.5.0", + "indexmap 2.2.6", + "semver", +] + +[[package]] +name = "wasmtime" +version = "18.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69472708b96ee90579a482bdbb908ce97e53a9e5ebbcab59cc29c3977bcab512" +dependencies = [ + "anyhow", + "bincode", + "bumpalo", + "cfg-if", + "gimli", + "indexmap 2.2.6", + "libc", + "log", + "object", + "once_cell", + "paste", + "rayon", + "rustix", + "serde", + "serde_derive", + "serde_json", + "target-lexicon", + "wasmparser", + "wasmtime-cache", + "wasmtime-cranelift", + "wasmtime-environ", + "wasmtime-jit-icache-coherence", + "wasmtime-runtime", + "windows-sys 0.52.0", +] + +[[package]] +name = "wasmtime-asm-macros" +version = "18.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86292d6a9bf30c669582a40c4a4b8e0b8640e951f3635ee8e0acf7f87809961e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "wasmtime-cache" +version = "18.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a180017db1233c902b992fea9484640d265f2fedf03db60eed57894cb2effcc" +dependencies = [ + "anyhow", + "base64 0.21.7", + "bincode", + "directories-next", + "log", + "rustix", + "serde", + "serde_derive", + "sha2 0.10.8", + "toml 0.5.11", + "windows-sys 0.52.0", + "zstd", +] + +[[package]] +name = "wasmtime-cranelift" +version = "18.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b57d58e220ae223855c5d030ef20753377bc716d0c81b34c1fe74c9f44268774" +dependencies = [ + "anyhow", + "cfg-if", + "cranelift-codegen", + "cranelift-control", + "cranelift-entity", + "cranelift-frontend", + "cranelift-native", + "cranelift-wasm", + "gimli", + "log", + "object", + "target-lexicon", + "thiserror", + "wasmparser", + "wasmtime-cranelift-shared", + "wasmtime-environ", + "wasmtime-versioned-export-macros", +] + +[[package]] +name = "wasmtime-cranelift-shared" +version = "18.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba2cfdfdbde42f0f3baeddb62f3555524dee9f836c96da8d466e299f75f5eee" +dependencies = [ + "anyhow", + "cranelift-codegen", + "cranelift-control", + "cranelift-native", + "gimli", + "object", + "target-lexicon", + "wasmtime-environ", +] + +[[package]] +name = "wasmtime-environ" +version = "18.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abbf3075d9ee7eb1263dc67949aced64d0f0bf27be8098d34d8e5826cf0ff0f2" +dependencies = [ + "anyhow", + "bincode", + "cranelift-entity", + "gimli", + "indexmap 2.2.6", + "log", + "object", + "serde", + "serde_derive", + "target-lexicon", + "thiserror", + "wasmparser", + "wasmtime-types", +] + +[[package]] +name = "wasmtime-jit-icache-coherence" +version = "18.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dacd2aa30fb20fd8cd0eb4e664024a1ab28a02958529fa05bf52117532a098fc" +dependencies = [ + "cfg-if", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "wasmtime-runtime" +version = "18.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d14e97c4bb36d91bcdd194745446d595e67ce8b89916806270fdbee640c747fd" +dependencies = [ + "anyhow", + "cc", + "cfg-if", + "indexmap 2.2.6", + "libc", + "log", + "mach", + "memfd", + "memoffset", + "paste", + "psm", + "rustix", + "sptr", + "wasm-encoder", + "wasmtime-asm-macros", + "wasmtime-environ", + "wasmtime-versioned-export-macros", + "wasmtime-wmemcheck", + "windows-sys 0.52.0", +] + +[[package]] +name = "wasmtime-types" +version = "18.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "530b94c627a454d24f520173d3145112d1b807c44c82697a57e1d8e28390cde4" +dependencies = [ + "cranelift-entity", + "serde", + "serde_derive", + "thiserror", + "wasmparser", +] + +[[package]] +name = "wasmtime-versioned-export-macros" +version = "18.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5399c175ddba4a471b9da45105dea3493059d52b2d54860eadb0df04c813948d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "wasmtime-wmemcheck" +version = "18.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1711f429111e782fac0537e0b3eb2ab6f821613cf1ec3013f2a0ff3fde41745" + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "widestring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" + +[[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.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys 0.52.0", +] + +[[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" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" +dependencies = [ + "windows-core 0.51.1", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86c949fede1d13936a99f14fafd3e76fd642b556dd2ce96287fbe2e0151bfac6" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "ws_stream_wasm" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" +dependencies = [ + "async_io_stream", + "futures", + "js-sys", + "log", + "pharos", + "rustc_version", + "send_wrapper 0.6.0", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x25519-dalek" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +dependencies = [ + "curve25519-dalek", + "rand_core", + "serde", + "zeroize", +] + +[[package]] +name = "x509-parser" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" +dependencies = [ + "asn1-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom", + "oid-registry", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "xml-rs" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" + +[[package]] +name = "xmltree" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb" +dependencies = [ + "xml-rs", +] + +[[package]] +name = "yamux" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed0164ae619f2dc144909a9f082187ebb5893693d8c0196e8085283ccd4b776" +dependencies = [ + "futures", + "log", + "nohash-hasher", + "parking_lot", + "pin-project", + "rand", + "static_assertions", +] + +[[package]] +name = "yamux" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f97202f6b125031b95d83e01dc57292b529384f80bfae4677e4bbc10178cf72" +dependencies = [ + "futures", + "instant", + "log", + "nohash-hasher", + "parking_lot", + "pin-project", + "rand", + "static_assertions", +] + +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", +] + +[[package]] +name = "zerocopy" +version = "0.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.10+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/crates/sv-emitter/Cargo.toml b/crates/sv-emitter/Cargo.toml new file mode 100644 index 00000000..7433d14e --- /dev/null +++ b/crates/sv-emitter/Cargo.toml @@ -0,0 +1,51 @@ +[package] +name = "sv-emitter" +description = "Service that emitts new blocks using fuel-core block subscription" +authors = { workspace = true } +keywords = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +version = { workspace = true } +rust-version = { workspace = true } +publish = false + +[[bin]] +name = "sv-emitter" +path = "src/main.rs" + +[dependencies] +anyhow = { workspace = true } +async-nats = { workspace = true } +clap = { workspace = true } +fuel-core = { workspace = true, default-features = false, features = ["p2p", "relayer", "rocksdb"] } +fuel-core-bin = { workspace = true, default-features = false, features = [ + "p2p", + "relayer", + "rocksdb", +] } +fuel-core-types = { workspace = true, default-features = false, features = ["std", "serde"] } +fuel-streams-core = { workspace = true, features = ["test-helpers"] } +fuel-streams-executors = { workspace = true, features = ["test-helpers"] } +futures = { workspace = true } +thiserror = { workspace = true } +tokio = { workspace = true } +tokio-util = "0.7.13" +tracing = { workspace = true } + +[features] +default = [] +test-helpers = [] + +[target.x86_64-unknown-linux-gnu.dependencies] +openssl = { version = "0.10.68", features = ["vendored"] } + +[target.x86_64-unknown-linux-musl.dependencies] +openssl = { version = "0.10.68", features = ["vendored"] } + +[target.aarch64-unknown-linux-gnu.dependencies] +openssl = { version = "0.10.68", features = ["vendored"] } + +[target.aarch64-unknown-linux-musl.dependencies] +openssl = { version = "0.10.68", features = ["vendored"] } diff --git a/crates/sv-emitter/src/cli.rs b/crates/sv-emitter/src/cli.rs new file mode 100644 index 00000000..377b3f2f --- /dev/null +++ b/crates/sv-emitter/src/cli.rs @@ -0,0 +1,24 @@ +//! This binary subscribes to events emitted from a Fuel client or node +//! to publish streams that can consumed via the `fuel-streams` SDK. + +use clap::Parser; + +/// CLI structure for parsing command-line arguments. +/// +/// - `network`: The fuel network we want to connect to. +/// - `fuel_core_config`: Configuration for the Fuel Core service, parsed using a flattened command. +#[derive(Clone, Parser)] +pub struct Cli { + /// Fuel Network to connect to. + #[arg( + long, + value_name = "NATS_URL", + env = "NATS_URL", + default_value = "localhost:4222", + help = "NATS URL to connect to." + )] + pub nats_url: String, + /// Flattened command structure for Fuel Core configuration. + #[command(flatten)] + pub fuel_core_config: fuel_core_bin::cli::run::Command, +} diff --git a/crates/sv-emitter/src/lib.rs b/crates/sv-emitter/src/lib.rs new file mode 100644 index 00000000..5bf4a4b0 --- /dev/null +++ b/crates/sv-emitter/src/lib.rs @@ -0,0 +1,2 @@ +pub mod cli; +pub mod shutdown; diff --git a/crates/sv-emitter/src/main.rs b/crates/sv-emitter/src/main.rs new file mode 100644 index 00000000..b7bd5bdc --- /dev/null +++ b/crates/sv-emitter/src/main.rs @@ -0,0 +1,205 @@ +use std::{sync::Arc, time::Duration}; + +use async_nats::jetstream::{ + context::PublishErrorKind, + stream::RetentionPolicy, + Context, +}; +use clap::Parser; +use fuel_core_types::blockchain::SealedBlock; +use fuel_streams_core::prelude::*; +use fuel_streams_executors::*; +use futures::StreamExt; +use sv_emitter::{cli::Cli, shutdown::ShutdownController}; +use thiserror::Error; +use tokio_util::sync::CancellationToken; + +#[derive(Error, Debug)] +pub enum LiveBlockProcessingError { + #[error("Failed to publish block: {0}")] + PublishError(#[from] PublishError), + + #[error("Processing was cancelled")] + Cancelled, +} + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let cli = Cli::parse(); + let config = cli.fuel_core_config; + let fuel_core: Arc = FuelCore::new(config).await?; + fuel_core.start().await?; + + let nats_client = setup_nats(&cli.nats_url).await?; + let last_block_height = Arc::new(fuel_core.get_latest_block_height()?); + let last_published = + Arc::new(find_last_published_height(&nats_client).await?); + + let shutdown = Arc::new(ShutdownController::new()); + shutdown.clone().spawn_signal_handler(); + + tracing::info!("Last published height: {}", last_published); + tracing::info!("Last block height: {}", last_block_height); + + tokio::select! { + result = async { + let historical = process_historical_blocks( + &nats_client, + fuel_core.clone(), + last_block_height, + last_published, + shutdown.token().clone(), + ); + + let live = process_live_blocks( + &nats_client.jetstream, + fuel_core.clone(), + shutdown.token().clone(), + ); + + tokio::join!(historical, live) + } => { + result.0?; + result.1?; + } + _ = shutdown.wait_for_shutdown() => { + tracing::info!("Shutdown signal received, waiting for processing to complete..."); + fuel_core.stop().await + } + } + + tracing::info!("Shutdown complete"); + Ok(()) +} + +async fn setup_nats(nats_url: &str) -> anyhow::Result { + let opts = NatsClientOpts::admin_opts(None) + .with_custom_url(nats_url.to_string()) + .with_domain("CORE".to_string()); + let nats_client = NatsClient::connect(&opts).await?; + let stream_name = nats_client.namespace.stream_name("block_importer"); + nats_client + .jetstream + .get_or_create_stream(async_nats::jetstream::stream::Config { + name: stream_name, + subjects: vec!["block_submitted.>".to_string()], + retention: RetentionPolicy::WorkQueue, + duplicate_window: Duration::from_secs(1), + ..Default::default() + }) + .await?; + + Ok(nats_client) +} + +async fn find_last_published_height( + nats_client: &NatsClient, +) -> anyhow::Result { + let block_stream = Stream::::get_or_init(nats_client).await; + let last_publish_height = block_stream + .get_last_published(BlocksSubject::WILDCARD) + .await?; + match last_publish_height { + Some(block) => Ok(block.height), + None => Ok(0), + } +} + +fn get_historical_block_range( + last_published_height: Arc, + last_block_height: Arc, +) -> Option> { + let last_published_height = *last_published_height; + let last_block_height = *last_block_height; + let start_height = last_published_height + 1; + let end_height = last_block_height; + if start_height > end_height { + tracing::info!("No historical blocks to process"); + return None; + } + let block_count = end_height - start_height + 1; + let heights: Vec = (start_height..=end_height).collect(); + tracing::info!( + "Processing {block_count} historical blocks from height {start_height} to {end_height}" + ); + Some(heights) +} + +fn process_historical_blocks( + nats_client: &NatsClient, + fuel_core: Arc, + last_block_height: Arc, + last_published_height: Arc, + token: CancellationToken, +) -> tokio::task::JoinHandle<()> { + let jetstream = nats_client.jetstream.clone(); + tokio::spawn(async move { + let Some(heights) = get_historical_block_range( + last_published_height, + last_block_height, + ) else { + return; + }; + futures::stream::iter(heights) + .map(|height| { + let jetstream = jetstream.clone(); + let fuel_core = fuel_core.clone(); + let sealed_block = fuel_core.get_sealed_block_by_height(height); + let sealed_block = Arc::new(sealed_block); + async move { + publish_block(&jetstream, &fuel_core, &sealed_block).await + } + }) + .buffer_unordered(100) + .take_until(token.cancelled()) + .collect::>() + .await; + }) +} + +async fn process_live_blocks( + jetstream: &Context, + fuel_core: Arc, + token: CancellationToken, +) -> Result<(), LiveBlockProcessingError> { + let mut subscription = fuel_core.blocks_subscription(); + while let Ok(data) = subscription.recv().await { + if token.is_cancelled() { + break; + } + let sealed_block = Arc::new(data.sealed_block.clone()); + publish_block(jetstream, &fuel_core, &sealed_block).await?; + } + Ok(()) +} + +#[derive(Error, Debug)] +pub enum PublishError { + #[error("Failed to publish block to NATS server: {0}")] + NatsPublish(#[from] async_nats::error::Error), + + #[error("Failed to create block payload due to: {0}")] + BlockPayload(#[from] ExecutorError), + + #[error("Failed to access offchain database: {0}")] + OffchainDatabase(String), +} + +async fn publish_block( + jetstream: &Context, + fuel_core: &Arc, + sealed_block: &Arc, +) -> Result<(), PublishError> { + let metadata = Metadata::new(fuel_core, sealed_block); + let fuel_core = Arc::clone(fuel_core); + let payload = BlockPayload::new(fuel_core, sealed_block, &metadata)?; + jetstream + .send_publish(payload.subject(), payload.to_owned().try_into()?) + .await + .map_err(PublishError::NatsPublish)? + .await + .map_err(PublishError::NatsPublish)?; + + tracing::info!("New block submitted: {}", payload.block_height()); + Ok(()) +} diff --git a/crates/sv-emitter/src/shutdown.rs b/crates/sv-emitter/src/shutdown.rs new file mode 100644 index 00000000..6d66e7b1 --- /dev/null +++ b/crates/sv-emitter/src/shutdown.rs @@ -0,0 +1,104 @@ +use std::sync::Arc; + +use tokio_util::sync::CancellationToken; + +#[derive(Clone)] +pub struct ShutdownController { + token: CancellationToken, +} + +impl Default for ShutdownController { + fn default() -> Self { + Self::new() + } +} + +impl ShutdownController { + pub fn new() -> Self { + Self { + token: CancellationToken::new(), + } + } + + pub fn token(&self) -> &CancellationToken { + &self.token + } + + pub fn spawn_signal_handler(self: Arc) -> Arc { + tokio::spawn({ + let shutdown = self.clone(); + async move { + tokio::signal::ctrl_c() + .await + .expect("Failed to listen for ctrl+c"); + tracing::info!("Received shutdown signal"); + shutdown.initiate_shutdown(); + } + }); + self + } + + pub fn initiate_shutdown(&self) { + tracing::info!("Initiating graceful shutdown..."); + self.token.cancel(); + } + + pub fn is_shutdown_initiated(&self) -> bool { + self.token.is_cancelled() + } + + pub async fn wait_for_shutdown(&self) { + self.token.cancelled().await; + } +} + +#[cfg(test)] +mod tests { + use std::time::Duration; + + use super::*; + + #[tokio::test] + async fn test_manual_shutdown() { + let controller = ShutdownController::new(); + assert!( + !controller.is_shutdown_initiated(), + "Controller should not be shutdown initially" + ); + + controller.initiate_shutdown(); + assert!( + controller.is_shutdown_initiated(), + "Controller should be shutdown after initiation" + ); + } + + #[tokio::test] + async fn test_wait_for_shutdown_timeout() { + let controller = ShutdownController::new(); + + let timeout = Duration::from_millis(50); + let result = + tokio::time::timeout(timeout, controller.wait_for_shutdown()).await; + + assert!( + result.is_err(), + "wait_for_shutdown should not complete without initiation" + ); + } + + #[tokio::test] + async fn test_clone_behavior() { + let controller = ShutdownController::new(); + let cloned = controller.clone(); + + // Initiate shutdown from clone + cloned.initiate_shutdown(); + + assert!( + controller.is_shutdown_initiated(), + "Original should be shutdown" + ); + assert!(cloned.is_shutdown_initiated(), "Clone should be shutdown"); + } +} diff --git a/examples/multiple-streams.rs b/examples/multiple-streams.rs index 0511434b..ebc0e5c0 100644 --- a/examples/multiple-streams.rs +++ b/examples/multiple-streams.rs @@ -274,25 +274,6 @@ async fn stream_contract( ReceiptsMintSubject::new().with_contract_id(Some(contract_id.into())), ); - let mut sub = receipt_stream.subscribe().await?; - - while let Some(bytes) = sub.next().await { - let decoded_msg = Receipt::decode_raw(bytes.unwrap().to_vec()).await; - let receipt = decoded_msg.payload; - - // Check if the receipt has a contract_id and if it matches our target - if let Some(receipt_contract_id) = &receipt.contract_id { - if *receipt_contract_id == contract_id.into() { - let receipt_subject = decoded_msg.subject; - let receipt_published_at = decoded_msg.timestamp; - println!( - "Received contract receipt: data={:?}, subject={}, published_at={}", - receipt, receipt_subject, receipt_published_at - ); - } - } - } - Ok(()) } diff --git a/scripts/run_publisher.sh b/scripts/run_publisher.sh index 7d29d677..b6240036 100755 --- a/scripts/run_publisher.sh +++ b/scripts/run_publisher.sh @@ -28,6 +28,13 @@ usage() { exit 1 } +# Set default values from environment variables with fallbacks +NETWORK=${NETWORK:-"testnet"} +MODE=${MODE:-"profiling"} +PORT=${PORT:-"4004"} +TELEMETRY_PORT=${TELEMETRY_PORT:-"8080"} +PACKAGE=${PACKAGE:-"fuel-streams-publisher"} + while [[ "$#" -gt 0 ]]; do case $1 in --network) @@ -63,7 +70,7 @@ done # ------------------------------ # Load Environment # ------------------------------ -source ./scripts/set_env.sh +source ./scripts/set_env.sh NETWORK=${NETWORK} # Print the configuration being used echo -e "\n==========================================" @@ -94,31 +101,33 @@ echo -e "==========================================\n" # Define common arguments COMMON_ARGS=( "--enable-relayer" + "--service-name" "fuel-${NETWORK}-node" "--keypair" "${KEYPAIR}" "--relayer" "${RELAYER}" "--ip=0.0.0.0" - "--service-name" "fuel-${NETWORK}-node" - "--db-path" "./cluster/docker/db-${NETWORK}" - "--snapshot" "./cluster/chain-config/${NETWORK}" - "--nats-url" "nats://localhost:4222" "--port" "${PORT}" - "--telemetry-port" "${TELEMETRY_PORT}" "--peering-port" "30333" + "--db-path" "./cluster/docker/db-${NETWORK}" + "--snapshot" "./cluster/chain-config/${NETWORK}" "--utxo-validation" "--poa-instant" "false" "--enable-p2p" - "--sync-header-batch-size" "${SYNC_HEADER_BATCH_SIZE}" - "--relayer-log-page-size=${RELAYER_LOG_PAGE_SIZE}" - "--sync-block-stream-buffer-size" "30" - "--bootstrap-nodes" "${RESERVED_NODES}" + "--reserved-nodes" "${RESERVED_NODES}" "--relayer-v2-listening-contracts=${RELAYER_V2_LISTENING_CONTRACTS}" "--relayer-da-deploy-height=${RELAYER_DA_DEPLOY_HEIGHT}" + "--relayer-log-page-size=${RELAYER_LOG_PAGE_SIZE}" + "--sync-block-stream-buffer-size" "50" + "--nats-url" "nats://localhost:4222" + "--max-database-cache-size" "17179869184" + "--state-rewind-duration" "136y" + "--request-timeout" "60" + "--graphql-max-complexity" "1000000000" ) # Execute based on mode if [ "$MODE" == "dev" ]; then - cargo run -p fuel-streams-publisher -- "${COMMON_ARGS[@]}" ${EXTRA_ARGS} + cargo run -p ${PACKAGE} -- "${COMMON_ARGS[@]}" ${EXTRA_ARGS} else - cargo build --profile profiling --package fuel-streams-publisher - samply record ./target/profiling/fuel-streams-publisher "${COMMON_ARGS[@]}" ${EXTRA_ARGS} + cargo build --profile profiling --package ${PACKAGE} + samply record ./target/profiling/${PACKAGE} "${COMMON_ARGS[@]}" ${EXTRA_ARGS} fi diff --git a/scripts/set_env.sh b/scripts/set_env.sh index b2f56cdf..9b67f661 100755 --- a/scripts/set_env.sh +++ b/scripts/set_env.sh @@ -40,12 +40,12 @@ cleanup_env() { fi } -# Load initial environment -load_env - # Clean up previous auto-generated content cleanup_env +# Load initial environment +load_env + # Set and export network-specific variables export RESERVED_NODES=$(eval echo "\$${NETWORK_UPPER}_RESERVED_NODES") export RELAYER_V2_LISTENING_CONTRACTS=$(eval echo "\$${NETWORK_UPPER}_RELAYER_V2_LISTENING_CONTRACTS") diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 9f1c81b8..943b0e62 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -26,7 +26,7 @@ anyhow = { workspace = true } async-trait = { workspace = true } fuel-core = { workspace = true, features = ["test-helpers"] } fuel-core-importer = { workspace = true, features = ["test-helpers"] } -fuel-core-types = { workspace = true } +fuel-core-types = { workspace = true, features = ["test-helpers"] } fuel-streams = { workspace = true, features = ["test-helpers"] } fuel-streams-core = { workspace = true, features = ["test-helpers"] } fuel-streams-publisher = { workspace = true, features = ["test-helpers"] } diff --git a/tests/tests/publisher.rs b/tests/tests/publisher.rs index 42ae9e85..81620ab8 100644 --- a/tests/tests/publisher.rs +++ b/tests/tests/publisher.rs @@ -1,15 +1,15 @@ -use std::{ - collections::{HashMap, HashSet}, - sync::Arc, -}; +use std::{collections::HashMap, sync::Arc}; -use fuel_core::combined_database::CombinedDatabase; +use fuel_core::{ + combined_database::CombinedDatabase, + service::{Config, FuelService}, + ShutdownListener, +}; use fuel_core_importer::ImporterResult; use fuel_core_types::blockchain::SealedBlock; use fuel_streams_core::prelude::*; use fuel_streams_publisher::{ publisher::shutdown::ShutdownController, - FuelCoreLike, Publisher, }; use futures::StreamExt; @@ -17,6 +17,7 @@ use tokio::sync::broadcast::{self, Receiver, Sender}; // TODO - Re-implement with `mockall` and `mock` macros struct TestFuelCore { + fuel_service: FuelService, chain_id: FuelCoreChainId, base_asset_id: FuelCoreAssetId, database: CombinedDatabase, @@ -28,7 +29,15 @@ impl TestFuelCore { fn default( blocks_broadcaster: Sender, ) -> Self { + let mut shutdown = ShutdownListener::spawn(); + let service = FuelService::new( + Default::default(), + Config::local_node(), + &mut shutdown, + ) + .unwrap(); Self { + fuel_service: service, chain_id: FuelCoreChainId::default(), base_asset_id: FuelCoreAssetId::zeroed(), database: CombinedDatabase::default(), @@ -53,6 +62,9 @@ impl FuelCoreLike for TestFuelCore { fn is_started(&self) -> bool { true } + fn fuel_service(&self) -> &FuelService { + &self.fuel_service + } async fn await_synced_at_least_once( &self, _historical: bool, @@ -91,6 +103,20 @@ impl FuelCoreLike for TestFuelCore { ) -> anyhow::Result>> { Ok(self.receipts.clone()) } + + fn get_tx_status( + &self, + _tx_id: &FuelCoreBytes32, + ) -> anyhow::Result> { + Ok(Some(FuelCoreTransactionStatus::Success { + receipts: self.receipts.clone().unwrap_or_default(), + block_height: 0.into(), + result: None, + time: FuelCoreTai64::now(), + total_gas: 0, + total_fee: 0, + })) + } } #[tokio::test(flavor = "multi_thread")] @@ -240,10 +266,61 @@ async fn publishes_receipts() { .await .unwrap(); - let receipts: HashSet = receipts.iter().map(Into::into).collect(); + let expected_receipts: Vec = + receipts.iter().map(Into::into).collect(); + let mut found_receipts = Vec::new(); + while let Some(Some(receipt)) = receipts_stream.next().await { - assert!(receipts.contains(&receipt)); + found_receipts.push(receipt); } + + assert_eq!( + found_receipts.len(), + expected_receipts.len(), + "Number of receipts doesn't match" + ); + + // Create sets of receipt identifiers + let found_ids: std::collections::HashSet<_> = found_receipts + .into_iter() + .map(|r| match r { + Receipt::Call(r) => r.id, + Receipt::Return(r) => r.id, + Receipt::ReturnData(r) => r.id, + Receipt::Revert(r) => r.id, + Receipt::Log(r) => r.id, + Receipt::LogData(r) => r.id, + Receipt::Transfer(r) => r.id, + Receipt::TransferOut(r) => r.id, + Receipt::Mint(r) => r.contract_id, + Receipt::Burn(r) => r.contract_id, + Receipt::Panic(r) => r.id, + _ => unreachable!(), + }) + .collect(); + + let expected_ids: std::collections::HashSet<_> = expected_receipts + .into_iter() + .map(|r| match r { + Receipt::Call(r) => r.id, + Receipt::Return(r) => r.id, + Receipt::ReturnData(r) => r.id, + Receipt::Revert(r) => r.id, + Receipt::Log(r) => r.id, + Receipt::LogData(r) => r.id, + Receipt::Transfer(r) => r.id, + Receipt::TransferOut(r) => r.id, + Receipt::Mint(r) => r.contract_id, + Receipt::Burn(r) => r.contract_id, + Receipt::Panic(r) => r.id, + _ => unreachable!(), + }) + .collect(); + + assert_eq!( + found_ids, expected_ids, + "Published receipt IDs don't match expected IDs" + ); } #[tokio::test(flavor = "multi_thread")] From a444792cb56a26dd127c9bc22ccd7fce8d1fdf6c Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Tue, 17 Dec 2024 11:27:40 +0700 Subject: [PATCH 02/31] build(repo): Add DNS/TLS configuration for Nats (#357) * build(repo): Add DNS/TLS configuration for Nats * build(repo): bump chart version * build(repo): fix chart * build(repo): fix chart * build(repo): fix secretName on nats client websocket config --- Tiltfile | 3 +- cluster/charts/fuel-streams/Chart.yaml | 2 +- .../charts/fuel-streams/templates/_blocks.tpl | 54 +++- .../fuel-streams/templates/_helpers.tpl | 59 ++++- .../charts/fuel-streams/templates/_hpa.yaml | 3 +- .../templates/consumer/statefulset.yaml | 11 +- .../templates/nats/accounts-secret.yaml | 15 ++ .../templates/nats/certificate.yaml | 49 ++-- .../templates/nats/external-service.yaml | 21 +- .../templates/publisher/statefulset.yaml | 10 +- .../templates/secret-creator.yaml | 4 +- .../templates/service-account.yaml | 2 +- .../templates/webserver/deployment.yaml | 14 +- cluster/charts/fuel-streams/values-local.yaml | 137 ++++++++++ cluster/charts/fuel-streams/values.yaml | 237 +++++++----------- 15 files changed, 394 insertions(+), 227 deletions(-) create mode 100644 cluster/charts/fuel-streams/templates/nats/accounts-secret.yaml create mode 100644 cluster/charts/fuel-streams/values-local.yaml diff --git a/Tiltfile b/Tiltfile index 0c3a7bac..1e6622e7 100755 --- a/Tiltfile +++ b/Tiltfile @@ -104,7 +104,8 @@ k8s_yaml(helm( namespace='fuel-streams', values=[ 'cluster/charts/fuel-streams/values-publisher-secrets.yaml', - 'cluster/charts/fuel-streams/values.yaml' + 'cluster/charts/fuel-streams/values.yaml', + 'cluster/charts/fuel-streams/values-local.yaml' ] )) diff --git a/cluster/charts/fuel-streams/Chart.yaml b/cluster/charts/fuel-streams/Chart.yaml index ae02c5af..a6beaf16 100755 --- a/cluster/charts/fuel-streams/Chart.yaml +++ b/cluster/charts/fuel-streams/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 appVersion: "1.0" description: A Helm chart for Kubernetes name: fuel-streams -version: 0.4.10 +version: 0.5.6 dependencies: - name: nats version: 1.2.6 diff --git a/cluster/charts/fuel-streams/templates/_blocks.tpl b/cluster/charts/fuel-streams/templates/_blocks.tpl index fe70c729..55e3bf07 100644 --- a/cluster/charts/fuel-streams/templates/_blocks.tpl +++ b/cluster/charts/fuel-streams/templates/_blocks.tpl @@ -57,4 +57,56 @@ readinessProbe: startupProbe: {{- include "merge" (dict "context" .context "service" .service "defaultKey" "startupProbe" "path" "config.startupProbe") | nindent 2 }} {{- end }} -{{- end }} \ No newline at end of file +{{- end }} + +{{/* +Configure nats accounts +*/}} +{{- define "nats-accounts" -}} +data: + auth.conf: | + accounts { + SYS: { + users: [ + {user: $NATS_SYS_USER, password: $NATS_SYS_PASSWORD} + ] + } + ADMIN: { + jetstream: enabled + users: [ + {user: $NATS_ADMIN_USER, password: $NATS_ADMIN_PASSWORD} + ] + } + PUBLIC: { + jetstream: enabled + users: [ + { + user: $NATS_PUBLIC_USER + password: $NATS_PUBLIC_PASSWORD + permissions: { + subscribe: ">" + publish: { + deny: [ + "*.by_id.>" + "*.blocks.>" + "*.transactions.>" + "*.inputs.>" + "*.outputs.>" + "*.receipts.>" + "*.logs.>" + "*.utxos.>" + "$JS.API.STREAM.CREATE.>" + "$JS.API.STREAM.UPDATE.>" + "$JS.API.STREAM.DELETE.>" + "$JS.API.STREAM.PURGE.>" + "$JS.API.STREAM.RESTORE.>" + "$JS.API.STREAM.MSG.DELETE.>" + "$JS.API.CONSUMER.DURABLE.CREATE.>" + ] + } + } + } + ] + } + } +{{- end }} diff --git a/cluster/charts/fuel-streams/templates/_helpers.tpl b/cluster/charts/fuel-streams/templates/_helpers.tpl index 4344d0aa..24026951 100644 --- a/cluster/charts/fuel-streams/templates/_helpers.tpl +++ b/cluster/charts/fuel-streams/templates/_helpers.tpl @@ -3,6 +3,16 @@ Expand the name of the chart. If nameOverride is provided in Values.config, use that instead of .Chart.Name. The result is truncated to 63 chars and has any trailing "-" removed to comply with Kubernetes naming rules. Returns: String - The chart name, truncated and cleaned +Example: + Given: + .Chart.Name = "fuel-streams" + .Values.config.nameOverride = "custom-name" + Result: "custom-name" + + Given: + .Chart.Name = "fuel-streams" + .Values.config.nameOverride = null + Result: "fuel-streams" */}} {{- define "fuel-streams.name" -}} {{- default .Chart.Name .Values.config.nameOverride | trunc 63 | trimSuffix "-" }} @@ -17,6 +27,24 @@ This template follows these rules: - If not, concatenate release name and chart name with a hyphen The result is truncated to 63 chars and has any trailing "-" removed to comply with Kubernetes naming rules. Returns: String - The fully qualified app name, truncated and cleaned +Example: + Given: + .Values.config.fullnameOverride = "override-name" + Result: "override-name" + + Given: + .Release.Name = "my-release" + .Chart.Name = "fuel-streams" + .Values.config.nameOverride = null + .Values.config.fullnameOverride = null + Result: "my-release-fuel-streams" + + Given: + .Release.Name = "fuel-streams-prod" + .Chart.Name = "fuel-streams" + .Values.config.nameOverride = null + .Values.config.fullnameOverride = null + Result: "fuel-streams-prod" */}} {{- define "fuel-streams.fullname" -}} {{- if .Values.config.fullnameOverride }} @@ -49,26 +77,43 @@ Includes: - Selector labels (app name and instance) - App version (if defined) - Managed-by label indicating Helm management +Parameters: + - name: Optional custom name to use instead of the default name + - .: Full context (passed automatically or as "context") Returns: Map - A set of key-value pairs representing Kubernetes labels +Example: + {{- include "fuel-streams.labels" . }} + # Or with custom name: + {{- include "fuel-streams.labels" (dict "name" "custom-name" "context" $) }} */}} {{- define "fuel-streams.labels" -}} -helm.sh/chart: {{ include "fuel-streams.chart" . }} -{{ include "fuel-streams.selectorLabels" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- $context := default . .context -}} +helm.sh/chart: {{ include "fuel-streams.chart" $context }} +{{ include "fuel-streams.selectorLabels" (dict "name" .name "context" $context) }} +{{- if $context.Chart.AppVersion }} +app.kubernetes.io/version: {{ $context.Chart.AppVersion | quote }} {{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/managed-by: {{ $context.Release.Service }} {{- end }} {{/* Selector labels Core identifying labels used for object selection and service discovery. These labels should be used consistently across all related resources. +Parameters: + - name: Optional custom name to use instead of the default name + - .: Full context (passed automatically or as "context") Returns: Map - A set of key-value pairs for Kubernetes selector labels +Example: + {{- include "fuel-streams.selectorLabels" . }} + # Or with custom name: + {{- include "fuel-streams.selectorLabels" (dict "name" "custom-name" "context" $) }} */}} {{- define "fuel-streams.selectorLabels" -}} -app.kubernetes.io/name: {{ include "fuel-streams.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} +{{- $context := default . .context -}} +{{- $name := default (include "fuel-streams.name" $context) .name -}} +app.kubernetes.io/name: {{ $name }} +app.kubernetes.io/instance: {{ $context.Release.Name }} {{- end }} {{/* diff --git a/cluster/charts/fuel-streams/templates/_hpa.yaml b/cluster/charts/fuel-streams/templates/_hpa.yaml index 76482c37..2f539b35 100644 --- a/cluster/charts/fuel-streams/templates/_hpa.yaml +++ b/cluster/charts/fuel-streams/templates/_hpa.yaml @@ -9,8 +9,7 @@ kind: HorizontalPodAutoscaler metadata: {{- include "k8s.metadata" (dict "context" $context "suffix" (printf "-%s" $service.name)) | nindent 2 }} labels: - {{- include "fuel-streams.labels" $context | nindent 4 }} - app.kubernetes.io/component: {{ $service.name }} + {{- include "fuel-streams.labels" (dict "name" $service.name "context" $context) | nindent 4 }} spec: scaleTargetRef: apiVersion: apps/v1 diff --git a/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml b/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml index d0a7a370..5f15bb02 100644 --- a/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml +++ b/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml @@ -7,9 +7,8 @@ metadata: annotations: {{- include "set-value" (dict "context" $consumer "path" "config.annotations") | nindent 4 }} labels: - {{- include "fuel-streams.labels" . | nindent 4 }} + {{- include "fuel-streams.labels" (dict "name" "consumer" "context" .) | nindent 4 }} {{- include "set-value" (dict "context" $consumer "path" "config.labels") | nindent 4 }} - app.kubernetes.io/component: consumer spec: serviceName: {{ include "fuel-streams.fullname" . }}-consumer {{- if not $consumer.autoscaling.enabled }} @@ -17,18 +16,15 @@ spec: {{- end }} selector: matchLabels: - {{- include "fuel-streams.selectorLabels" . | nindent 6 }} - {{- include "set-value" (dict "context" $consumer "path" "config.selectorLabels") | nindent 6 }} - app.kubernetes.io/component: consumer + {{- include "fuel-streams.selectorLabels" (dict "name" "consumer" "context" .) | nindent 6 }} template: metadata: annotations: {{- include "set-value" (dict "context" $consumer "path" "config.podAnnotations") | nindent 8 }} labels: - {{- include "fuel-streams.selectorLabels" . | nindent 8 }} + {{- include "fuel-streams.labels" (dict "name" "consumer" "context" .) | nindent 8 }} {{- include "set-value" (dict "context" $consumer "path" "config.labels") | nindent 8 }} - app.kubernetes.io/component: consumer spec: {{- if .Values.serviceAccount.create }} @@ -79,6 +75,5 @@ spec: {{- toYaml . | nindent 12 }} {{- end }} - {{- include "k8s.hpa" (dict "context" . "service" (dict "name" "consumer" "autoscaling" $consumer.autoscaling)) }} {{- end }} diff --git a/cluster/charts/fuel-streams/templates/nats/accounts-secret.yaml b/cluster/charts/fuel-streams/templates/nats/accounts-secret.yaml new file mode 100644 index 00000000..f5b8c743 --- /dev/null +++ b/cluster/charts/fuel-streams/templates/nats/accounts-secret.yaml @@ -0,0 +1,15 @@ +{{- $secret := .Values.natsAccountsSecret }} +{{- if $secret.enabled }} +apiVersion: v1 +kind: Secret +metadata: + {{- include "k8s.metadata" (dict "context" . "suffix" "-nats-accounts") | nindent 2 }} + labels: + {{- include "fuel-streams.labels" (dict "name" "nats-accounts" "context" .) | nindent 4 }} + app.kubernetes.io/component: nats +type: Opaque +data: + {{- if $secret.data }} + {{- toYaml $secret.data | nindent 2 }} + {{- end }} +{{- end }} diff --git a/cluster/charts/fuel-streams/templates/nats/certificate.yaml b/cluster/charts/fuel-streams/templates/nats/certificate.yaml index 3425c04c..46b00bba 100644 --- a/cluster/charts/fuel-streams/templates/nats/certificate.yaml +++ b/cluster/charts/fuel-streams/templates/nats/certificate.yaml @@ -1,23 +1,48 @@ {{- $cert := .Values.natsExternalService.certificate}} {{- $service := .Values.natsExternalService.service }} {{- if and .Values.natsExternalService.enabled $service.dns }} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + {{- include "k8s.metadata" (dict "context" . "suffix" "-nats-cert") | nindent 2 }} + annotations: + {{- include "set-value" (dict "context" $cert "path" "annotations") | nindent 4 }} + labels: + {{- include "fuel-streams.labels" (dict "name" "nats-client" "context" .) | nindent 4 }} + {{- include "set-value" (dict "context" $cert "path" "labels") | nindent 4 }} + app.kubernetes.io/component: nats +spec: + secretName: {{ include "fuel-streams.fullname" . }}-nats-tls + duration: {{ $cert.duration }} + renewBefore: {{ $cert.renewBefore }} + dnsNames: + - {{ $service.dns }} + issuerRef: + name: {{ $cert.issuer }} + kind: ClusterIssuer +--- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: {{- include "k8s.metadata" (dict "context" . "suffix" "-nats-cert-validator") | nindent 2 }} labels: - {{- include "fuel-streams.labels" . | nindent 4 }} + {{- include "fuel-streams.labels" (dict "name" "nats-client" "context" .) | nindent 4 }} {{- include "set-value" (dict "context" $cert "path" "labels") | nindent 4 }} - app.kubernetes.io/service: external-ws + app.kubernetes.io/component: nats annotations: cert-manager.io/cluster-issuer: {{ $cert.issuer }} kubernetes.io/ingress.class: nginx acme.cert-manager.io/http01-ingress-class: nginx nginx.ingress.kubernetes.io/ssl-redirect: "false" nginx.ingress.kubernetes.io/force-ssl-redirect: "false" + cert-manager.io/common-name: {{ $service.dns }} {{- include "set-value" (dict "context" $cert "path" "annotations") | nindent 4 }} spec: ingressClassName: nginx + tls: + - hosts: + - {{ $service.dns }} + secretName: {{ include "fuel-streams.fullname" . }}-nats-tls rules: - host: {{ $service.dns }} http: @@ -29,24 +54,4 @@ spec: name: cm-acme-http-solver port: number: 8089 ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - {{- include "k8s.metadata" (dict "context" . "suffix" "-nats-cert") | nindent 2 }} - labels: - {{- include "fuel-streams.labels" . | nindent 4 }} - {{- include "set-value" (dict "context" $cert "path" "labels") | nindent 4 }} - app.kubernetes.io/service: external-ws - annotations: - {{- include "set-value" (dict "context" $cert "path" "annotations") | nindent 4 }} -spec: - secretName: {{ include "fuel-streams.fullname" . }}-nats-tls - duration: {{ $cert.duration }} - renewBefore: {{ $cert.renewBefore }} - dnsNames: - - {{ $service.dns }} - issuerRef: - name: {{ $cert.issuer }} - kind: ClusterIssuer {{- end }} diff --git a/cluster/charts/fuel-streams/templates/nats/external-service.yaml b/cluster/charts/fuel-streams/templates/nats/external-service.yaml index 57afb5a0..22231bbc 100644 --- a/cluster/charts/fuel-streams/templates/nats/external-service.yaml +++ b/cluster/charts/fuel-streams/templates/nats/external-service.yaml @@ -3,13 +3,9 @@ apiVersion: v1 kind: Service metadata: - {{- include "k8s.metadata" (dict "context" . "suffix" "-nats-external") | nindent 2 }} - labels: - {{- include "fuel-streams.labels" . | nindent 4 }} - {{- include "set-value" (dict "context" $service "path" "labels") | nindent 4 }} - app.kubernetes.io/service: external-ws + {{- include "k8s.metadata" (dict "context" . "suffix" "-nats-client-nlb") | nindent 2 }} annotations: - external-dns.alpha.kubernetes.io/hostname: {{ $service.dns | quote }} + external-dns.alpha.kubernetes.io/hostname: {{ $service.dns }} external-dns.alpha.kubernetes.io/cloudflare-proxied: "false" service.beta.kubernetes.io/aws-load-balancer-attributes: load_balancing.cross_zone.enabled=true service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp @@ -19,15 +15,15 @@ metadata: service.beta.kubernetes.io/aws-load-balancer-type: external service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags: "WebSocket=true" {{- include "set-value" (dict "context" $service "path" "annotations") | nindent 2 }} + labels: + {{- include "fuel-streams.labels" (dict "name" "nats-client" "context" .) | nindent 4 }} + {{- include "set-value" (dict "context" $service "path" "labels") | nindent 4 }} + app.kubernetes.io/component: nats spec: type: LoadBalancer loadBalancerClass: service.k8s.aws/nlb externalTrafficPolicy: Local ports: - - name: http-acme - port: 80 - targetPort: 8089 - protocol: TCP - appProtocol: tcp name: nats port: 4222 @@ -39,7 +35,6 @@ spec: protocol: TCP targetPort: websocket selector: - {{- include "fuel-streams.selectorLabels" . | nindent 4 }} - app.kubernetes.io/service: external-ws + {{- include "fuel-streams.selectorLabels" (dict "name" "nats-client" "context" .) | nindent 4 }} + app.kubernetes.io/component: nats {{- end }} - diff --git a/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml b/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml index 5bdbec61..85de7960 100644 --- a/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml +++ b/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml @@ -7,9 +7,8 @@ metadata: annotations: {{- include "set-value" (dict "context" $publisher "path" "config.annotations") | nindent 4 }} labels: - {{- include "fuel-streams.labels" . | nindent 4 }} + {{- include "fuel-streams.labels" (dict "name" "publisher" "context" .) | nindent 4 }} {{- include "set-value" (dict "context" $publisher "path" "config.labels") | nindent 4 }} - app.kubernetes.io/component: publisher spec: serviceName: {{ include "fuel-streams.fullname" . }}-publisher {{- if not $publisher.autoscaling.enabled }} @@ -17,18 +16,15 @@ spec: {{- end }} selector: matchLabels: - {{- include "fuel-streams.selectorLabels" . | nindent 6 }} - {{- include "set-value" (dict "context" $publisher "path" "config.selectorLabels") | nindent 6 }} - app.kubernetes.io/component: publisher + {{- include "fuel-streams.selectorLabels" (dict "name" "publisher" "context" .) | nindent 6 }} template: metadata: annotations: {{- include "set-value" (dict "context" $publisher "path" "config.podAnnotations") | nindent 8 }} labels: - {{- include "fuel-streams.selectorLabels" . | nindent 8 }} + {{- include "fuel-streams.labels" (dict "name" "publisher" "context" .) | nindent 8 }} {{- include "set-value" (dict "context" $publisher "path" "config.labels") | nindent 8 }} - app.kubernetes.io/component: publisher spec: {{- if .Values.serviceAccount.create }} diff --git a/cluster/charts/fuel-streams/templates/secret-creator.yaml b/cluster/charts/fuel-streams/templates/secret-creator.yaml index 04719e93..a64043ec 100755 --- a/cluster/charts/fuel-streams/templates/secret-creator.yaml +++ b/cluster/charts/fuel-streams/templates/secret-creator.yaml @@ -4,7 +4,7 @@ kind: Role metadata: {{- include "k8s.metadata" (dict "context" . "suffix" "-secret-creator") | nindent 2 }} labels: - {{- include "fuel-streams.labels" . | nindent 2 }} + {{- include "fuel-streams.labels" (dict "name" "secret-creator" "context" .) | nindent 2 }} rules: - apiGroups: [""] # "" indicates the core API group resources: ["pods"] @@ -20,6 +20,8 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: {{- include "k8s.metadata" (dict "context" . "suffix" "-secret-creator") | nindent 2 }} + labels: + {{- include "fuel-streams.labels" (dict "name" "secret-creator" "context" .) | nindent 2 }} subjects: - kind: ServiceAccount name: {{ include "fuel-streams.serviceAccountName" . }} diff --git a/cluster/charts/fuel-streams/templates/service-account.yaml b/cluster/charts/fuel-streams/templates/service-account.yaml index 8201ea7c..eac6647b 100755 --- a/cluster/charts/fuel-streams/templates/service-account.yaml +++ b/cluster/charts/fuel-streams/templates/service-account.yaml @@ -4,6 +4,6 @@ kind: ServiceAccount metadata: {{- include "k8s.metadata" (dict "context" . "suffix" "-service-account") | nindent 2 }} labels: - {{- include "fuel-streams.labels" . | nindent 4 }} + {{- include "fuel-streams.labels" (dict "name" "service-account" "context" .) | nindent 4 }} automountServiceAccountToken: {{ .Values.serviceAccount.automount }} {{- end -}} diff --git a/cluster/charts/fuel-streams/templates/webserver/deployment.yaml b/cluster/charts/fuel-streams/templates/webserver/deployment.yaml index b0bd4782..57b7dad3 100644 --- a/cluster/charts/fuel-streams/templates/webserver/deployment.yaml +++ b/cluster/charts/fuel-streams/templates/webserver/deployment.yaml @@ -7,31 +7,23 @@ metadata: annotations: {{- include "set-value" (dict "context" $webserver "path" "config.annotations") | nindent 4 }} labels: - {{- include "fuel-streams.labels" . | nindent 4 }} + {{- include "fuel-streams.labels" (dict "name" "webserver" "context" .) | nindent 4 }} {{- include "set-value" (dict "context" $webserver "path" "config.labels") | nindent 4 }} - app.kubernetes.io/component: webserver - app.kubernetes.io/service: external-ws - spec: {{- if not $webserver.autoscaling.enabled }} replicas: {{ $webserver.config.replicaCount }} {{- end }} selector: matchLabels: - {{- include "fuel-streams.selectorLabels" . | nindent 6 }} - {{- include "set-value" (dict "context" $webserver "path" "config.selectorLabels") | nindent 6 }} - app.kubernetes.io/component: webserver - app.kubernetes.io/service: external-ws + {{- include "fuel-streams.selectorLabels" (dict "name" "webserver" "context" .) | nindent 6 }} template: metadata: annotations: {{- include "set-value" (dict "context" $webserver "path" "config.podAnnotations") | nindent 8 }} labels: - {{- include "fuel-streams.selectorLabels" . | nindent 8 }} + {{- include "fuel-streams.labels" (dict "name" "webserver" "context" .) | nindent 8 }} {{- include "set-value" (dict "context" $webserver "path" "config.labels") | nindent 8 }} - app.kubernetes.io/component: webserver - app.kubernetes.io/service: external-ws spec: {{- if .Values.serviceAccount.create }} diff --git a/cluster/charts/fuel-streams/values-local.yaml b/cluster/charts/fuel-streams/values-local.yaml new file mode 100644 index 00000000..bcf9a1b9 --- /dev/null +++ b/cluster/charts/fuel-streams/values-local.yaml @@ -0,0 +1,137 @@ +config: + createRoles: true + healthChecks: true + +# Reduce storage requirements for local development +publisher: + storage: + size: 10Gi + storageClass: "standard" # Use default storage class + + config: + replicaCount: 1 + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + + env: + PORT: 8080 + PUBLISHER_MAX_THREADS: "12" + NATS_URL: "fuel-streams-nats-publisher:4222" + +consumer: + config: + replicaCount: 1 + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + +# NATS Core configuration for local development +nats-core: + container: + env: + GOMEMLIMIT: 1GiB + merge: + resources: + requests: + cpu: 100m + memory: 512Mi + limits: + cpu: 500m + memory: 1Gi + + config: + cluster: + replicas: 1 # Single replica for local development + + jetstream: + fileStore: + pvc: + size: 10Gi + storageClassName: "standard" + + merge: + jetstream: + max_file_store: << 10GiB >> + max_memory_store: << 1GiB >> + +# NATS Publisher configuration for local development +nats-publisher: + container: + env: + GOMEMLIMIT: 1GiB + merge: + resources: + requests: + cpu: 100m + memory: 512Mi + limits: + cpu: 500m + memory: 1Gi + + config: + jetstream: + fileStore: + pvc: + size: 10Gi + storageClassName: "standard" + + merge: + jetstream: + max_file_store: << 10GiB >> + max_memory_store: << 1GiB >> + +# NATS Client configuration for local development +nats-client: + container: + env: + GOMEMLIMIT: 1GiB + merge: + resources: + requests: + cpu: 100m + memory: 512Mi + limits: + cpu: 500m + memory: 1Gi + + config: + jetstream: + fileStore: + pvc: + size: 10Gi + storageClassName: "standard" + + merge: + jetstream: + max_file_store: << 10GiB >> + max_memory_store: << 1GiB >> + +# Disable external service for local development +natsExternalService: + enabled: false + +# Use simple passwords for local development +natsAccountsSecret: + enabled: true + data: + - name: NATS_SYS_USER + value: sys + - name: NATS_SYS_PASS + value: sys + - name: NATS_ADMIN_USER + value: admin + - name: NATS_ADMIN_PASS + value: admin + - name: NATS_PUBLISHER_USER + value: default_user + - name: NATS_PUBLISHER_PASS + value: "" \ No newline at end of file diff --git a/cluster/charts/fuel-streams/values.yaml b/cluster/charts/fuel-streams/values.yaml index 4c1a1aac..7cc3a948 100755 --- a/cluster/charts/fuel-streams/values.yaml +++ b/cluster/charts/fuel-streams/values.yaml @@ -1,6 +1,3 @@ -docker: - registry: registry.dev.svc.cluster.local:5000 - config: # Override the name and fullname of the chart nameOverride: "" @@ -88,8 +85,8 @@ publisher: network: mainnet image: - repository: sv-emitter - pullPolicy: Never + repository: ghcr.io/fuellabs/sv-emitter + pullPolicy: Always tag: "latest" extraArgs: [] @@ -104,8 +101,8 @@ publisher: storage: name: rocks-db - size: 1Gi - storageClass: standard + size: 500Gi + storageClass: "gp3-generic" accessMode: ReadWriteOnce mountPath: /mnt/db @@ -178,11 +175,11 @@ publisher: consumer: enabled: true - port: 8081 + port: 8080 image: - repository: sv-consumer - pullPolicy: Never - tag: latest + repository: ghcr.io/fuellabs/sv-consumer + pullPolicy: Always + tag: "latest" args: - --nats-core-url - $(NATS_CORE_URL) @@ -190,12 +187,12 @@ consumer: - $(NATS_PUBLISHER_URL) env: - PORT: 8081 + PORT: 8080 NATS_CORE_URL: "fuel-streams-nats-core:4222" NATS_PUBLISHER_URL: "fuel-streams-nats-publisher:4222" config: - replicaCount: 1 + replicaCount: 3 labels: {} annotations: {} podAnnotations: {} @@ -234,8 +231,10 @@ consumer: nats-core: enabled: true + natsBox: enabled: false + promExporter: enabled: false port: 6777 @@ -253,16 +252,12 @@ nats-core: repository: nats tag: 2.10.22-alpine env: - GOMEMLIMIT: 2GiB + GOMEMLIMIT: 7GiB merge: - # startupProbe: - # initialDelaySeconds: 60 - # periodSeconds: 10 - # failureThreshold: 1080 resources: requests: - cpu: 8 - memory: 2Gi + cpu: 2 + memory: 8Gi service: enabled: true @@ -284,25 +279,13 @@ nats-core: cluster: enabled: true port: 6222 - replicas: 3 + replicas: 5 routeURLs: useFQDN: true websocket: enabled: true port: 8443 - tls: - enabled: false - # secretName: fuel-streams-nats-tls - # dir: /etc/nats-certs/websocket - # cert: tls.crt - # key: tls.key - merge: - no_tls: true - # same_origin: false - # compression: false - # handshake_timeout: "20s" - # no_auth_user: default_user jetstream: enabled: true @@ -310,8 +293,8 @@ nats-core: dir: /data pvc: enabled: true - size: 20Gi - storageClassName: standard + size: 2000Gi + storageClassName: "gp3-generic" leafnodes: enabled: true @@ -322,27 +305,18 @@ nats-core: port: 8222 merge: + max_payload: << 32MiB >> jetstream: domain: CORE - max_file_store: << 20GiB >> - max_memory_store: << 1792MiB >> - max_payload: << 8MiB >> + max_file_store: << 2000GiB >> + max_memory_store: << 7GiB >> system_account: SYS - accounts: - SYS: - users: - - user: sys - password: sys - ADMIN: - jetstream: enabled - users: - - user: admin - password: admin - PUBLIC: - jetstream: enabled - users: - - user: default_user - password: "" + $include: auth.conf + + configMap: + merge: + $tplYaml: | + {{- include "nats-accounts" . | nindent 8 }} # ------------------------------------------------------------------------------------------------- # NATS Publisher configuration @@ -353,24 +327,26 @@ nats-publisher: natsBox: enabled: false + promExporter: enabled: false + statefulSet: + merge: + spec: + replicas: 5 + container: image: repository: nats tag: 2.10.22-alpine env: - GOMEMLIMIT: 1GiB + GOMEMLIMIT: 7GiB merge: - # startupProbe: - # initialDelaySeconds: 60 - # periodSeconds: 10 - # failureThreshold: 1080 resources: requests: - cpu: 4 - memory: 1Gi + cpu: 2 + memory: 8Gi service: enabled: true @@ -386,11 +362,6 @@ nats-publisher: mqtt: enabled: false - statefulSet: - merge: - spec: - replicas: 3 - podTemplate: topologySpreadConstraints: kubernetes.io/hostname: @@ -410,8 +381,8 @@ nats-publisher: dir: /data pvc: enabled: true - size: 5Gi - storageClassName: standard + size: 100Gi + storageClassName: "gp3-generic" leafnodes: enabled: true @@ -428,27 +399,18 @@ nats-publisher: port: 8222 merge: + max_payload: << 32MiB >> jetstream: domain: PUBLISHER - max_file_store: << 5GiB >> - max_memory_store: << 768MiB >> - max_payload: << 8MiB >> + max_file_store: << 100GiB >> + max_memory_store: << 7GiB >> system_account: SYS - accounts: - SYS: - users: - - user: sys - password: sys - ADMIN: - jetstream: enabled - users: - - user: admin - password: admin - PUBLIC: - jetstream: enabled - users: - - user: default_user - password: "" + $include: auth.conf + + configMap: + merge: + $tplYaml: | + {{- include "nats-accounts" . | nindent 8 }} # ------------------------------------------------------------------------------------------------- # NATS Client configuration @@ -457,25 +419,28 @@ nats-publisher: nats-client: enabled: true - global: - labels: - app.kubernetes.io/service: external-ws natsBox: enabled: false + promExporter: enabled: false + statefulSet: + merge: + spec: + replicas: 3 + container: image: repository: nats tag: 2.10.22-alpine env: - GOMEMLIMIT: 512MiB + GOMEMLIMIT: 7GiB merge: resources: requests: cpu: 2 - memory: 512Mi + memory: 8Gi service: enabled: true @@ -491,11 +456,6 @@ nats-client: mqtt: enabled: false - statefulSet: - merge: - spec: - replicas: 2 - podTemplate: topologySpreadConstraints: kubernetes.io/hostname: @@ -512,8 +472,8 @@ nats-client: dir: /data pvc: enabled: true - size: 2Gi - storageClassName: standard + size: 100Gi + storageClassName: "gp3-generic" leafnodes: enabled: true @@ -526,72 +486,39 @@ nats-client: websocket: enabled: true port: 8443 + # This is just enable if the natsExternalService is enabled + # and the DNS is set to the correct value tls: - enabled: false - # secretName: fuel-streams-nats-tls - # dir: /etc/nats-certs/websocket - # cert: tls.crt - # key: tls.key + enabled: true + dir: /etc/nats-certs/websocket + cert: tls.crt + key: tls.key + secretName: fuel-streams-nats-tls merge: - no_tls: true - # same_origin: false - # compression: false - # handshake_timeout: "20s" - # no_auth_user: default_user + no_tls: false + same_origin: false + compression: false + handshake_timeout: "20s" + no_auth_user: default_user monitor: enabled: false port: 8222 merge: + max_payload: << 32MiB >> jetstream: domain: CLIENT - max_file_store: << 2GiB >> - max_memory_store: << 384MiB >> - max_payload: << 8MiB >> + max_file_store: << 100GiB >> + max_memory_store: << 7GiB >> system_account: SYS - accounts: - SYS: - users: - - user: sys - password: sys - ADMIN: - jetstream: enabled - users: - - user: admin - password: admin - PUBLIC: - jetstream: enabled - users: - - user: default_user - password: "" - - # TODO: Add users and permissions later - # accounts: - # USERS: - # jetstream: enabled - # users: - # - user: default_user - # permissions: - # subscribe: ">" - # publish: - # deny: - # - "*.by_id.>" - # - "*.blocks.>" - # - "*.transactions.>" - # - "*.inputs.>" - # - "*.outputs.>" - # - "*.receipts.>" - # - "*.logs.>" - # - "*.utxos.>" - # - "$JS.API.STREAM.CREATE.>" - # - "$JS.API.STREAM.UPDATE.>" - # - "$JS.API.STREAM.DELETE.>" - # - "$JS.API.STREAM.PURGE.>" - # - "$JS.API.STREAM.RESTORE.>" - # - "$JS.API.STREAM.MSG.DELETE.>" - # - "$JS.API.CONSUMER.DURABLE.CREATE.>" - + $include: auth.conf + + configMap: + merge: + $tplYaml: | + {{- include "nats-accounts" . | nindent 8 }} + # ------------------------------------------------------------------------------------------------- # NATS External Service configuration (WebSocket) # ------------------------------------------------------------------------------------------------- @@ -609,6 +536,12 @@ natsExternalService: labels: {} annotations: {} +# This is just need to run locally, for production you need to +# create a secret with the correct values named fuel-streams-nats-accounts +natsAccountsSecret: + enabled: false + data: [] + # ------------------------------------------------------------------------------------------------- # WebServer configuration # ------------------------------------------------------------------------------------------------- From ad5a3af8203075a42db10f450863f8575716b87e Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Thu, 19 Dec 2024 16:00:30 -0300 Subject: [PATCH 03/31] build(repo): Update NATS dependency on chart (#358) * build(repo): Update NATS dependency on chart * build(repo): Bump chart version --- cluster/charts/fuel-streams/Chart.lock | 10 +- cluster/charts/fuel-streams/Chart.yaml | 8 +- cluster/charts/fuel-streams/values-local.yaml | 12 +- cluster/charts/fuel-streams/values.yaml | 110 +++++++----------- 4 files changed, 57 insertions(+), 83 deletions(-) diff --git a/cluster/charts/fuel-streams/Chart.lock b/cluster/charts/fuel-streams/Chart.lock index 44606f01..3b1e4e2c 100644 --- a/cluster/charts/fuel-streams/Chart.lock +++ b/cluster/charts/fuel-streams/Chart.lock @@ -1,12 +1,12 @@ dependencies: - name: nats repository: https://nats-io.github.io/k8s/helm/charts/ - version: 1.2.6 + version: 1.2.8 - name: nats repository: https://nats-io.github.io/k8s/helm/charts/ - version: 1.2.6 + version: 1.2.8 - name: nats repository: https://nats-io.github.io/k8s/helm/charts/ - version: 1.2.6 -digest: sha256:ad7948ef2413ea2f9af239829570612f04abd624844413ad73600fd67ce2e9b6 -generated: "2024-12-08T20:11:41.144678-03:00" + version: 1.2.8 +digest: sha256:a5f3dd64e1a20f7c9d58894359f6f909f33d14772355ee70033fd411219bcc7e +generated: "2024-12-18T16:59:13.903435-03:00" diff --git a/cluster/charts/fuel-streams/Chart.yaml b/cluster/charts/fuel-streams/Chart.yaml index a6beaf16..61e1bdf8 100755 --- a/cluster/charts/fuel-streams/Chart.yaml +++ b/cluster/charts/fuel-streams/Chart.yaml @@ -2,20 +2,20 @@ apiVersion: v2 appVersion: "1.0" description: A Helm chart for Kubernetes name: fuel-streams -version: 0.5.6 +version: 0.5.7 dependencies: - name: nats - version: 1.2.6 + version: 1.2.8 repository: https://nats-io.github.io/k8s/helm/charts/ alias: nats-core condition: nats-core.enabled - name: nats - version: 1.2.6 + version: 1.2.8 repository: https://nats-io.github.io/k8s/helm/charts/ alias: nats-publisher condition: nats-publisher.enabled - name: nats - version: 1.2.6 + version: 1.2.8 repository: https://nats-io.github.io/k8s/helm/charts/ alias: nats-client condition: nats-client.enabled diff --git a/cluster/charts/fuel-streams/values-local.yaml b/cluster/charts/fuel-streams/values-local.yaml index bcf9a1b9..dc5af796 100644 --- a/cluster/charts/fuel-streams/values-local.yaml +++ b/cluster/charts/fuel-streams/values-local.yaml @@ -6,8 +6,8 @@ config: publisher: storage: size: 10Gi - storageClass: "standard" # Use default storage class - + storageClass: "standard" # Use default storage class + config: replicaCount: 1 resources: @@ -50,7 +50,7 @@ nats-core: config: cluster: - replicas: 1 # Single replica for local development + replicas: 1 # Single replica for local development jetstream: fileStore: @@ -121,7 +121,7 @@ natsExternalService: # Use simple passwords for local development natsAccountsSecret: - enabled: true + enabled: true data: - name: NATS_SYS_USER value: sys @@ -132,6 +132,6 @@ natsAccountsSecret: - name: NATS_ADMIN_PASS value: admin - name: NATS_PUBLISHER_USER - value: default_user + value: default_user - name: NATS_PUBLISHER_PASS - value: "" \ No newline at end of file + value: "" diff --git a/cluster/charts/fuel-streams/values.yaml b/cluster/charts/fuel-streams/values.yaml index 7cc3a948..7741dc0b 100755 --- a/cluster/charts/fuel-streams/values.yaml +++ b/cluster/charts/fuel-streams/values.yaml @@ -140,11 +140,6 @@ publisher: podValue: 4 periodSeconds: 15 - env: - PORT: 8080 - PUBLISHER_MAX_THREADS: "32" - NATS_URL: "fuel-streams-nats-publisher:4222" - # Additional environment variables with complex structures # extraEnv: [] # - name: RELAYER @@ -169,6 +164,11 @@ publisher: # - secretRef: # name: additional-secrets + env: + PORT: 8080 + PUBLISHER_MAX_THREADS: "32" + NATS_URL: "fuel-streams-nats-publisher:4222" + # ------------------------------------------------------------------------------------------------- # Consumer configuration # ------------------------------------------------------------------------------------------------- @@ -225,6 +225,29 @@ consumer: podValue: 4 periodSeconds: 15 +# ------------------------------------------------------------------------------------------------- +# NATS Common Configuration +# ------------------------------------------------------------------------------------------------- + +natsExternalService: + enabled: true + certificate: + issuer: "letsencrypt-prod" + duration: "2160h" + renewBefore: "360h" + annotations: {} + labels: {} + service: + dns: "stream-dev.fuel.network" + labels: {} + annotations: {} + +# This is just need to run locally, for production you need to +# create a secret with the correct values named fuel-streams-nats-accounts +natsAccountsSecret: + enabled: false + data: [] + # ------------------------------------------------------------------------------------------------- # NATS Core configuration # ------------------------------------------------------------------------------------------------- @@ -250,7 +273,7 @@ nats-core: container: image: repository: nats - tag: 2.10.22-alpine + tag: 2.10.24-alpine env: GOMEMLIMIT: 7GiB merge: @@ -270,8 +293,6 @@ nats-core: enabled: true leafnodes: enabled: true - mqtt: - enabled: false monitor: enabled: false @@ -282,7 +303,7 @@ nats-core: replicas: 5 routeURLs: useFQDN: true - + websocket: enabled: true port: 8443 @@ -308,11 +329,13 @@ nats-core: max_payload: << 32MiB >> jetstream: domain: CORE + sync_interval: << 30s >> + max_outstanding_catchup: << 512MiB >> max_file_store: << 2000GiB >> max_memory_store: << 7GiB >> system_account: SYS $include: auth.conf - + configMap: merge: $tplYaml: | @@ -339,7 +362,7 @@ nats-publisher: container: image: repository: nats - tag: 2.10.22-alpine + tag: 2.10.24-alpine env: GOMEMLIMIT: 7GiB merge: @@ -353,28 +376,12 @@ nats-publisher: ports: nats: enabled: true - websocket: - enabled: false leafnodes: enabled: true monitor: enabled: false - mqtt: - enabled: false - - podTemplate: - topologySpreadConstraints: - kubernetes.io/hostname: - maxSkew: 1 - whenUnsatisfiable: DoNotSchedule config: - cluster: - enabled: false - - websocket: - enabled: false - jetstream: enabled: true fileStore: @@ -389,9 +396,7 @@ nats-publisher: port: 7422 merge: remotes: - - urls: ["nats://sys:sys@fuel-streams-nats-core:7422"] - account: SYS - - urls: ["nats://admin:admin@fuel-streams-nats-core:7422"] + - urls: ["nats-leaf://admin:admin@fuel-streams-nats-core:7422"] account: ADMIN monitor: @@ -402,6 +407,8 @@ nats-publisher: max_payload: << 32MiB >> jetstream: domain: PUBLISHER + sync_interval: << 30s >> + max_outstanding_catchup: << 512MiB >> max_file_store: << 100GiB >> max_memory_store: << 7GiB >> system_account: SYS @@ -422,9 +429,6 @@ nats-client: natsBox: enabled: false - promExporter: - enabled: false - statefulSet: merge: spec: @@ -433,7 +437,7 @@ nats-client: container: image: repository: nats - tag: 2.10.22-alpine + tag: 2.10.24-alpine env: GOMEMLIMIT: 7GiB merge: @@ -454,18 +458,9 @@ nats-client: monitor: enabled: false mqtt: - enabled: false - - podTemplate: - topologySpreadConstraints: - kubernetes.io/hostname: - maxSkew: 1 - whenUnsatisfiable: DoNotSchedule + enabled: false config: - cluster: - enabled: false - jetstream: enabled: true fileStore: @@ -480,7 +475,7 @@ nats-client: port: 7422 merge: remotes: - - urls: ["ws://admin:admin@fuel-streams-nats-core:8443"] + - urls: ["nats-leaf://admin:admin@fuel-streams-nats-core:7422"] account: ADMIN websocket: @@ -509,6 +504,8 @@ nats-client: max_payload: << 32MiB >> jetstream: domain: CLIENT + sync_interval: << 30s >> + max_outstanding_catchup: << 512MiB >> max_file_store: << 100GiB >> max_memory_store: << 7GiB >> system_account: SYS @@ -519,29 +516,6 @@ nats-client: $tplYaml: | {{- include "nats-accounts" . | nindent 8 }} -# ------------------------------------------------------------------------------------------------- -# NATS External Service configuration (WebSocket) -# ------------------------------------------------------------------------------------------------- - -natsExternalService: - enabled: true - certificate: - issuer: "letsencrypt-prod" - duration: "2160h" - renewBefore: "360h" - annotations: {} - labels: {} - service: - dns: "stream-dev.fuel.network" - labels: {} - annotations: {} - -# This is just need to run locally, for production you need to -# create a secret with the correct values named fuel-streams-nats-accounts -natsAccountsSecret: - enabled: false - data: [] - # ------------------------------------------------------------------------------------------------- # WebServer configuration # ------------------------------------------------------------------------------------------------- From 4095c3d30ae216c273920fb09880a667cd3f0ed1 Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 00:14:20 -0300 Subject: [PATCH 04/31] refactor(repo): remove FuelNetwork from nats --- .../src/nats/nats_client_opts.rs | 188 ++++++++++-------- crates/fuel-streams-ws/src/server/context.rs | 22 -- crates/fuel-streams/src/client/client_impl.rs | 3 +- tests/tests/client.rs | 40 +++- 4 files changed, 132 insertions(+), 121 deletions(-) diff --git a/crates/fuel-streams-storage/src/nats/nats_client_opts.rs b/crates/fuel-streams-storage/src/nats/nats_client_opts.rs index 3ae30f1f..101825ba 100644 --- a/crates/fuel-streams-storage/src/nats/nats_client_opts.rs +++ b/crates/fuel-streams-storage/src/nats/nats_client_opts.rs @@ -1,53 +1,49 @@ use std::time::Duration; use async_nats::ConnectOptions; -use fuel_networks::{FuelNetwork, FuelNetworkUserRole}; use super::NatsNamespace; -/// Represents options for configuring a NATS client. -/// -/// # Examples -/// -/// Creating a new `NatsClientOpts` instance: -/// -/// ``` -/// use fuel_streams_storage::nats::NatsClientOpts; -/// use fuel_networks::FuelNetwork; -/// -/// let opts = NatsClientOpts::new(FuelNetwork::Local); -/// ``` -/// -/// Creating a public `NatsClientOpts`: -/// -/// ``` -/// use fuel_streams_storage::nats::NatsClientOpts; -/// use fuel_networks::FuelNetwork; -/// -/// let opts = NatsClientOpts::new(FuelNetwork::Local); -/// ``` -/// -/// Modifying `NatsClientOpts`: -/// -/// ``` -/// use fuel_streams_storage::nats::NatsClientOpts; -/// use fuel_networks::{FuelNetwork, FuelNetworkUserRole}; -/// -/// let opts = NatsClientOpts::new(FuelNetwork::Local) -/// .with_role(FuelNetworkUserRole::Admin) -/// .with_timeout(10); -/// ``` +#[derive(Debug, Clone, Eq, PartialEq, Default)] +pub enum NatsAuth { + Admin, + System, + #[default] + Public, + Custom(String, String), +} + +impl NatsAuth { + fn credentials_from_env(&self) -> (String, String) { + match self { + NatsAuth::Admin => ( + dotenvy::var("NATS_ADMIN_USER") + .expect("NATS_ADMIN_USER must be set"), + dotenvy::var("NATS_ADMIN_PASS") + .expect("NATS_ADMIN_PASS must be set"), + ), + NatsAuth::System => ( + dotenvy::var("NATS_SYS_USER") + .expect("NATS_SYS_USER must be set"), + dotenvy::var("NATS_SYS_PASS") + .expect("NATS_SYS_PASS must be set"), + ), + NatsAuth::Public => ("default_user".to_string(), "".to_string()), + NatsAuth::Custom(user, pass) => { + (user.to_string(), pass.to_string()) + } + } + } +} + #[derive(Debug, Clone)] pub struct NatsClientOpts { - pub network: FuelNetwork, - /// The role of the user connecting to the NATS server (Admin or Public). - pub(crate) role: FuelNetworkUserRole, + /// The URL of the NATS server. + pub(crate) url: String, /// The namespace used as a prefix for NATS streams, consumers, and subject names. pub(crate) namespace: NatsNamespace, /// The timeout in seconds for NATS operations. pub(crate) timeout_secs: u64, - /// URL of the NATS server. - pub(crate) url: Option, /// The domain to use for the NATS client. pub(crate) domain: Option, /// The user to use for the NATS client. @@ -57,44 +53,39 @@ pub struct NatsClientOpts { } impl NatsClientOpts { - pub fn new(network: FuelNetwork) -> Self { + pub fn new(url: String) -> Self { Self { - network, - role: FuelNetworkUserRole::default(), + url, namespace: NatsNamespace::default(), timeout_secs: 5, - url: None, + domain: None, user: None, password: None, - domain: None, } } pub fn admin_opts() -> Self { - Self::new(FuelNetwork::load_from_env()) - .with_role(FuelNetworkUserRole::Admin) + Self::from_env(Some(NatsAuth::Admin)) } - - pub fn with_role(self, role: FuelNetworkUserRole) -> Self { - Self { role, ..self } + pub fn system_opts() -> Self { + Self::from_env(Some(NatsAuth::System)) + } + pub fn public_opts() -> Self { + Self::from_env(Some(NatsAuth::Public)) } - pub fn with_url(self, url: String) -> Self { - Self { - url: Some(url), - ..self - } + pub fn from_env(auth: Option) -> Self { + let url = dotenvy::var("NATS_URL").expect("NATS_URL must be set"); + let (user, pass) = auth.unwrap_or_default().credentials_from_env(); + Self::new(url).with_user(user).with_password(pass) } pub fn get_url(&self) -> String { - match self.url.clone() { - Some(url) => url, - None => match self.role { - FuelNetworkUserRole::Admin => dotenvy::var("NATS_URL") - .expect("NATS_URL must be set for admin role"), - FuelNetworkUserRole::Default => self.network.to_nats_url(), - }, - } + self.url.clone() + } + + pub fn with_url(self, url: String) -> Self { + Self { url, ..self } } pub fn with_domain(self, domain: String) -> Self { @@ -138,36 +129,16 @@ impl NatsClientOpts { } pub(super) fn connect_opts(&self) -> ConnectOptions { - let (user, pass) = match self.role { - FuelNetworkUserRole::Admin => ( - Some("admin".to_string()), - Some( - dotenvy::var("NATS_ADMIN_PASS") - .expect("`NATS_ADMIN_PASS` env must be set"), - ), - ), - FuelNetworkUserRole::Default => { - (Some("default_user".to_string()), Some("".to_string())) - } - }; - - let (user, pass) = match (self.user.clone(), self.password.clone()) { - (Some(user), Some(pass)) => (Some(user), Some(pass)), - _ => (user, pass), - }; - - match (user, pass) { + let opts = match (self.user.clone(), self.password.clone()) { (Some(user), Some(pass)) => { ConnectOptions::with_user_and_password(user, pass) - .connection_timeout(Duration::from_secs(self.timeout_secs)) - .max_reconnects(1) - .name(Self::conn_id()) } - _ => ConnectOptions::new() - .connection_timeout(Duration::from_secs(self.timeout_secs)) - .max_reconnects(1) - .name(Self::conn_id()), - } + _ => ConnectOptions::new(), + }; + + opts.connection_timeout(Duration::from_secs(self.timeout_secs)) + .max_reconnects(1) + .name(Self::conn_id()) } // This will be useful for debugging and monitoring connections @@ -180,3 +151,44 @@ impl NatsClientOpts { rand::thread_rng().gen() } } + +#[cfg(test)] +mod tests { + use std::env; + + use super::*; + + #[test] + fn test_role_credentials() { + // Setup + env::set_var("NATS_ADMIN_USER", "admin"); + env::set_var("NATS_ADMIN_PASS", "admin_pass"); + + // Test Admin role credentials + let (user, pass) = NatsAuth::Admin.credentials_from_env(); + assert_eq!(user, "admin"); + assert_eq!(pass, "admin_pass"); + + // Cleanup + env::remove_var("NATS_ADMIN_USER"); + env::remove_var("NATS_ADMIN_PASS"); + } + + #[test] + fn test_from_env_with_role() { + // Setup + env::set_var("NATS_URL", "nats://localhost:4222"); + env::set_var("NATS_ADMIN_USER", "admin"); + env::set_var("NATS_ADMIN_PASS", "admin_pass"); + + // Test Admin role + let opts = NatsClientOpts::from_env(Some(NatsAuth::Admin)); + assert_eq!(opts.user, Some("admin".to_string())); + assert_eq!(opts.password, Some("admin_pass".to_string())); + + // Cleanup + env::remove_var("NATS_URL"); + env::remove_var("NATS_ADMIN_USER"); + env::remove_var("NATS_ADMIN_PASS"); + } +} diff --git a/crates/fuel-streams-ws/src/server/context.rs b/crates/fuel-streams-ws/src/server/context.rs index 7bda3220..b57e251a 100644 --- a/crates/fuel-streams-ws/src/server/context.rs +++ b/crates/fuel-streams-ws/src/server/context.rs @@ -47,28 +47,6 @@ impl Context { }) } - pub async fn new_for_testing( - fuel_network: FuelNetwork, - ) -> anyhow::Result { - let nats_client_opts = NatsClientOpts::new(fuel_network); - let nats_client = NatsClient::connect(&nats_client_opts).await?; - let s3_client_opts = S3ClientOpts::admin_opts(); - let s3_client = Arc::new(S3Client::new(&s3_client_opts).await?); - Ok(Context { - fuel_streams: Arc::new( - FuelStreams::new(&nats_client, &s3_client).await, - ), - nats_client: nats_client.clone(), - telemetry: Telemetry::new(None).await?, - s3_client: None, - jwt_secret: String::new(), - }) - } - - pub fn get_streams(&self) -> &FuelStreams { - &self.fuel_streams - } - #[allow(dead_code)] async fn shutdown_services_with_timeout(&self) -> anyhow::Result<()> { tokio::time::timeout(GRACEFUL_SHUTDOWN_TIMEOUT, async { diff --git a/crates/fuel-streams/src/client/client_impl.rs b/crates/fuel-streams/src/client/client_impl.rs index 620d1a7d..d6657369 100644 --- a/crates/fuel-streams/src/client/client_impl.rs +++ b/crates/fuel-streams/src/client/client_impl.rs @@ -36,7 +36,8 @@ impl Client { /// # } /// ``` pub async fn connect(network: FuelNetwork) -> Result { - let nats_opts = NatsClientOpts::new(network); + let nats_opts = + NatsClientOpts::public_opts().with_url(network.to_nats_url()); let nats_client = NatsClient::connect(&nats_opts) .await .map_err(ClientError::NatsConnectionFailed)?; diff --git a/tests/tests/client.rs b/tests/tests/client.rs index a0178a7c..d4204200 100644 --- a/tests/tests/client.rs +++ b/tests/tests/client.rs @@ -73,7 +73,9 @@ async fn multiple_client_connections() -> BoxedResult<()> { #[tokio::test] async fn public_user_cannot_create_streams() -> BoxedResult<()> { - let opts = NatsClientOpts::new(FuelNetwork::Local) + let network = FuelNetwork::Local; + let opts = NatsClientOpts::public_opts() + .with_url(network.to_nats_url()) .with_rdn_namespace() .with_timeout(1); let client = NatsClient::connect(&opts).await?; @@ -95,7 +97,9 @@ async fn public_user_cannot_create_streams() -> BoxedResult<()> { #[tokio::test] async fn public_user_cannot_create_stores() -> BoxedResult<()> { - let opts = NatsClientOpts::new(FuelNetwork::Local) + let network = FuelNetwork::Local; + let opts = NatsClientOpts::public_opts() + .with_url(network.to_nats_url()) .with_rdn_namespace() .with_timeout(1); @@ -116,7 +120,9 @@ async fn public_user_cannot_create_stores() -> BoxedResult<()> { #[tokio::test] async fn public_user_cannot_delete_stores() -> BoxedResult<()> { + let network = FuelNetwork::Local; let opts = NatsClientOpts::admin_opts() + .with_url(network.to_nats_url()) .with_rdn_namespace() .with_timeout(1); @@ -131,7 +137,8 @@ async fn public_user_cannot_delete_stores() -> BoxedResult<()> { }) .await?; - let opts = NatsClientOpts::new(FuelNetwork::Local) + let opts = NatsClientOpts::public_opts() + .with_url(network.to_nats_url()) .with_rdn_namespace() .with_timeout(1); let client = NatsClient::connect(&opts).await?; @@ -164,7 +171,9 @@ async fn public_user_cannot_delete_stream() -> BoxedResult<()> { }) .await?; - let public_opts = opts.clone().with_role(FuelNetworkUserRole::Default); + let network = FuelNetwork::Local; + let public_opts = + NatsClientOpts::public_opts().with_url(network.to_nats_url()); let public_client = NatsClient::connect(&public_opts).await?; assert!( @@ -181,21 +190,29 @@ async fn public_user_cannot_delete_stream() -> BoxedResult<()> { #[tokio::test] async fn public_user_can_access_streams_after_created() { - let opts = NatsClientOpts::new(FuelNetwork::Local) + let network = FuelNetwork::Local; + let admin_opts = NatsClientOpts::admin_opts() + .with_url(network.to_nats_url()) .with_rdn_namespace() .with_timeout(1); - let admin_opts = opts.clone().with_role(FuelNetworkUserRole::Admin); - assert!(NatsClient::connect(&admin_opts).await.is_ok()); + let public_opts = NatsClientOpts::public_opts() + .with_url(network.to_nats_url()) + .with_rdn_namespace() + .with_timeout(1); - let public_opts = opts.clone().with_role(FuelNetworkUserRole::Default); + assert!(NatsClient::connect(&admin_opts).await.is_ok()); assert!(NatsClient::connect(&public_opts).await.is_ok()); } #[tokio::test] async fn public_and_admin_user_can_access_streams_after_created( ) -> BoxedResult<()> { - let admin_opts = NatsClientOpts::admin_opts(); + let network = FuelNetwork::Local; + let admin_opts = NatsClientOpts::admin_opts() + .with_url(network.to_nats_url()) + .with_rdn_namespace() + .with_timeout(1); let s3_opts = Arc::new(S3ClientOpts::admin_opts()); let admin_tasks: Vec>> = (0..100) .map(|_| { @@ -210,7 +227,10 @@ async fn public_and_admin_user_can_access_streams_after_created( }) .collect(); - let public_opts = NatsClientOpts::new(FuelNetwork::Local); + let public_opts = NatsClientOpts::public_opts() + .with_url(network.to_nats_url()) + .with_rdn_namespace() + .with_timeout(1); let s3_public_opts = Arc::new(S3ClientOpts::new(FuelNetwork::Local)); let public_tasks: Vec>> = (0..100) .map(|_| { From d4d86773f532b1536ea3e687028964bcde9b99be Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 00:36:17 -0300 Subject: [PATCH 05/31] refactor(repo): remove unused benches --- Cargo.lock | 162 ------------ Makefile | 2 +- benches/bench-consumers/Cargo.toml | 30 --- benches/bench-consumers/README.md | 13 - benches/bench-consumers/benches/consumers.rs | 43 --- benches/bench-consumers/src/lib.rs | 1 - benches/bench-consumers/src/main.rs | 10 - .../src/runners/benchmark_results.rs | 103 -------- benches/bench-consumers/src/runners/mod.rs | 5 - .../bench-consumers/src/runners/runner_all.rs | 25 -- .../src/runners/runner_consumer.rs | 55 ---- .../src/runners/runner_kv_watcher.rs | 40 --- .../src/runners/runner_subscription.rs | 35 --- benches/load-tester/Cargo.toml | 22 -- benches/load-tester/README.md | 9 - benches/load-tester/src/lib.rs | 1 - benches/load-tester/src/main.rs | 16 -- benches/load-tester/src/runners/cli.rs | 33 --- benches/load-tester/src/runners/mod.rs | 4 - benches/load-tester/src/runners/results.rs | 118 --------- benches/load-tester/src/runners/runner_all.rs | 247 ------------------ .../src/runners/runner_streamable.rs | 38 --- benches/nats-publisher/Cargo.toml | 28 -- benches/nats-publisher/README.md | 18 -- benches/nats-publisher/config/nats.conf | 5 - benches/nats-publisher/src/lib.rs | 2 - benches/nats-publisher/src/main.rs | 78 ------ benches/nats-publisher/src/utils/blocks.rs | 93 ------- benches/nats-publisher/src/utils/mod.rs | 3 - benches/nats-publisher/src/utils/nats.rs | 130 --------- benches/nats-publisher/src/utils/tx.rs | 129 --------- crates/fuel-streams-core/README.md | 2 +- .../src/nats/nats_client.rs | 6 +- 33 files changed, 4 insertions(+), 1502 deletions(-) delete mode 100644 benches/bench-consumers/Cargo.toml delete mode 100644 benches/bench-consumers/README.md delete mode 100644 benches/bench-consumers/benches/consumers.rs delete mode 100644 benches/bench-consumers/src/lib.rs delete mode 100644 benches/bench-consumers/src/main.rs delete mode 100644 benches/bench-consumers/src/runners/benchmark_results.rs delete mode 100644 benches/bench-consumers/src/runners/mod.rs delete mode 100644 benches/bench-consumers/src/runners/runner_all.rs delete mode 100644 benches/bench-consumers/src/runners/runner_consumer.rs delete mode 100644 benches/bench-consumers/src/runners/runner_kv_watcher.rs delete mode 100644 benches/bench-consumers/src/runners/runner_subscription.rs delete mode 100644 benches/load-tester/Cargo.toml delete mode 100644 benches/load-tester/README.md delete mode 100644 benches/load-tester/src/lib.rs delete mode 100644 benches/load-tester/src/main.rs delete mode 100644 benches/load-tester/src/runners/cli.rs delete mode 100644 benches/load-tester/src/runners/mod.rs delete mode 100644 benches/load-tester/src/runners/results.rs delete mode 100644 benches/load-tester/src/runners/runner_all.rs delete mode 100644 benches/load-tester/src/runners/runner_streamable.rs delete mode 100644 benches/nats-publisher/Cargo.toml delete mode 100644 benches/nats-publisher/README.md delete mode 100644 benches/nats-publisher/config/nats.conf delete mode 100644 benches/nats-publisher/src/lib.rs delete mode 100644 benches/nats-publisher/src/main.rs delete mode 100644 benches/nats-publisher/src/utils/blocks.rs delete mode 100644 benches/nats-publisher/src/utils/mod.rs delete mode 100644 benches/nats-publisher/src/utils/nats.rs delete mode 100644 benches/nats-publisher/src/utils/tx.rs diff --git a/Cargo.lock b/Cargo.lock index bd1f6448..f32d9ffb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -410,15 +410,6 @@ version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" -[[package]] -name = "approx" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" -dependencies = [ - "num-traits", -] - [[package]] name = "arbitrary" version = "1.4.1" @@ -1370,22 +1361,6 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" -[[package]] -name = "bench-consumers" -version = "0.0.13" -dependencies = [ - "anyhow", - "async-nats", - "chrono", - "criterion", - "fuel-core-types 0.40.2", - "fuel-streams-core", - "futures", - "nats-publisher", - "statrs", - "tokio", -] - [[package]] name = "bincode" version = "1.3.3" @@ -1585,12 +1560,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "bytemuck" -version = "1.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" - [[package]] name = "byteorder" version = "1.5.0" @@ -6339,21 +6308,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" -[[package]] -name = "load-tester" -version = "0.0.13" -dependencies = [ - "anyhow", - "async-nats", - "chrono", - "clap 4.5.23", - "fuel-streams", - "fuel-streams-core", - "futures", - "statrs", - "tokio", -] - [[package]] name = "local-channel" version = "0.1.5" @@ -6463,16 +6417,6 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" -[[package]] -name = "matrixmultiply" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a" -dependencies = [ - "autocfg", - "rawpointer", -] - [[package]] name = "md-5" version = "0.10.6" @@ -6644,23 +6588,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e94e1e6445d314f972ff7395df2de295fe51b71821694f0b0e1e79c4f12c8577" -[[package]] -name = "nalgebra" -version = "0.33.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b" -dependencies = [ - "approx", - "matrixmultiply", - "num-complex", - "num-rational", - "num-traits", - "rand", - "rand_distr", - "simba", - "typenum", -] - [[package]] name = "names" version = "0.14.0" @@ -6688,25 +6615,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "nats-publisher" -version = "0.0.13" -dependencies = [ - "anyhow", - "async-nats", - "clap 4.5.23", - "criterion", - "fuel-core", - "fuel-core-bin", - "fuel-core-importer", - "fuel-core-storage", - "fuel-core-types 0.40.2", - "fuel-data-parser", - "fuel-streams-core", - "tokio", - "tracing", -] - [[package]] name = "netlink-packet-core" version = "0.7.0" @@ -6858,15 +6766,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-complex" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" -dependencies = [ - "num-traits", -] - [[package]] name = "num-conv" version = "0.1.0" @@ -6900,7 +6799,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", - "libm", ] [[package]] @@ -7956,16 +7854,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rand_distr" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" -dependencies = [ - "num-traits", - "rand", -] - [[package]] name = "rand_xorshift" version = "0.3.0" @@ -7975,12 +7863,6 @@ dependencies = [ "rand_core", ] -[[package]] -name = "rawpointer" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" - [[package]] name = "rayon" version = "1.10.0" @@ -8571,15 +8453,6 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" -[[package]] -name = "safe_arch" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3460605018fdc9612bce72735cba0d27efbcd9904780d44c7e3a9948f96148a" -dependencies = [ - "bytemuck", -] - [[package]] name = "same-file" version = "1.0.6" @@ -9019,19 +8892,6 @@ dependencies = [ "rand_core", ] -[[package]] -name = "simba" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa" -dependencies = [ - "approx", - "num-complex", - "num-traits", - "paste", - "wide", -] - [[package]] name = "simdutf8" version = "0.1.5" @@ -9175,18 +9035,6 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7beae5182595e9a8b683fa98c4317f956c9a2dec3b9716990d20023cc60c766" -[[package]] -name = "statrs" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a3fe7c28c6512e766b0874335db33c94ad7b8f9054228ae1c2abd47ce7d335e" -dependencies = [ - "approx", - "nalgebra", - "num-traits", - "rand", -] - [[package]] name = "streams-tests" version = "0.0.13" @@ -10883,16 +10731,6 @@ dependencies = [ "rustls-pki-types", ] -[[package]] -name = "wide" -version = "0.7.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58e6db2670d2be78525979e9a5f9c69d296fd7d670549fe9ebf70f8708cb5019" -dependencies = [ - "bytemuck", - "safe_arch", -] - [[package]] name = "widestring" version = "1.1.0" diff --git a/Makefile b/Makefile index cac132b9..e9465743 100644 --- a/Makefile +++ b/Makefile @@ -140,7 +140,7 @@ test: fi bench: - cargo bench -p data-parser -p nats-publisher -p bench-consumers + cargo bench -p data-parser helm-test: helm unittest -f "tests/**/*.yaml" -f "tests/*.yaml" cluster/charts/fuel-streams diff --git a/benches/bench-consumers/Cargo.toml b/benches/bench-consumers/Cargo.toml deleted file mode 100644 index fb0dfb5b..00000000 --- a/benches/bench-consumers/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "bench-consumers" -authors = { workspace = true } -keywords = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } -version = { workspace = true } -rust-version = { workspace = true } -publish = false - -[[bench]] -name = "consumers" -harness = false -path = "benches/consumers.rs" - -[dependencies] -anyhow = { workspace = true } -async-nats = { workspace = true } -chrono = { workspace = true } -fuel-core-types = { workspace = true } -fuel-streams-core = { workspace = true, features = ["bench-helpers"] } -futures = { workspace = true } -nats-publisher = { path = "../nats-publisher" } -statrs = "0.18" -tokio = { workspace = true } - -[dev-dependencies] -criterion = { version = "0.5", features = ["html_reports", "async_tokio"] } diff --git a/benches/bench-consumers/README.md b/benches/bench-consumers/README.md deleted file mode 100644 index ad650983..00000000 --- a/benches/bench-consumers/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Running - -1. After running the [`nats-publisher`](../nats-publisher/README.md) locally, just execute the run on this project: - - ```sh - cargo run - ``` - -2. You can also run benchmarks with cargo: - - ```sh - cargo bench --bench consumers - ``` diff --git a/benches/bench-consumers/benches/consumers.rs b/benches/bench-consumers/benches/consumers.rs deleted file mode 100644 index 8b66907f..00000000 --- a/benches/bench-consumers/benches/consumers.rs +++ /dev/null @@ -1,43 +0,0 @@ -use bench_consumers::runners::{ - runner_consumer::run_blocks_consumer, - runner_kv_watcher::run_watch_kv_blocks, - runner_subscription::run_subscriptions, -}; -use criterion::{criterion_group, criterion_main, Criterion}; -use nats_publisher::utils::nats::NatsHelper; -use tokio::runtime::Runtime; - -static MSGS_LIMIT: usize = 10000; - -fn benchmark_all(c: &mut Criterion) { - let rt = Runtime::new().unwrap(); - let mut group = c.benchmark_group("NATS Benchmarks"); - let nats = rt.block_on(async { NatsHelper::connect(false).await.unwrap() }); - - group.bench_function("consume_blocks_ack_none", |b| { - b.to_async(&rt).iter(|| async { - run_blocks_consumer(&nats, MSGS_LIMIT).await.unwrap() - }); - }); - - group.bench_function("watch_kv_blocks", |b| { - b.to_async(&rt).iter(|| async { - run_watch_kv_blocks(&nats, MSGS_LIMIT).await.unwrap() - }); - }); - - group.bench_function("subscriptions", |b| { - b.to_async(&rt).iter(|| async { - run_subscriptions(&nats, MSGS_LIMIT).await.unwrap() - }); - }); - - group.finish(); -} - -criterion_group!( - name = benches; - config = Criterion::default().sample_size(10); // Adjust sample size as needed - targets = benchmark_all -); -criterion_main!(benches); diff --git a/benches/bench-consumers/src/lib.rs b/benches/bench-consumers/src/lib.rs deleted file mode 100644 index 0edfafa9..00000000 --- a/benches/bench-consumers/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod runners; diff --git a/benches/bench-consumers/src/main.rs b/benches/bench-consumers/src/main.rs deleted file mode 100644 index a4bc6b64..00000000 --- a/benches/bench-consumers/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -use runners::runner_all::run_all_benchmarks; - -mod runners; - -#[tokio::main] -async fn main() -> anyhow::Result<()> { - println!("Running benchmarks"); - run_all_benchmarks().await?; - Ok(()) -} diff --git a/benches/bench-consumers/src/runners/benchmark_results.rs b/benches/bench-consumers/src/runners/benchmark_results.rs deleted file mode 100644 index e4aaaf42..00000000 --- a/benches/bench-consumers/src/runners/benchmark_results.rs +++ /dev/null @@ -1,103 +0,0 @@ -use core::fmt; -use std::time::{Duration, Instant}; - -use chrono::{DateTime, Utc}; -use statrs::statistics::{Data, Distribution}; - -#[derive(Debug, Clone)] -pub struct BenchmarkResult { - pub name: String, - pub message_count: usize, - pub error_count: usize, - start_time: Instant, - pub elapsed_time: Option, - pub messages_per_second: Option, - pub publish_times: Vec, - pub mean_publish_time: Option, - pub messages_limit: usize, -} - -impl fmt::Display for BenchmarkResult { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "\n{}\nBenchmark Results: {}\n{}\nTotal Messages: {}\nTotal Errors: {}\nElapsed Time: {:?}\nMessages per Second: {:.2}\nMean Publish Time: {:?}\n{}", - "=".repeat(50), - self.name, - "=".repeat(50), - self.message_count, - self.error_count, - self.elapsed_time.unwrap_or_default(), - self.messages_per_second.unwrap_or_default(), - self.mean_publish_time.unwrap_or_default(), - "=".repeat(50) - ) - } -} - -impl BenchmarkResult { - pub fn new(name: String, messages_limit: usize) -> Self { - Self { - name, - message_count: 0, - error_count: 0, - start_time: Instant::now(), - elapsed_time: None, - messages_per_second: None, - publish_times: vec![], - mean_publish_time: None, - messages_limit, - } - } - - pub fn increment_message_count(&mut self) { - self.message_count += 1; - } - - pub fn increment_error_count(&mut self) { - self.error_count += 1; - } - - pub fn finalize(&mut self) -> &mut Self { - self.calculate_mean_publish_time(); - let elapsed = self.start_time.elapsed(); - self.elapsed_time = Some(elapsed); - self.messages_per_second = - Some(self.message_count as f64 / elapsed.as_secs_f64()); - self - } - - pub fn is_complete(&self) -> bool { - self.message_count + self.error_count >= self.messages_limit - } - - pub fn add_publish_time(&mut self, timestamp: u128) -> &mut Self { - let current_time = Utc::now(); - let publish_time = - DateTime::::from_timestamp_millis(timestamp as i64) - .expect("Invalid timestamp"); - let duration = current_time - .signed_duration_since(publish_time) - .to_std() - .expect("Duration calculation failed"); - - self.publish_times.push(duration); - self - } - - pub fn calculate_mean_publish_time(&mut self) { - if self.publish_times.is_empty() { - return; - } - - let times_ns: Vec = self - .publish_times - .iter() - .map(|d| d.as_nanos() as f64) - .collect(); - - let data = Data::new(times_ns); - let mean_ns = data.mean().unwrap(); - self.mean_publish_time = Some(Duration::from_nanos(mean_ns as u64)); - } -} diff --git a/benches/bench-consumers/src/runners/mod.rs b/benches/bench-consumers/src/runners/mod.rs deleted file mode 100644 index b1918cbe..00000000 --- a/benches/bench-consumers/src/runners/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod benchmark_results; -pub mod runner_all; -pub mod runner_consumer; -pub mod runner_kv_watcher; -pub mod runner_subscription; diff --git a/benches/bench-consumers/src/runners/runner_all.rs b/benches/bench-consumers/src/runners/runner_all.rs deleted file mode 100644 index 410e4570..00000000 --- a/benches/bench-consumers/src/runners/runner_all.rs +++ /dev/null @@ -1,25 +0,0 @@ -use anyhow::Result; -use nats_publisher::utils::nats::NatsHelper; -use tokio::try_join; - -static MSGS_LIMIT: usize = 5000; - -use super::{ - runner_consumer::run_blocks_consumer, - runner_kv_watcher::run_watch_kv_blocks, - runner_subscription::run_subscriptions, -}; - -#[allow(dead_code)] -pub async fn run_all_benchmarks() -> Result<()> { - let use_nats_compression = false; // adjust as needed - let nats = NatsHelper::connect(use_nats_compression).await?; - - let _ = try_join!( - run_subscriptions(&nats, MSGS_LIMIT), - run_watch_kv_blocks(&nats, MSGS_LIMIT), - run_blocks_consumer(&nats, MSGS_LIMIT), - ); - - Ok(()) -} diff --git a/benches/bench-consumers/src/runners/runner_consumer.rs b/benches/bench-consumers/src/runners/runner_consumer.rs deleted file mode 100644 index bbf02f23..00000000 --- a/benches/bench-consumers/src/runners/runner_consumer.rs +++ /dev/null @@ -1,55 +0,0 @@ -use anyhow::Result; -use async_nats::jetstream::consumer::AckPolicy; -pub use async_nats::jetstream::consumer::{ - pull::Config as PullConsumerConfig, - DeliverPolicy, -}; -use fuel_core_types::blockchain::block::Block; -use fuel_streams_core::prelude::StreamData; -use futures::StreamExt; -use nats_publisher::utils::nats::NatsHelper; - -use super::benchmark_results::BenchmarkResult; - -pub async fn run_blocks_consumer( - nats: &NatsHelper, - limit: usize, -) -> Result<()> { - let mut result = BenchmarkResult::new( - "Blocks Consumer (Ephemeral + AckNone)".into(), - limit, - ); - - let consumer = nats - .stream_blocks - .create_consumer(PullConsumerConfig { - deliver_policy: DeliverPolicy::New, - ack_policy: AckPolicy::None, - ..Default::default() - }) - .await?; - - let mut messages = consumer.messages().await?; - while let Some(message) = messages.next().await { - let msg = message?; - match nats - .data_parser() - .decode::>(&msg.payload) - .await - { - Err(_) => result.increment_error_count(), - Ok(decoded) => { - result - .add_publish_time(decoded.ts_as_millis()) - .increment_message_count(); - if result.is_complete() { - result.finalize(); - println!("{}", result); - break; - } - } - } - } - - Ok(()) -} diff --git a/benches/bench-consumers/src/runners/runner_kv_watcher.rs b/benches/bench-consumers/src/runners/runner_kv_watcher.rs deleted file mode 100644 index a4db8d73..00000000 --- a/benches/bench-consumers/src/runners/runner_kv_watcher.rs +++ /dev/null @@ -1,40 +0,0 @@ -use anyhow::Result; -use fuel_core_types::blockchain::block::Block; -use fuel_streams_core::prelude::StreamData; -use futures::StreamExt; -use nats_publisher::utils::nats::NatsHelper; - -use super::benchmark_results::BenchmarkResult; - -#[allow(dead_code)] -pub async fn run_watch_kv_blocks( - nats: &NatsHelper, - limit: usize, -) -> Result<()> { - let mut result = - BenchmarkResult::new("KV Blocks Watcher".to_string(), limit); - let mut watch = nats.kv_blocks.watch_all().await?; - - while let Some(message) = watch.next().await { - let item = message?; - match nats - .data_parser() - .decode::>(&item.value) - .await - { - Err(_) => result.increment_error_count(), - Ok(decoded) => { - result - .add_publish_time(decoded.ts_as_millis()) - .increment_message_count(); - if result.is_complete() { - result.finalize(); - println!("{}", result); - break; - } - } - } - } - - Ok(()) -} diff --git a/benches/bench-consumers/src/runners/runner_subscription.rs b/benches/bench-consumers/src/runners/runner_subscription.rs deleted file mode 100644 index 1ec3a7f6..00000000 --- a/benches/bench-consumers/src/runners/runner_subscription.rs +++ /dev/null @@ -1,35 +0,0 @@ -use anyhow::Result; -use fuel_core_types::blockchain::block::Block; -use fuel_streams_core::prelude::StreamData; -use futures::StreamExt; -use nats_publisher::utils::nats::NatsHelper; - -use super::benchmark_results::BenchmarkResult; - -#[allow(dead_code)] -pub async fn run_subscriptions(nats: &NatsHelper, limit: usize) -> Result<()> { - let mut result = BenchmarkResult::new("Pub/Sub".to_string(), limit); - let mut subscriber = nats.client.subscribe("blocks.sub.*").await?; - while let Some(message) = subscriber.next().await { - let payload = message.payload; - match nats - .data_parser() - .decode::>(&payload) - .await - { - Err(_) => result.increment_error_count(), - Ok(decoded) => { - result - .add_publish_time(decoded.ts_as_millis()) - .increment_message_count(); - if result.is_complete() { - result.finalize(); - println!("{}", result); - break; - } - } - } - } - - Ok(()) -} diff --git a/benches/load-tester/Cargo.toml b/benches/load-tester/Cargo.toml deleted file mode 100644 index 32f93f06..00000000 --- a/benches/load-tester/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "load-tester" -authors = { workspace = true } -keywords = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } -version = { workspace = true } -rust-version = { workspace = true } -publish = false - -[dependencies] -anyhow = { workspace = true } -async-nats = { workspace = true } -chrono = { workspace = true } -clap = { workspace = true } -fuel-streams = { workspace = true } -fuel-streams-core = { workspace = true, features = ["bench-helpers"] } -futures = { workspace = true } -statrs = "0.18.0" -tokio = { workspace = true } diff --git a/benches/load-tester/README.md b/benches/load-tester/README.md deleted file mode 100644 index 984a28a6..00000000 --- a/benches/load-tester/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Running - -To run the load-test suite: - - ```sh - cargo run -- --network testnet --max-subscriptions 10 --step-size 1 - ``` - -Adjustments are to be applied based on the network, max-subscriptions and step-size. diff --git a/benches/load-tester/src/lib.rs b/benches/load-tester/src/lib.rs deleted file mode 100644 index 0edfafa9..00000000 --- a/benches/load-tester/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod runners; diff --git a/benches/load-tester/src/main.rs b/benches/load-tester/src/main.rs deleted file mode 100644 index b13a223c..00000000 --- a/benches/load-tester/src/main.rs +++ /dev/null @@ -1,16 +0,0 @@ -use clap::Parser; -use load_tester::runners::{cli::Cli, runner_all::LoadTesterEngine}; - -#[tokio::main] -async fn main() -> anyhow::Result<()> { - let cli = Cli::parse(); - println!("Running load test ..."); - let load_tester = LoadTesterEngine::new( - cli.network, - cli.max_subscriptions, - cli.step_size, - ); - load_tester.run().await?; - println!("Finished load testing!"); - Ok(()) -} diff --git a/benches/load-tester/src/runners/cli.rs b/benches/load-tester/src/runners/cli.rs deleted file mode 100644 index 46cb07ad..00000000 --- a/benches/load-tester/src/runners/cli.rs +++ /dev/null @@ -1,33 +0,0 @@ -use clap::Parser; -use fuel_streams::types::FuelNetwork; - -#[derive(Clone, Parser)] -pub struct Cli { - /// Fuel Network to connect to. - #[arg( - long, - value_name = "NETWORK", - env = "NETWORK", - default_value = "Local", - value_parser = clap::value_parser!(FuelNetwork) - )] - pub network: FuelNetwork, - /// Maximum subscriptions for load testing - #[arg( - long, - value_name = "MAXS", - env = "MAX_SUBS", - default_value = "10", - help = "Maximum subscriptions for load testing." - )] - pub max_subscriptions: u16, - /// Maximum step size for load testing - #[arg( - long, - value_name = "SSIZE", - env = "STEP_SIZE", - default_value = "1", - help = "Maximum step size for load testing." - )] - pub step_size: u16, -} diff --git a/benches/load-tester/src/runners/mod.rs b/benches/load-tester/src/runners/mod.rs deleted file mode 100644 index cc84e6f4..00000000 --- a/benches/load-tester/src/runners/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod cli; -pub mod results; -pub mod runner_all; -pub mod runner_streamable; diff --git a/benches/load-tester/src/runners/results.rs b/benches/load-tester/src/runners/results.rs deleted file mode 100644 index fe1b56b8..00000000 --- a/benches/load-tester/src/runners/results.rs +++ /dev/null @@ -1,118 +0,0 @@ -use core::fmt; -use std::{ - sync::{ - atomic::{AtomicUsize, Ordering}, - RwLock, - }, - time::{Duration, Instant}, -}; - -use chrono::{DateTime, Utc}; -use statrs::statistics::{Data, Distribution}; - -#[derive(Debug)] -pub struct LoadTestTracker { - pub name: String, - pub message_count: AtomicUsize, - pub error_count: AtomicUsize, - start_time: Instant, - pub elapsed_time: RwLock>, - pub messages_per_second: RwLock>, - pub publish_times: RwLock>, - pub mean_publish_time: RwLock>, -} - -impl fmt::Display for LoadTestTracker { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "\n{}\nLoadTest Results: {}\n{}\nTotal Messages: {}\nTotal Errors: {}\nElapsed Time: {:?}\nMessages per Second: {:.2}\nMean Publish Time: {:?}\n{}", - "=".repeat(50), - self.name, - "=".repeat(50), - self.message_count.load(Ordering::Relaxed), - self.error_count.load(Ordering::Relaxed), - self.elapsed_time.read().unwrap().unwrap_or_default(), - self.messages_per_second.read().unwrap().unwrap_or_default(), - self.mean_publish_time.read().unwrap().unwrap_or_default(), - "=".repeat(50) - ) - } -} - -impl LoadTestTracker { - pub fn new(name: String) -> Self { - Self { - name, - message_count: AtomicUsize::new(0), - error_count: AtomicUsize::new(0), - start_time: Instant::now(), - elapsed_time: RwLock::new(None), - messages_per_second: RwLock::new(None), - publish_times: RwLock::new(vec![]), - mean_publish_time: RwLock::new(None), - } - } - - pub fn increment_message_count(&self) { - self.message_count.fetch_add(1, Ordering::Relaxed); - } - - pub fn increment_error_count(&self) { - self.error_count.fetch_add(1, Ordering::Relaxed); - } - - pub fn refresh(&self) -> &Self { - self.calculate_mean_publish_time(); - - let elapsed = self.start_time.elapsed(); - let message_count = self.message_count.load(Ordering::Relaxed); - - if let Ok(mut elapsed_time) = self.elapsed_time.write() { - *elapsed_time = Some(elapsed); - } - - if let Ok(mut messages_per_second) = self.messages_per_second.write() { - *messages_per_second = - Some(message_count as f64 / elapsed.as_secs_f64()); - } - - self - } - - pub fn add_publish_time(&self, timestamp: u128) -> &Self { - let current_time = Utc::now(); - let publish_time = - DateTime::::from_timestamp_millis(timestamp as i64) - .expect("Invalid timestamp"); - let duration = current_time - .signed_duration_since(publish_time) - .to_std() - .expect("Duration calculation failed"); - - if let Ok(mut times) = self.publish_times.write() { - times.push(duration); - } - self - } - - pub fn calculate_mean_publish_time(&self) { - // Lock the mutex to access publish_times - let times = self.publish_times.read().unwrap(); - - if times.is_empty() { - return; - } - - let times_ns: Vec = - times.iter().map(|d| d.as_nanos() as f64).collect(); - drop(times); - - let data = Data::new(times_ns); - let mean_ns = data.mean().unwrap(); - - if let Ok(mut mean_publish_time) = self.mean_publish_time.write() { - *mean_publish_time = Some(Duration::from_nanos(mean_ns as u64)); - } - } -} diff --git a/benches/load-tester/src/runners/runner_all.rs b/benches/load-tester/src/runners/runner_all.rs deleted file mode 100644 index 21ee7815..00000000 --- a/benches/load-tester/src/runners/runner_all.rs +++ /dev/null @@ -1,247 +0,0 @@ -use std::{sync::Arc, time::Duration}; - -use anyhow::Result; -use fuel_streams::client::Client; -use fuel_streams_core::prelude::*; -use tokio::task::JoinHandle; - -use super::{ - results::LoadTestTracker, - runner_streamable::run_streamable_consumer, -}; - -pub struct LoadTesterEngine { - max_subscriptions: u16, - step_size: u16, - fuel_network: FuelNetwork, -} - -impl LoadTesterEngine { - pub fn new( - fuel_network: FuelNetwork, - max_subscriptions: u16, - step_size: u16, - ) -> Self { - Self { - fuel_network, - max_subscriptions, - step_size, - } - } -} - -impl LoadTesterEngine { - pub async fn run(&self) -> Result<(), anyhow::Error> { - let client = Client::connect(self.fuel_network).await?; - let mut handles: Vec> = vec![]; - // blocks - let blocks_test_tracker = - Arc::new(LoadTestTracker::new("Blocks Consumer".into())); - let blocks_test_tracker_printer = Arc::clone(&blocks_test_tracker); - - // inputs - let inputs_test_tracker = - Arc::new(LoadTestTracker::new("Inputs Consumer".into())); - let inputs_test_tracker_printer = Arc::clone(&inputs_test_tracker); - - // txs - let txs_test_tracker = - Arc::new(LoadTestTracker::new("Txs Consumer".into())); - let txs_test_tracker_printer = Arc::clone(&txs_test_tracker); - - // receipts - let receipts_test_tracker = - Arc::new(LoadTestTracker::new("Receipts Consumer".into())); - let receipts_test_tracker_printer = Arc::clone(&receipts_test_tracker); - - // utxos - let utxos_test_tracker = - Arc::new(LoadTestTracker::new("Utxos Consumer".into())); - let utxos_test_tracker_printer = Arc::clone(&utxos_test_tracker); - - // logs - let logs_test_tracker = - Arc::new(LoadTestTracker::new("Logs Consumer".into())); - let logs_test_tracker_printer = Arc::clone(&logs_test_tracker); - - // outputs - let outputs_test_tracker = - Arc::new(LoadTestTracker::new("Outputs Consumer".into())); - let outputs_test_tracker_printer = Arc::clone(&outputs_test_tracker); - - // print regularly the tracked metrics - handles.push(tokio::spawn(async move { - loop { - // blocks - blocks_test_tracker_printer.refresh(); - println!("{}", blocks_test_tracker_printer); - - // inputs - inputs_test_tracker_printer.refresh(); - println!("{}", inputs_test_tracker_printer); - - // txs - txs_test_tracker_printer.refresh(); - println!("{}", txs_test_tracker_printer); - - // utxos - utxos_test_tracker_printer.refresh(); - println!("{}", utxos_test_tracker_printer); - - // receipts - receipts_test_tracker_printer.refresh(); - println!("{}", receipts_test_tracker_printer); - - // outputs - outputs_test_tracker_printer.refresh(); - println!("{}", outputs_test_tracker_printer); - - // logs - logs_test_tracker_printer.refresh(); - println!("{}", logs_test_tracker_printer); - - // do a short pause - tokio::time::sleep(Duration::from_secs(5)).await; - } - })); - - // Incrementally increase subscriptions - for current_subs in - (1..=self.max_subscriptions).step_by(self.step_size as usize) - { - let client = client.clone(); - let blocks_test_tracker = Arc::clone(&blocks_test_tracker); - for _ in 0..current_subs { - // blocks - { - let client = client.clone(); - let blocks_test_tracker = Arc::clone(&blocks_test_tracker); - handles.push(tokio::spawn(async move { - if let Err(e) = run_streamable_consumer::( - &client, - blocks_test_tracker, - ) - .await - { - eprintln!( - "Error in blocks subscriptions - {:?}", - e - ); - } - })); - } - // logs - { - let client = client.clone(); - let logs_test_tracker = Arc::clone(&logs_test_tracker); - handles.push(tokio::spawn(async move { - if let Err(e) = run_streamable_consumer::( - &client, - logs_test_tracker, - ) - .await - { - eprintln!("Error in logs subscriptions - {:?}", e); - } - })); - } - // inputs - { - let client = client.clone(); - let inputs_test_tracker = Arc::clone(&inputs_test_tracker); - handles.push(tokio::spawn(async move { - if let Err(e) = run_streamable_consumer::( - &client, - inputs_test_tracker, - ) - .await - { - eprintln!( - "Error in inputs subscriptions - {:?}", - e - ); - } - })); - } - // txs - { - let client = client.clone(); - let txs_test_tracker = Arc::clone(&txs_test_tracker); - handles.push(tokio::spawn(async move { - if let Err(e) = run_streamable_consumer::( - &client, - txs_test_tracker, - ) - .await - { - eprintln!("Error in txs subscriptions - {:?}", e); - } - })); - } - // outputs - { - let client = client.clone(); - let outputs_test_tracker = - Arc::clone(&outputs_test_tracker); - handles.push(tokio::spawn(async move { - if let Err(e) = run_streamable_consumer::( - &client, - outputs_test_tracker, - ) - .await - { - eprintln!( - "Error in outputs subscriptions - {:?}", - e - ); - } - })); - } - // utxos - { - let client = client.clone(); - let utxos_test_tracker = Arc::clone(&utxos_test_tracker); - handles.push(tokio::spawn(async move { - if let Err(e) = run_streamable_consumer::( - &client, - utxos_test_tracker, - ) - .await - { - eprintln!("Error in utxos subscriptions - {:?}", e); - } - })); - } - // receipts - { - let client = client.clone(); - let receipts_test_tracker = - Arc::clone(&receipts_test_tracker); - handles.push(tokio::spawn(async move { - if let Err(e) = run_streamable_consumer::( - &client, - receipts_test_tracker, - ) - .await - { - eprintln!( - "Error in receipts subscriptions - {:?}", - e - ); - } - })); - } - } - - // Small pause between test iterations - tokio::time::sleep(Duration::from_secs(5)).await; - } - - // cleanup - for handle in handles.iter() { - handle.abort(); - } - - Ok(()) - } -} diff --git a/benches/load-tester/src/runners/runner_streamable.rs b/benches/load-tester/src/runners/runner_streamable.rs deleted file mode 100644 index bda6f2db..00000000 --- a/benches/load-tester/src/runners/runner_streamable.rs +++ /dev/null @@ -1,38 +0,0 @@ -use std::sync::Arc; - -use anyhow::Result; -pub use async_nats::jetstream::consumer::DeliverPolicy; -use fuel_streams::{client::Client, StreamConfig}; -use fuel_streams_core::prelude::*; -use futures::StreamExt; - -use super::results::LoadTestTracker; - -pub async fn run_streamable_consumer( - client: &Client, - load_test_tracker: Arc, -) -> Result<()> { - // Create a new stream for blocks - let stream = fuel_streams::Stream::::new(client).await; - - // Configure the stream to start from the last published block - let config = StreamConfig { - deliver_policy: DeliverPolicy::Last, - }; - - // Subscribe to the block stream with the specified configuration - let mut sub = stream.subscribe_raw_with_config(config).await?; - - // Process incoming blocks - while let Some(bytes) = sub.next().await { - load_test_tracker.increment_message_count(); - let decoded_msg = S::decode_raw(bytes).unwrap(); - - let ts_millis = decoded_msg.ts_as_millis(); - load_test_tracker - .add_publish_time(ts_millis) - .increment_message_count(); - } - - Ok(()) -} diff --git a/benches/nats-publisher/Cargo.toml b/benches/nats-publisher/Cargo.toml deleted file mode 100644 index 365a8df3..00000000 --- a/benches/nats-publisher/Cargo.toml +++ /dev/null @@ -1,28 +0,0 @@ -[package] -name = "nats-publisher" -authors = { workspace = true } -keywords = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } -version = { workspace = true } -rust-version = { workspace = true } -publish = false - -[dependencies] -anyhow = { workspace = true } -async-nats = { workspace = true } -clap = { workspace = true } -fuel-core = { workspace = true } -fuel-core-bin = { workspace = true } -fuel-core-importer = { workspace = true } -fuel-core-storage = { workspace = true } -fuel-core-types = { workspace = true } -fuel-data-parser = { workspace = true } -fuel-streams-core = { workspace = true } -tokio = { workspace = true } -tracing = { workspace = true } - -[dev-dependencies] -criterion = { version = "0.5", features = ["html_reports", "async_tokio"] } diff --git a/benches/nats-publisher/README.md b/benches/nats-publisher/README.md deleted file mode 100644 index 1dbe8ad5..00000000 --- a/benches/nats-publisher/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# Running - -1. First make sure you have your `.env` configured properly: - - ```sh - make create-env - ``` - -2. Make sure you have NATS server running within the workspace root: - - ```sh - make start-nats - ``` - -3. The, you can start local node and start publishing on NATS: - ```sh - make run-publisher - ``` diff --git a/benches/nats-publisher/config/nats.conf b/benches/nats-publisher/config/nats.conf deleted file mode 100644 index e2b7d425..00000000 --- a/benches/nats-publisher/config/nats.conf +++ /dev/null @@ -1,5 +0,0 @@ -jetstream: { - max_mem_store: 64MiB, - max_file_store: 10GiB -} -max_payload = 8388608 diff --git a/benches/nats-publisher/src/lib.rs b/benches/nats-publisher/src/lib.rs deleted file mode 100644 index 3bed9398..00000000 --- a/benches/nats-publisher/src/lib.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[allow(unused)] -pub mod utils; diff --git a/benches/nats-publisher/src/main.rs b/benches/nats-publisher/src/main.rs deleted file mode 100644 index 62050a44..00000000 --- a/benches/nats-publisher/src/main.rs +++ /dev/null @@ -1,78 +0,0 @@ -mod utils; - -use clap::Parser; -use fuel_core_importer::ports::ImporterDatabase; -use fuel_streams_core::prelude::*; -use utils::{blocks::BlockHelper, nats::NatsHelper, tx::TxHelper}; - -#[derive(Parser)] -pub struct Cli { - #[command(flatten)] - fuel_core_config: fuel_core_bin::cli::run::Command, -} - -#[tokio::main] -async fn main() -> anyhow::Result<()> { - fuel_core_bin::cli::init_logging(); - - let cli = Cli::parse(); - let service = - fuel_core_bin::cli::run::get_service(cli.fuel_core_config).await?; - let chain_config = service.shared.config.snapshot_reader.chain_config(); - let chain_id = chain_config.consensus_parameters.chain_id(); - let block_importer = service.shared.block_importer.block_importer.clone(); - let database = service.shared.database.clone(); - - service - .start_and_await() - .await - .expect("Fuel core service startup failed"); - - // ------------------------------------------------------------------------ - // NATS - // ------------------------------------------------------------------------ - let nats = NatsHelper::connect(true).await?; - let block_helper = BlockHelper::new(nats.to_owned(), &database); - let tx_helper = TxHelper::new(nats.to_owned(), &chain_id, &database); - - // ------------------------------------------------------------------------ - // OLD BLOCKS - // ------------------------------------------------------------------------ - tokio::task::spawn({ - let database = database.clone(); - let block_helper = block_helper.clone(); - let _tx_helper = tx_helper.clone(); - let last_height = database.on_chain().latest_block_height()?.unwrap(); - async move { - for height in 0..*last_height { - let height = height.into(); - let block = block_helper.find_by_height(height); - let block = - Block::new(&block, Consensus::default(), Vec::new()); - - block_helper.publish(&block).await?; - // for (index, tx) in block.transactions().iter().enumerate() { - // tx_helper.publish(&block, tx, index).await?; - // } - } - Ok::<(), async_nats::Error>(()) - } - }); - - // ------------------------------------------------------------------------ - // NEW BLOCKS - // ------------------------------------------------------------------------ - let mut subscription = block_importer.subscribe(); - while let Ok(result) = subscription.recv().await { - let result = &**result; - let block = &result.sealed_block.entity; - let block = Block::new(block, Consensus::default(), Vec::new()); - - block_helper.publish(&block).await?; - // for (index, tx) in block.transactions().iter().enumerate() { - // tx_helper.publish(block, tx, index).await?; - // } - } - - Ok(()) -} diff --git a/benches/nats-publisher/src/utils/blocks.rs b/benches/nats-publisher/src/utils/blocks.rs deleted file mode 100644 index 3f192f7c..00000000 --- a/benches/nats-publisher/src/utils/blocks.rs +++ /dev/null @@ -1,93 +0,0 @@ -use async_nats::jetstream::context::Publish; -use fuel_core::combined_database::CombinedDatabase; -use fuel_core_storage::transactional::AtomicView; -use fuel_streams_core::prelude::*; -use tokio::try_join; -use tracing::info; - -use super::nats::NatsHelper; - -#[derive(Clone)] -pub struct BlockHelper { - nats: NatsHelper, - database: CombinedDatabase, -} - -impl BlockHelper { - pub fn new(nats: NatsHelper, database: &CombinedDatabase) -> Self { - Self { - nats, - database: database.to_owned(), - } - } - - pub fn find_by_height(&self, height: FuelCoreBlockHeight) -> FuelCoreBlock { - self.database - .on_chain() - .latest_view() - .unwrap() - .get_sealed_block_by_height(&height) - .unwrap() - .unwrap_or_else(|| { - panic!("NATS Publisher: no block at height {height}") - }) - .entity - } - - pub async fn publish(&self, block: &Block) -> anyhow::Result<()> { - try_join!( - self.publish_core(block), - self.publish_encoded(block), - self.publish_to_kv(block) - )?; - Ok(()) - } -} - -/// Publisher -impl BlockHelper { - async fn publish_core(&self, block: &Block) -> anyhow::Result<()> { - let subject: BlocksSubject = block.into(); - let payload = self.nats.data_parser().encode(block).await?; - self.nats - .context - .publish(subject.parse(), payload.into()) - .await?; - - Ok(()) - } - async fn publish_encoded(&self, block: &Block) -> anyhow::Result<()> { - let height = block.height; - let subject: BlocksSubject = block.into(); - let payload = self.nats.data_parser().encode(block).await?; - let nats_payload = Publish::build() - .message_id(subject.parse()) - .payload(payload.into()); - - self.nats - .context - .send_publish(subject.parse(), nats_payload) - .await? - .await?; - - info!( - "NATS: publishing block {} encoded to stream \"blocks_encoded\"", - height - ); - Ok(()) - } - - async fn publish_to_kv(&self, block: &Block) -> anyhow::Result<()> { - let height = block.height; - let subject: BlocksSubject = block.into(); - - let payload = self.nats.data_parser().encode(block).await?; - self.nats - .kv_blocks - .put(subject.parse(), payload.into()) - .await?; - - info!("NATS: publishing block {} to kv store \"blocks\"", height); - Ok(()) - } -} diff --git a/benches/nats-publisher/src/utils/mod.rs b/benches/nats-publisher/src/utils/mod.rs deleted file mode 100644 index 642417eb..00000000 --- a/benches/nats-publisher/src/utils/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod blocks; -pub mod nats; -pub mod tx; diff --git a/benches/nats-publisher/src/utils/nats.rs b/benches/nats-publisher/src/utils/nats.rs deleted file mode 100644 index 2a6e3ad6..00000000 --- a/benches/nats-publisher/src/utils/nats.rs +++ /dev/null @@ -1,130 +0,0 @@ -use async_nats::{ - jetstream::{ - kv::{self, Store}, - stream::{self, Compression, Stream}, - Context, - }, - ConnectOptions, -}; -use fuel_data_parser::DataParser; -use fuel_streams_core::prelude::FuelNetwork; - -#[allow(dead_code)] -#[derive(Clone)] -pub struct NatsHelper { - pub client: async_nats::Client, - pub kv_blocks: Store, - pub kv_transactions: Store, - pub context: Context, - pub stream_blocks: Stream, - pub stream_transactions: Stream, - pub use_nats_compression: bool, - pub data_parser: DataParser, -} - -impl NatsHelper { - pub async fn connect(use_nats_compression: bool) -> anyhow::Result { - let client = connect().await?; - let ( - context, - kv_blocks, - kv_transactions, - stream_blocks, - stream_transactions, - ) = create_resources(&client, use_nats_compression).await?; - // adjust as needed - let data_parser = DataParser::default(); - - Ok(Self { - client, - context, - kv_blocks, - kv_transactions, - stream_blocks, - stream_transactions, - use_nats_compression, - data_parser, - }) - } - - #[allow(dead_code)] - pub fn data_parser(&self) -> &DataParser { - &self.data_parser - } - - #[allow(dead_code)] - pub fn data_parser_mut(&mut self) -> &mut DataParser { - &mut self.data_parser - } -} - -pub async fn connect() -> anyhow::Result { - Ok(ConnectOptions::new() - .user_and_password("admin".into(), "secret".into()) - .connect(FuelNetwork::Local.to_nats_url()) - .await?) -} - -async fn create_resources( - client: &async_nats::Client, - use_nats_compression: bool, -) -> anyhow::Result<(Context, Store, Store, Stream, Stream)> { - let jetstream = async_nats::jetstream::new(client.clone()); - - // ------------------------------------------------------------------------ - // BLOCKS - // ------------------------------------------------------------------------ - let stream_blocks = jetstream - .get_or_create_stream(stream::Config { - name: "blocks_encoded".into(), - subjects: vec!["blocks.>".into()], - compression: if use_nats_compression { - Some(Compression::S2) - } else { - None - }, - ..Default::default() - }) - .await?; - - // TRANSACTIONS - // ------------------------------------------------------------------------ - let stream_transactions = jetstream - .get_or_create_stream(stream::Config { - name: "transactions_encoded".into(), - subjects: vec!["transactions.>".into()], - compression: if use_nats_compression { - Some(Compression::S2) - } else { - None - }, - ..Default::default() - }) - .await?; - - // KV STORE - // ------------------------------------------------------------------------ - let kv_blocks = jetstream - .create_key_value(kv::Config { - compression: use_nats_compression, - bucket: "blocks".into(), - ..Default::default() - }) - .await?; - - let kv_transactions = jetstream - .create_key_value(kv::Config { - compression: use_nats_compression, - bucket: "transactions".into(), - ..Default::default() - }) - .await?; - - Ok(( - jetstream, - kv_blocks, - kv_transactions, - stream_blocks, - stream_transactions, - )) -} diff --git a/benches/nats-publisher/src/utils/tx.rs b/benches/nats-publisher/src/utils/tx.rs deleted file mode 100644 index 49da5f26..00000000 --- a/benches/nats-publisher/src/utils/tx.rs +++ /dev/null @@ -1,129 +0,0 @@ -use async_nats::jetstream::context::Publish; -use fuel_core::combined_database::CombinedDatabase; -use fuel_core_types::fuel_types::ChainId; -use fuel_streams_core::prelude::*; -use tokio::try_join; -use tracing::info; - -use super::nats::NatsHelper; - -#[allow(unused)] -#[derive(Clone)] -pub struct TxHelper { - nats: NatsHelper, - chain_id: ChainId, - database: CombinedDatabase, -} - -#[allow(unused)] -/// Public -impl TxHelper { - pub fn new( - nats: NatsHelper, - chain_id: &ChainId, - database: &CombinedDatabase, - ) -> Self { - Self { - nats, - chain_id: chain_id.to_owned(), - database: database.to_owned(), - } - } - - pub async fn publish( - &self, - block: &Block, - tx: &Transaction, - index: usize, - ) -> anyhow::Result<()> { - try_join!( - self.publish_core(block, tx, index), - self.publish_encoded(block, tx, index), - self.publish_to_kv(block, tx, index) - )?; - Ok(()) - } -} - -/// Publishers -impl TxHelper { - async fn publish_core( - &self, - block: &Block, - tx: &Transaction, - index: usize, - ) -> anyhow::Result<()> { - let subject = &self.get_subject(tx, block, index); - let payload = self.nats.data_parser().encode(block).await?; - self.nats - .context - .publish(subject.parse(), payload.into()) - .await?; - Ok(()) - } - - async fn publish_encoded( - &self, - block: &Block, - tx: &Transaction, - index: usize, - ) -> anyhow::Result<()> { - let tx_id = &tx.id; - let subject = self.get_subject(tx, block, index); - let payload = self.nats.data_parser().encode(block).await?; - let nats_payload = Publish::build() - .message_id(subject.parse()) - .payload(payload.into()); - - self.nats - .context - .send_publish(subject.parse(), nats_payload) - .await? - .await?; - - info!( - "NATS: publishing transaction {} json to stream \"transactions_encoded\"", - tx_id - ); - Ok(()) - } - - async fn publish_to_kv( - &self, - block: &Block, - tx: &Transaction, - index: usize, - ) -> anyhow::Result<()> { - let tx_id = &tx.id; - let subject = self.get_subject(tx, block, index); - let payload = self.nats.data_parser().encode(block).await?; - self.nats - .kv_transactions - .put(subject.parse(), payload.into()) - .await?; - - info!( - "NATS: publishing transaction {} to kv store \"transactions\"", - tx_id - ); - Ok(()) - } -} - -/// Getters -impl TxHelper { - fn get_subject( - &self, - tx: &Transaction, - block: &Block, - index: usize, - ) -> TransactionsSubject { - // construct tx subject - let mut subject: TransactionsSubject = tx.into(); - subject = subject - .with_index(Some(index)) - .with_block_height(Some(BlockHeight::from(block.height))) - .with_status(Some(tx.status.clone())); - subject - } -} diff --git a/crates/fuel-streams-core/README.md b/crates/fuel-streams-core/README.md index 221aca64..2cf4ec9f 100644 --- a/crates/fuel-streams-core/README.md +++ b/crates/fuel-streams-core/README.md @@ -61,7 +61,7 @@ use futures::StreamExt; #[tokio::main] async fn main() -> BoxedResult<()> { // Connect to NATS server - let nats_opts = NatsClientOpts::new(FuelNetwork::Local); + let nats_opts = NatsClientOpts::admin_opts(); let nats_client = NatsClient::connect(&nats_opts).await?; let s3_opts = S3ClientOpts::new(FuelNetwork::Local); diff --git a/crates/fuel-streams-storage/src/nats/nats_client.rs b/crates/fuel-streams-storage/src/nats/nats_client.rs index e734f697..ea3899d4 100644 --- a/crates/fuel-streams-storage/src/nats/nats_client.rs +++ b/crates/fuel-streams-storage/src/nats/nats_client.rs @@ -15,10 +15,9 @@ use super::{types::*, NatsClientOpts, NatsError, NatsNamespace}; /// /// ```no_run /// use fuel_streams_storage::nats::*; -/// use fuel_networks::FuelNetwork; /// /// async fn example() -> Result<(), Box> { -/// let opts = NatsClientOpts::new(FuelNetwork::Local); +/// let opts = NatsClientOpts::public_opts(); /// let client = NatsClient::connect(&opts).await?; /// Ok(()) /// } @@ -28,11 +27,10 @@ use super::{types::*, NatsClientOpts, NatsError, NatsNamespace}; /// /// ```no_run /// use fuel_streams_storage::nats::*; -/// use fuel_networks::FuelNetwork; /// use async_nats::jetstream::kv; /// /// async fn example() -> Result<(), Box> { -/// let opts = NatsClientOpts::new(FuelNetwork::Local); +/// let opts = NatsClientOpts::public_opts(); /// let client = NatsClient::connect(&opts).await?; /// let kv_config = kv::Config { /// bucket: "my-bucket".into(), From 559d20e414ce3d6a1f6fc4dde0ddfbf4271f63bf Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 01:45:57 -0300 Subject: [PATCH 06/31] refactor(repo): general improvements --- .env.sample | 33 ++++-- Cargo.lock | 25 ++-- Cargo.toml | 1 + crates/fuel-streams-core/Cargo.toml | 1 + crates/fuel-streams-core/README.md | 2 +- crates/fuel-streams-core/src/lib.rs | 2 +- .../src/stream/stream_impl.rs | 3 +- crates/fuel-streams-nats/Cargo.toml | 29 +++++ .../nats => fuel-streams-nats/src}/error.rs | 0 .../mod.rs => fuel-streams-nats/src/lib.rs} | 9 +- .../src}/nats_client.rs | 4 +- .../src}/nats_client_opts.rs | 67 ++++++++--- .../src}/nats_namespace.rs | 6 +- .../nats => fuel-streams-nats/src}/types.rs | 0 crates/fuel-streams-storage/Cargo.toml | 6 +- crates/fuel-streams-storage/src/lib.rs | 4 - .../fuel-streams-storage/src/s3/s3_client.rs | 25 ++-- .../src/s3/s3_client_opts.rs | 111 +++++++++++++----- crates/fuel-streams-ws/Cargo.toml | 1 + .../fuel-streams-ws/src/server/ws/models.rs | 2 +- .../fuel-streams-ws/src/server/ws/socket.rs | 2 +- crates/fuel-streams/src/client/client_impl.rs | 19 ++- tests/Cargo.toml | 4 - tests/tests/client.rs | 3 +- 24 files changed, 241 insertions(+), 118 deletions(-) create mode 100644 crates/fuel-streams-nats/Cargo.toml rename crates/{fuel-streams-storage/src/nats => fuel-streams-nats/src}/error.rs (100%) rename crates/{fuel-streams-storage/src/nats/mod.rs => fuel-streams-nats/src/lib.rs} (84%) rename crates/{fuel-streams-storage/src/nats => fuel-streams-nats/src}/nats_client.rs (97%) rename crates/{fuel-streams-storage/src/nats => fuel-streams-nats/src}/nats_client_opts.rs (77%) rename crates/{fuel-streams-storage/src/nats => fuel-streams-nats/src}/nats_namespace.rs (92%) rename crates/{fuel-streams-storage/src/nats => fuel-streams-nats/src}/types.rs (100%) diff --git a/.env.sample b/.env.sample index 5b6c89de..928ab29f 100644 --- a/.env.sample +++ b/.env.sample @@ -1,26 +1,33 @@ -# Common Configuration +# Authentication & Security KEYPAIR=generated-p2p-secret -NATS_URL=nats://localhost:4222 -NATS_ADMIN_PASS=generated-secret -NATS_SYSTEM_PASS=generated-secret +JWT_AUTH_SECRET=generated-secret + +# AWS S3 Configuration AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test -AWS_REGION=us-east-1 AWS_ENDPOINT_URL=http://localhost:4566 -AWS_S3_BUCKET_NAME=fuel-streams-testnet +AWS_REGION=us-east-1 +AWS_S3_ENABLED=false +AWS_S3_BUCKET_NAME=fuel-streams-local + +# NATS Configuration +NATS_URL=nats://localhost:4222 +NATS_SYSTEM_USER=sys +NATS_SYSTEM_PASS=sys +NATS_ADMIN_USER=admin +NATS_ADMIN_PASS=admin +NATS_PUBLIC_USER=default_user +NATS_PUBLIC_PASS="" + +# Monitoring & Logging USE_ELASTIC_LOGGING=false USE_METRICS=true PUBLISHER_MAX_THREADS=16 + +# Elasticsearch Configuration ELASTICSEARCH_URL=http://127.0.0.1:9200 ELASTICSEARCH_USERNAME=elastic ELASTICSEARCH_PASSWORD=generated-secret -AWS_S3_ENABLED=false -AWS_ACCESS_KEY_ID=s3-access-key-id -AWS_SECRET_ACCESS_KEY=s3-secret-access-key -AWS_REGION=s3-region -AWS_ENDPOINT_URL=s3-endpoint -AWS_S3_BUCKET_NAME=fuel-streams-local -JWT_AUTH_SECRET=generated-secret # Mainnet Configuration MAINNET_RELAYER=https://mainnet.infura.io/v3/ diff --git a/Cargo.lock b/Cargo.lock index f32d9ffb..139e30dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4148,6 +4148,7 @@ dependencies = [ "fuel-data-parser", "fuel-networks", "fuel-streams-macros", + "fuel-streams-nats", "fuel-streams-storage", "futures", "hex", @@ -4199,23 +4200,34 @@ dependencies = [ ] [[package]] -name = "fuel-streams-storage" +name = "fuel-streams-nats" version = "0.0.13" dependencies = [ "async-nats", + "displaydoc", + "dotenvy", + "pretty_assertions", + "rand", + "serde_json", + "thiserror 2.0.8", + "tokio", + "tracing", +] + +[[package]] +name = "fuel-streams-storage" +version = "0.0.13" +dependencies = [ "aws-config", "aws-sdk-s3", "aws-smithy-runtime-api", "aws-smithy-types", - "displaydoc", "dotenvy", - "fuel-networks", "pretty_assertions", "rand", "serde_json", "thiserror 2.0.8", "tokio", - "tracing", ] [[package]] @@ -4239,6 +4251,7 @@ dependencies = [ "elasticsearch", "fuel-streams", "fuel-streams-core", + "fuel-streams-nats", "fuel-streams-storage", "futures", "futures-util", @@ -9039,11 +9052,7 @@ checksum = "d7beae5182595e9a8b683fa98c4317f956c9a2dec3b9716990d20023cc60c766" name = "streams-tests" version = "0.0.13" dependencies = [ - "anyhow", - "async-trait", "fuel-core", - "fuel-core-importer", - "fuel-core-types 0.40.2", "fuel-streams", "fuel-streams-core", "futures", diff --git a/Cargo.toml b/Cargo.toml index 89507d35..43e054c8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,6 +75,7 @@ fuel-data-parser = { version = "0.0.13", path = "crates/fuel-data-parser" } fuel-streams-core = { version = "0.0.13", path = "crates/fuel-streams-core" } fuel-streams-ws = { version = "0.0.13", path = "crates/fuel-streams-ws" } fuel-streams-macros = { version = "0.0.13", path = "crates/fuel-streams-macros" } +fuel-streams-nats = { version = "0.0.13", path = "crates/fuel-streams-nats" } fuel-streams-storage = { version = "0.0.13", path = "crates/fuel-streams-storage" } subject-derive = { version = "0.0.13", path = "crates/fuel-streams-macros/subject-derive" } fuel-streams-executors = { version = "0.0.13", path = "crates/fuel-streams-executors" } diff --git a/crates/fuel-streams-core/Cargo.toml b/crates/fuel-streams-core/Cargo.toml index 703f641e..7161a10b 100644 --- a/crates/fuel-streams-core/Cargo.toml +++ b/crates/fuel-streams-core/Cargo.toml @@ -35,6 +35,7 @@ fuel-core-types = { workspace = true, default-features = false, features = ["std fuel-data-parser = { workspace = true } fuel-networks = { workspace = true } fuel-streams-macros = { workspace = true } +fuel-streams-nats = { workspace = true } fuel-streams-storage = { workspace = true } futures = { workspace = true } hex = { workspace = true } diff --git a/crates/fuel-streams-core/README.md b/crates/fuel-streams-core/README.md index 2cf4ec9f..69684062 100644 --- a/crates/fuel-streams-core/README.md +++ b/crates/fuel-streams-core/README.md @@ -64,7 +64,7 @@ async fn main() -> BoxedResult<()> { let nats_opts = NatsClientOpts::admin_opts(); let nats_client = NatsClient::connect(&nats_opts).await?; - let s3_opts = S3ClientOpts::new(FuelNetwork::Local); + let s3_opts = S3ClientOpts::new(S3Env::Local, S3Role::Admin); let s3_client = Arc::new(S3Client::new(&s3_opts).await?); // Create a stream for blocks diff --git a/crates/fuel-streams-core/src/lib.rs b/crates/fuel-streams-core/src/lib.rs index 54428083..ba8b30f8 100644 --- a/crates/fuel-streams-core/src/lib.rs +++ b/crates/fuel-streams-core/src/lib.rs @@ -9,7 +9,7 @@ pub mod transactions; pub mod utxos; pub mod nats { - pub use fuel_streams_storage::nats::*; + pub use fuel_streams_nats::*; } pub mod s3 { diff --git a/crates/fuel-streams-core/src/stream/stream_impl.rs b/crates/fuel-streams-core/src/stream/stream_impl.rs index e64f1853..5976dc89 100644 --- a/crates/fuel-streams-core/src/stream/stream_impl.rs +++ b/crates/fuel-streams-core/src/stream/stream_impl.rs @@ -10,12 +10,11 @@ use async_nats::{ }; use async_trait::async_trait; use fuel_streams_macros::subject::IntoSubject; -use fuel_streams_storage::*; use futures::{stream::BoxStream, StreamExt, TryStreamExt}; use sha2::{Digest, Sha256}; use tokio::sync::OnceCell; -use super::{error::StreamError, stream_encoding::StreamEncoder}; +use crate::prelude::*; #[derive(Debug, Clone)] pub struct PublishPacket { diff --git a/crates/fuel-streams-nats/Cargo.toml b/crates/fuel-streams-nats/Cargo.toml new file mode 100644 index 00000000..60254899 --- /dev/null +++ b/crates/fuel-streams-nats/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "fuel-streams-nats" +description = "Strategies and adapters for storing fuel streams in NATS" +authors = { workspace = true } +keywords = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +version = { workspace = true } +rust-version = { workspace = true } + +[dependencies] +async-nats = { workspace = true } +displaydoc = { workspace = true } +dotenvy = { workspace = true } +rand = { workspace = true } +thiserror = { workspace = true } +tracing = { workspace = true } + +[dev-dependencies] +pretty_assertions = { workspace = true } +serde_json = { workspace = true } +tokio = { workspace = true, features = ["rt-multi-thread", "macros", "test-util"] } + +[features] +default = [] +test-helpers = [] +bench-helpers = [] diff --git a/crates/fuel-streams-storage/src/nats/error.rs b/crates/fuel-streams-nats/src/error.rs similarity index 100% rename from crates/fuel-streams-storage/src/nats/error.rs rename to crates/fuel-streams-nats/src/error.rs diff --git a/crates/fuel-streams-storage/src/nats/mod.rs b/crates/fuel-streams-nats/src/lib.rs similarity index 84% rename from crates/fuel-streams-storage/src/nats/mod.rs rename to crates/fuel-streams-nats/src/lib.rs index 63359fd2..0b664ba9 100644 --- a/crates/fuel-streams-storage/src/nats/mod.rs +++ b/crates/fuel-streams-nats/src/lib.rs @@ -2,11 +2,10 @@ /// As much as possible, the public interface/APIS should be agnostic of NATS. These can then be extended /// in the fuel-streams-publisher and fuel-streams crates to provide a more opinionated API towards /// their specific use-cases. -mod error; -mod nats_client; -mod nats_client_opts; -mod nats_namespace; - +pub mod error; +pub mod nats_client; +pub mod nats_client_opts; +pub mod nats_namespace; pub mod types; pub use error::*; diff --git a/crates/fuel-streams-storage/src/nats/nats_client.rs b/crates/fuel-streams-nats/src/nats_client.rs similarity index 97% rename from crates/fuel-streams-storage/src/nats/nats_client.rs rename to crates/fuel-streams-nats/src/nats_client.rs index ea3899d4..fd3474fa 100644 --- a/crates/fuel-streams-storage/src/nats/nats_client.rs +++ b/crates/fuel-streams-nats/src/nats_client.rs @@ -14,7 +14,7 @@ use super::{types::*, NatsClientOpts, NatsError, NatsNamespace}; /// Creating a new `NatsClient`: /// /// ```no_run -/// use fuel_streams_storage::nats::*; +/// use fuel_streams_nats::*; /// /// async fn example() -> Result<(), Box> { /// let opts = NatsClientOpts::public_opts(); @@ -26,7 +26,7 @@ use super::{types::*, NatsClientOpts, NatsError, NatsNamespace}; /// Creating a key-value store: /// /// ```no_run -/// use fuel_streams_storage::nats::*; +/// use fuel_streams_nats::*; /// use async_nats::jetstream::kv; /// /// async fn example() -> Result<(), Box> { diff --git a/crates/fuel-streams-storage/src/nats/nats_client_opts.rs b/crates/fuel-streams-nats/src/nats_client_opts.rs similarity index 77% rename from crates/fuel-streams-storage/src/nats/nats_client_opts.rs rename to crates/fuel-streams-nats/src/nats_client_opts.rs index 101825ba..ef196b34 100644 --- a/crates/fuel-streams-storage/src/nats/nats_client_opts.rs +++ b/crates/fuel-streams-nats/src/nats_client_opts.rs @@ -36,6 +36,37 @@ impl NatsAuth { } } +/// Configuration options for connecting to NATS +/// +/// # Examples +/// +/// ```no_run +/// use fuel_streams_nats::*; +/// +/// // Create with URL +/// let opts = NatsClientOpts::new("nats://localhost:4222".to_string(), Some(NatsAuth::Admin)); +/// +/// // Create with admin credentials from environment +/// let opts = NatsClientOpts::admin_opts(); +/// +/// // Create with system credentials from environment +/// let opts = NatsClientOpts::system_opts(); +/// +/// // Create with public credentials +/// let opts = NatsClientOpts::public_opts(); +/// ``` +/// +/// Customize options: +/// +/// ```no_run +/// use fuel_streams_nats::*; +/// +/// let opts = NatsClientOpts::new("nats://localhost:4222".to_string(), Some(NatsAuth::Admin)) +/// .with_domain("mydomain") +/// .with_user("myuser") +/// .with_password("mypass") +/// .with_timeout(10); +/// ``` #[derive(Debug, Clone)] pub struct NatsClientOpts { /// The URL of the NATS server. @@ -53,17 +84,22 @@ pub struct NatsClientOpts { } impl NatsClientOpts { - pub fn new(url: String) -> Self { + pub fn new(url: String, auth: Option) -> Self { + let (user, pass) = auth.unwrap_or_default().credentials_from_env(); Self { url, namespace: NatsNamespace::default(), timeout_secs: 5, domain: None, - user: None, - password: None, + user: Some(user), + password: Some(pass), } } + pub fn from_env(auth: Option) -> Self { + let url = dotenvy::var("NATS_URL").expect("NATS_URL must be set"); + Self::new(url, auth) + } pub fn admin_opts() -> Self { Self::from_env(Some(NatsAuth::Admin)) } @@ -74,37 +110,34 @@ impl NatsClientOpts { Self::from_env(Some(NatsAuth::Public)) } - pub fn from_env(auth: Option) -> Self { - let url = dotenvy::var("NATS_URL").expect("NATS_URL must be set"); - let (user, pass) = auth.unwrap_or_default().credentials_from_env(); - Self::new(url).with_user(user).with_password(pass) - } - pub fn get_url(&self) -> String { self.url.clone() } - pub fn with_url(self, url: String) -> Self { - Self { url, ..self } + pub fn with_url>(self, url: S) -> Self { + Self { + url: url.into(), + ..self + } } - pub fn with_domain(self, domain: String) -> Self { + pub fn with_domain>(self, domain: S) -> Self { Self { - domain: Some(domain), + domain: Some(domain.into()), ..self } } - pub fn with_user(self, user: String) -> Self { + pub fn with_user>(self, user: S) -> Self { Self { - user: Some(user), + user: Some(user.into()), ..self } } - pub fn with_password(self, password: String) -> Self { + pub fn with_password>(self, password: S) -> Self { Self { - password: Some(password), + password: Some(password.into()), ..self } } diff --git a/crates/fuel-streams-storage/src/nats/nats_namespace.rs b/crates/fuel-streams-nats/src/nats_namespace.rs similarity index 92% rename from crates/fuel-streams-storage/src/nats/nats_namespace.rs rename to crates/fuel-streams-nats/src/nats_namespace.rs index c89f5fd2..947e8760 100644 --- a/crates/fuel-streams-storage/src/nats/nats_namespace.rs +++ b/crates/fuel-streams-nats/src/nats_namespace.rs @@ -7,7 +7,7 @@ static DEFAULT_NAMESPACE: &str = "fuel"; /// # Examples /// /// ``` -/// use fuel_streams_storage::nats::NatsNamespace; +/// use fuel_streams_nats::NatsNamespace; /// /// let default_namespace = NatsNamespace::default(); /// assert_eq!(default_namespace.to_string(), "fuel"); @@ -44,7 +44,7 @@ impl NatsNamespace { /// # Examples /// /// ``` - /// use fuel_streams_storage::nats::NatsNamespace; + /// use fuel_streams_nats::NatsNamespace; /// /// let namespace = NatsNamespace::default(); /// assert_eq!(namespace.subject_name("test"), "fuel.test"); @@ -61,7 +61,7 @@ impl NatsNamespace { /// # Examples /// /// ``` - /// use fuel_streams_storage::nats::NatsNamespace; + /// use fuel_streams_nats::NatsNamespace; /// /// let namespace = NatsNamespace::default(); /// assert_eq!(namespace.stream_name("test"), "fuel_test"); diff --git a/crates/fuel-streams-storage/src/nats/types.rs b/crates/fuel-streams-nats/src/types.rs similarity index 100% rename from crates/fuel-streams-storage/src/nats/types.rs rename to crates/fuel-streams-nats/src/types.rs diff --git a/crates/fuel-streams-storage/Cargo.toml b/crates/fuel-streams-storage/Cargo.toml index c8478563..476e0882 100644 --- a/crates/fuel-streams-storage/Cargo.toml +++ b/crates/fuel-streams-storage/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fuel-streams-storage" -description = "strategies and adapters for storing fuel streams in transient and file storage systems (i.e. NATS and S3)" +description = "Srategies and adapters for storing fuel streams in transient and file storage systems (i.e. NATS and S3)" authors = { workspace = true } keywords = { workspace = true } edition = { workspace = true } @@ -11,17 +11,13 @@ version = { workspace = true } rust-version = { workspace = true } [dependencies] -async-nats = { workspace = true } aws-config = { version = "1.5.10", features = ["behavior-version-latest"] } aws-sdk-s3 = "1.65.0" aws-smithy-runtime-api = "1.7.3" aws-smithy-types = "=1.2.9" -displaydoc = { workspace = true } dotenvy = { workspace = true } -fuel-networks = { workspace = true } rand = { workspace = true } thiserror = { workspace = true } -tracing = { workspace = true } [dev-dependencies] pretty_assertions = { workspace = true } diff --git a/crates/fuel-streams-storage/src/lib.rs b/crates/fuel-streams-storage/src/lib.rs index 15f3b0ec..f5cf85aa 100644 --- a/crates/fuel-streams-storage/src/lib.rs +++ b/crates/fuel-streams-storage/src/lib.rs @@ -1,7 +1,3 @@ // TODO: Introduce Adapters for Transient and FileStorage (NATS and S3 clients would implement those) - -pub mod nats; pub mod s3; - -pub use nats::*; pub use s3::*; diff --git a/crates/fuel-streams-storage/src/s3/s3_client.rs b/crates/fuel-streams-storage/src/s3/s3_client.rs index ea07be30..6a031f1f 100644 --- a/crates/fuel-streams-storage/src/s3/s3_client.rs +++ b/crates/fuel-streams-storage/src/s3/s3_client.rs @@ -48,18 +48,12 @@ impl S3Client { pub async fn new(opts: &S3ClientOpts) -> Result { // Load AWS configuration let mut aws_config = aws_config::from_env(); + aws_config = aws_config.endpoint_url(opts.endpoint_url()); + let region_provider = + RegionProviderChain::first_try(Region::new(opts.region())); + let region = region_provider.region().await.unwrap(); - if let Some(endpoint_url) = opts.endpoint_url() { - aws_config = aws_config.endpoint_url(endpoint_url); - } - - if let Some(region) = opts.region() { - let region_provider = - RegionProviderChain::first_try(Region::new(region)); - let region = region_provider.region().await.unwrap(); - - aws_config = aws_config.region(region); - } + aws_config = aws_config.region(region); let s3_config = aws_sdk_s3::config::Builder::from(&aws_config.load().await) @@ -135,13 +129,12 @@ impl S3Client { #[cfg(any(test, feature = "test-helpers"))] pub async fn new_for_testing() -> Self { - use fuel_networks::FuelNetwork; - dotenvy::dotenv().expect(".env file not found"); - let s3_client = Self::new( - &S3ClientOpts::new(FuelNetwork::Local).with_random_namespace(), - ) + let s3_client = Self::new(&S3ClientOpts::new( + crate::S3Env::Local, + crate::S3Role::Admin, + )) .await .expect( "S3Client creation failed. Check AWS Env vars and Localstack setup", diff --git a/crates/fuel-streams-storage/src/s3/s3_client_opts.rs b/crates/fuel-streams-storage/src/s3/s3_client_opts.rs index a0d377a8..468efa30 100644 --- a/crates/fuel-streams-storage/src/s3/s3_client_opts.rs +++ b/crates/fuel-streams-storage/src/s3/s3_client_opts.rs @@ -1,49 +1,94 @@ -use fuel_networks::{FuelNetwork, FuelNetworkUserRole}; +use std::str::FromStr; + +#[derive(Debug, Clone, Default)] +pub enum S3Role { + Admin, + #[default] + Public, +} + +#[derive(Debug, Clone, Default)] +pub enum S3Env { + #[default] + Local, + Testnet, + Mainnet, +} + +impl FromStr for S3Env { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "local" => Ok(S3Env::Local), + "testnet" => Ok(S3Env::Testnet), + "mainnet" => Ok(S3Env::Mainnet), + _ => Err(format!("unknown S3 type: {}", s)), + } + } +} -// Introduced for consistency. -// TODO: make it more ergonomic by probably using FuelNetwork in S3Client directly #[derive(Debug, Clone, Default)] pub struct S3ClientOpts { - pub fuel_network: FuelNetwork, - pub role: FuelNetworkUserRole, + pub s3_env: S3Env, + pub role: S3Role, pub namespace: Option, } impl S3ClientOpts { - pub fn new(fuel_network: FuelNetwork) -> Self { + pub fn new(s3_env: S3Env, role: S3Role) -> Self { + Self { + s3_env, + role, + namespace: None, + } + } + + pub fn from_env(role: Option) -> Self { + let s3_env = std::env::var("NETWORK") + .map(|s| S3Env::from_str(&s).unwrap_or_default()) + .unwrap_or_default(); + Self { - fuel_network, - role: FuelNetworkUserRole::default(), + s3_env, + role: role.unwrap_or_default(), namespace: None, } } pub fn admin_opts() -> Self { - Self::new(FuelNetwork::load_from_env()) - .with_role(FuelNetworkUserRole::Admin) + Self::from_env(Some(S3Role::Admin)) } - pub fn with_role(self, role: FuelNetworkUserRole) -> Self { - Self { role, ..self } + pub fn public_opts() -> Self { + Self::from_env(Some(S3Role::Public)) } - pub fn endpoint_url(&self) -> Option { + pub fn endpoint_url(&self) -> String { match self.role { - FuelNetworkUserRole::Admin => dotenvy::var("AWS_ENDPOINT_URL").ok(), - FuelNetworkUserRole::Default => Some(self.fuel_network.to_s3_url()), + S3Role::Admin => dotenvy::var("AWS_ENDPOINT_URL") + .expect("AWS_ENDPOINT_URL must be set for admin role"), + S3Role::Public => { + match self.s3_env { + S3Env::Local => "http://localhost:4566".to_string(), + S3Env::Testnet | S3Env::Mainnet => { + let bucket = self.bucket(); + let region = self.region(); + format!("https://{bucket}.s3-website-{region}.amazonaws.com") + } + } + } } } - pub fn region(&self) -> Option { - match self.role { - FuelNetworkUserRole::Admin => dotenvy::var("AWS_S3_REGION").ok(), - FuelNetworkUserRole::Default => { - Some(self.fuel_network.to_s3_region()) - } + pub fn region(&self) -> String { + match &self.role { + S3Role::Admin => dotenvy::var("AWS_REGION") + .expect("AWS_REGION must be set for admin role"), + S3Role::Public => "us-east-1".to_string(), } } - // TODO: Consider revamping and reusing NATs' Namespace here #[cfg(any(test, feature = "test-helpers"))] pub fn with_random_namespace(mut self) -> Self { let random_namespace = { @@ -56,14 +101,20 @@ impl S3ClientOpts { } pub fn bucket(&self) -> String { - match self.role { - FuelNetworkUserRole::Admin => dotenvy::var("AWS_S3_BUCKET_NAME") - .expect("AWS_S3_BUCKET_NAME must be set for admin role"), - FuelNetworkUserRole::Default => format!( - "{}-{}", - self.fuel_network.to_s3_bucket(), - self.namespace.to_owned().unwrap_or_default() - ), + if matches!(self.role, S3Role::Admin) { + return dotenvy::var("AWS_S3_BUCKET_NAME") + .expect("AWS_S3_BUCKET_NAME must be set for admin role"); } + + let base_bucket = match self.s3_env { + S3Env::Local => "fuel-streams-local", + S3Env::Testnet => "fuel-streams-testnet", + S3Env::Mainnet => "fuel-streams", + }; + + self.namespace + .as_ref() + .map(|ns| format!("{base_bucket}-{ns}")) + .unwrap_or(base_bucket.to_string()) } } diff --git a/crates/fuel-streams-ws/Cargo.toml b/crates/fuel-streams-ws/Cargo.toml index 82ee00f8..96f36779 100644 --- a/crates/fuel-streams-ws/Cargo.toml +++ b/crates/fuel-streams-ws/Cargo.toml @@ -29,6 +29,7 @@ dotenvy = { workspace = true } elasticsearch = "8.15.0-alpha.1" fuel-streams = { workspace = true, features = ["test-helpers"] } fuel-streams-core = { workspace = true, features = ["test-helpers"] } +fuel-streams-nats = { workspace = true, features = ["test-helpers"] } fuel-streams-storage = { workspace = true, features = ["test-helpers"] } futures = { workspace = true } futures-util = { workspace = true } diff --git a/crates/fuel-streams-ws/src/server/ws/models.rs b/crates/fuel-streams-ws/src/server/ws/models.rs index 3033e5f8..0dfcec38 100644 --- a/crates/fuel-streams-ws/src/server/ws/models.rs +++ b/crates/fuel-streams-ws/src/server/ws/models.rs @@ -1,4 +1,4 @@ -use fuel_streams_storage::DeliverPolicy as NatsDeliverPolicy; +use fuel_streams_nats::DeliverPolicy as NatsDeliverPolicy; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)] diff --git a/crates/fuel-streams-ws/src/server/ws/socket.rs b/crates/fuel-streams-ws/src/server/ws/socket.rs index a705b2cf..aa4b8055 100644 --- a/crates/fuel-streams-ws/src/server/ws/socket.rs +++ b/crates/fuel-streams-ws/src/server/ws/socket.rs @@ -15,7 +15,7 @@ use fuel_streams::{ Streamable, }; use fuel_streams_core::SubscriptionConfig; -use fuel_streams_storage::DeliverPolicy; +use fuel_streams_nats::DeliverPolicy; use futures::StreamExt; use uuid::Uuid; diff --git a/crates/fuel-streams/src/client/client_impl.rs b/crates/fuel-streams/src/client/client_impl.rs index d6657369..b2d9deb1 100644 --- a/crates/fuel-streams/src/client/client_impl.rs +++ b/crates/fuel-streams/src/client/client_impl.rs @@ -42,7 +42,18 @@ impl Client { .await .map_err(ClientError::NatsConnectionFailed)?; - let s3_client_opts = S3ClientOpts::new(network); + let s3_client_opts = match network { + FuelNetwork::Local => { + S3ClientOpts::new(S3Env::Local, S3Role::Admin) + } + FuelNetwork::Testnet => { + S3ClientOpts::new(S3Env::Testnet, S3Role::Public) + } + FuelNetwork::Mainnet => { + S3ClientOpts::new(S3Env::Mainnet, S3Role::Public) + } + }; + let s3_client = S3Client::new(&s3_client_opts) .await .map_err(ClientError::S3ConnectionFailed)?; @@ -68,11 +79,11 @@ impl Client { /// ```no_run /// use fuel_streams::client::{Client, FuelNetwork}; /// use fuel_streams_core::nats::NatsClientOpts; - /// use fuel_streams_core::s3::S3ClientOpts; + /// use fuel_streams_core::s3::{S3ClientOpts, S3Env, S3Role}; /// /// # async fn example() -> Result<(), fuel_streams::Error> { - /// let nats_opts = NatsClientOpts::new(FuelNetwork::Local); - /// let s3_opts = S3ClientOpts::new(FuelNetwork::Local); + /// let nats_opts = NatsClientOpts::public_opts().with_url("nats://localhost:4222"); + /// let s3_opts = S3ClientOpts::new(S3Env::Local, S3Role::Admin); /// /// let client = Client::with_opts(&nats_opts, &s3_opts).await?; /// # Ok(()) diff --git a/tests/Cargo.toml b/tests/Cargo.toml index b1d78fe8..747eb520 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -22,11 +22,7 @@ name = "special_integration_tests" path = "src/main.rs" [dependencies] -anyhow = { workspace = true } -async-trait = { workspace = true } fuel-core = { workspace = true, features = ["test-helpers"] } -fuel-core-importer = { workspace = true, features = ["test-helpers"] } -fuel-core-types = { workspace = true, features = ["test-helpers"] } fuel-streams = { workspace = true, features = ["test-helpers"] } fuel-streams-core = { workspace = true, features = ["test-helpers"] } futures = { workspace = true } diff --git a/tests/tests/client.rs b/tests/tests/client.rs index d4204200..29ffcb5d 100644 --- a/tests/tests/client.rs +++ b/tests/tests/client.rs @@ -231,7 +231,8 @@ async fn public_and_admin_user_can_access_streams_after_created( .with_url(network.to_nats_url()) .with_rdn_namespace() .with_timeout(1); - let s3_public_opts = Arc::new(S3ClientOpts::new(FuelNetwork::Local)); + let s3_public_opts = + Arc::new(S3ClientOpts::new(S3Env::Local, S3Role::Public)); let public_tasks: Vec>> = (0..100) .map(|_| { let opts: NatsClientOpts = public_opts.clone(); From 43b28ff3df464b9fcef1e5356431a80da17be127 Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 03:32:44 -0300 Subject: [PATCH 07/31] fix(repo): general fixes --- Cargo.lock | 2 +- Makefile | 57 ++- cluster/docker/docker-compose.yml | 80 ++++- cluster/docker/init-localstack.sh | 5 +- cluster/docker/nats-config/accounts.conf | 15 + cluster/docker/nats-config/client.conf | 18 + cluster/docker/nats-config/core.conf | 13 + cluster/docker/nats-config/publisher.conf | 18 + cluster/docker/nats.conf | 46 --- .../src/stream/fuel_streams.rs | 93 +++-- .../src/stream/stream_impl.rs | 2 +- crates/fuel-streams-executors/src/lib.rs | 7 +- crates/fuel-streams-ws/Cargo.toml | 1 - crates/fuel-streams-ws/src/cli.rs | 2 +- crates/fuel-streams-ws/src/main.rs | 2 +- crates/fuel-streams-ws/src/server/context.rs | 11 +- crates/fuel-streams-ws/src/server/state.rs | 2 +- .../src/server/ws/fuel_streams.rs | 198 ----------- crates/fuel-streams-ws/src/server/ws/mod.rs | 1 - .../fuel-streams-ws/src/server/ws/socket.rs | 335 +++++++++--------- crates/sv-consumer/Cargo.toml | 1 + crates/sv-consumer/src/main.rs | 9 +- scripts/run_publisher.sh | 8 +- scripts/run_streamer.sh | 83 +++-- scripts/set_env.sh | 4 +- 25 files changed, 486 insertions(+), 527 deletions(-) create mode 100644 cluster/docker/nats-config/accounts.conf create mode 100644 cluster/docker/nats-config/client.conf create mode 100644 cluster/docker/nats-config/core.conf create mode 100644 cluster/docker/nats-config/publisher.conf delete mode 100644 cluster/docker/nats.conf delete mode 100644 crates/fuel-streams-ws/src/server/ws/fuel_streams.rs diff --git a/Cargo.lock b/Cargo.lock index 139e30dd..3fc33980 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4241,7 +4241,6 @@ dependencies = [ "actix-ws", "anyhow", "async-nats", - "async-trait", "bytestring", "chrono", "clap 4.5.23", @@ -9176,6 +9175,7 @@ dependencies = [ "anyhow", "async-nats", "clap 4.5.23", + "dotenvy", "fuel-core", "fuel-streams-core", "fuel-streams-executors", diff --git a/Makefile b/Makefile index e9465743..eef9f35c 100644 --- a/Makefile +++ b/Makefile @@ -230,6 +230,10 @@ run-publisher-testnet-dev: run-publisher-testnet-profiling: $(MAKE) run-publisher NETWORK=testnet MODE=profiling +# ------------------------------------------------------------ +# Consumer Run Commands +# ------------------------------------------------------------ + run-consumer: NATS_CORE_URL="localhost:4222" run-consumer: NATS_PUBLISHER_URL="localhost:4223" run-consumer: @@ -241,45 +245,66 @@ run-consumer: # Streamer Run Commands # ------------------------------------------------------------ +run-streamer: NETWORK="testnet" +run-streamer: MODE="dev" +run-streamer: API_PORT="9003" +run-streamer: NATS_URL="nats://localhost:4222" +run-streamer: S3_ENABLED="true" +run-streamer: JWT_SECRET="secret" +run-streamer: USE_METRICS="false" run-streamer: check-network @./scripts/run_streamer.sh \ --mode $(MODE) \ - $(if $(CONFIG_PATH),--config-path $(CONFIG_PATH),) \ - $(if $(extra_args),--extra-args "$(extra_args)",) + --api-port $(API_PORT) \ + --nats-url $(NATS_URL) \ + --s3-enabled $(S3_ENABLED) \ + --jwt-secret $(JWT_SECRET) \ + $(if $(USE_METRICS),--use-metrics,) \ + $(if $(extra_args),$(extra_args),) run-streamer-mainnet-dev: - $(MAKE) run-streamer NETWORK=mainnet MODE=dev CONFIG_PATH=crates/fuel-streams-ws/config.toml + $(MAKE) run-streamer NETWORK=mainnet MODE=dev run-streamer-mainnet-profiling: - $(MAKE) run-streamer NETWORK=mainnet MODE=profiling CONFIG_PATH=crates/fuel-streams-ws/config.toml + $(MAKE) run-streamer NETWORK=mainnet MODE=profiling run-streamer-testnet-dev: - $(MAKE) run-streamer NETWORK=testnet MODE=dev CONFIG_PATH=crates/fuel-streams-ws/config.toml + $(MAKE) run-streamer NETWORK=testnet MODE=dev run-streamer-testnet-profiling: - $(MAKE) run-streamer NETWORK=testnet MODE=profiling CONFIG_PATH=crates/fuel-streams-ws/config.toml + $(MAKE) run-streamer NETWORK=testnet MODE=profiling # ------------------------------------------------------------ # Docker Compose # ------------------------------------------------------------ +# Define service profiles +DOCKER_SERVICES := nats localstack docker + +run-docker-compose: PROFILE="all" run-docker-compose: @./scripts/set_env.sh - @docker compose -f cluster/docker/docker-compose.yml --env-file .env $(COMMAND) + @docker compose -f cluster/docker/docker-compose.yml --profile $(PROFILE) --env-file .env $(COMMAND) + +# Common docker-compose commands +define make-docker-commands +start-$(1): + $(MAKE) run-docker-compose PROFILE="$(if $(filter docker,$(1)),all,$(1))" COMMAND="up -d" -start-nats: - $(MAKE) run-docker-compose COMMAND="up -d" +stop-$(1): + $(MAKE) run-docker-compose PROFILE="$(if $(filter docker,$(1)),all,$(1))" COMMAND="down" -stop-nats: - $(MAKE) run-docker-compose COMMAND="down" +restart-$(1): + $(MAKE) run-docker-compose PROFILE="$(if $(filter docker,$(1)),all,$(1))" COMMAND="restart" -restart-nats: - $(MAKE) run-docker-compose COMMAND="restart" +clean-$(1): + $(MAKE) run-docker-compose PROFILE="$(if $(filter docker,$(1)),all,$(1))" COMMAND="down -v --remove-orphans" -clean-nats: - $(MAKE) run-docker-compose COMMAND="down -v --rmi all --remove-orphans" +reset-$(1): clean-$(1) start-$(1) +endef -reset-nats: clean-nats start-nats +# Generate targets for each service +$(foreach service,$(DOCKER_SERVICES),$(eval $(call make-docker-commands,$(service)))) # ------------------------------------------------------------ # Local cluster (Minikube) diff --git a/cluster/docker/docker-compose.yml b/cluster/docker/docker-compose.yml index 1966f3c3..34f9c55e 100644 --- a/cluster/docker/docker-compose.yml +++ b/cluster/docker/docker-compose.yml @@ -1,38 +1,88 @@ services: - nats: + nats-core: + profiles: + - all + - nats image: nats:latest - container_name: nats + container_name: nats-core + restart: always + ports: + - 4111:4222 + volumes: + - ./nats-config/core.conf:/etc/nats/nats.conf + - ./nats-config/accounts.conf:/etc/nats/accounts.conf + command: + - --name=fuel-streams-nats-core + - --js + - --config=/etc/nats/nats.conf + - -D + env_file: + - ./../../.env + + nats-client: + profiles: + - all + - nats + image: nats:latest + container_name: nats-client + restart: always + ports: + - 4333:4222 + volumes: + - ./nats-config/client.conf:/etc/nats/nats.conf + - ./nats-config/accounts.conf:/etc/nats/accounts.conf + command: + - --name=fuel-streams-nats-client + - --js + - --config=/etc/nats/nats.conf + - -D + env_file: + - ./../../.env + depends_on: + - nats-core + + nats-publisher: + profiles: + - all + - nats + image: nats:latest + container_name: nats-publisher restart: always ports: - 4222:4222 - - 8222:8222 - - 8443:8443 volumes: - - ./nats.conf:/etc/nats/nats.conf + - ./nats-config/publisher.conf:/etc/nats/nats.conf + - ./nats-config/accounts.conf:/etc/nats/accounts.conf command: - - -m - - "8222" - - --name=fuel-streams-publisher-server + - --name=fuel-streams-nats-publisher - --js - --config=/etc/nats/nats.conf - -D env_file: - ./../../.env + depends_on: + - nats-core + localstack: + profiles: + - all + - localstack image: localstack/localstack:latest container_name: localstack restart: always ports: - - "4566:4566" # LocalStack main gateway port - - "4572:4572" # S3 service port (optional) + - "4566:4566" # LocalStack main gateway port + - "4572:4572" # S3 service port (optional) environment: - - SERVICES=s3 # Enable just S3 service + - SERVICES=s3 # Enable just S3 service - DEBUG=1 - - AWS_ACCESS_KEY_ID=test - - AWS_SECRET_ACCESS_KEY=test - - DEFAULT_REGION=us-east-1 - - DEFAULT_BUCKETS=fuel-streams-local + - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} + - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} + - DEFAULT_REGION=${AWS_REGION} + - DEFAULT_BUCKETS=${AWS_S3_BUCKET_NAME} volumes: - ./localstack-data:/var/lib/localstack - /var/run/docker.sock:/var/run/docker.sock - ./init-localstack.sh:/etc/localstack/init/ready.d/init-localstack.sh + env_file: + - ./../../.env diff --git a/cluster/docker/init-localstack.sh b/cluster/docker/init-localstack.sh index 9ad8d0d7..befa0901 100755 --- a/cluster/docker/init-localstack.sh +++ b/cluster/docker/init-localstack.sh @@ -3,5 +3,6 @@ set -e echo "Creating S3 bucket in LocalStack..." -awslocal s3 mb s3://fuel-streams-test -echo "Bucket created: fuel-streams-test" +BUCKET_NAME=${AWS_S3_BUCKET_NAME:-fuel-streams-test} +awslocal s3 mb "s3://${BUCKET_NAME}" +echo "Bucket created: ${BUCKET_NAME}" diff --git a/cluster/docker/nats-config/accounts.conf b/cluster/docker/nats-config/accounts.conf new file mode 100644 index 00000000..59a035c8 --- /dev/null +++ b/cluster/docker/nats-config/accounts.conf @@ -0,0 +1,15 @@ +accounts { + SYS: { + users: [{user: $NATS_SYSTEM_USER, password: $NATS_SYSTEM_PASS}] + }, + ADMIN: { + users: [{user: $NATS_ADMIN_USER, password: $NATS_ADMIN_PASS}] + jetstream: enabled + }, + PUBLIC: { + users: [{user: $NATS_PUBLIC_USER, password: $NATS_PUBLIC_PASS}] + jetstream: enabled + } +} + +system_account: SYS diff --git a/cluster/docker/nats-config/client.conf b/cluster/docker/nats-config/client.conf new file mode 100644 index 00000000..08d9e2b3 --- /dev/null +++ b/cluster/docker/nats-config/client.conf @@ -0,0 +1,18 @@ +port: 4222 +server_name: client-server + +jetstream { + store_dir: "./data/store_client" + domain: CLIENT +} + +leafnodes { + remotes: [ + { + urls: ["nats://admin:admin@nats-core:7422"] + account: "ADMIN" + } + ] +} + +include ./accounts.conf diff --git a/cluster/docker/nats-config/core.conf b/cluster/docker/nats-config/core.conf new file mode 100644 index 00000000..2e8f11f4 --- /dev/null +++ b/cluster/docker/nats-config/core.conf @@ -0,0 +1,13 @@ +port: 4222 +server_name: core-server + +jetstream { + store_dir: "./data/core" + domain: CORE +} + +leafnodes { + port: 7422 +} + +include ./accounts.conf diff --git a/cluster/docker/nats-config/publisher.conf b/cluster/docker/nats-config/publisher.conf new file mode 100644 index 00000000..52de2113 --- /dev/null +++ b/cluster/docker/nats-config/publisher.conf @@ -0,0 +1,18 @@ +port: 4222 +server_name: leaf-server + +jetstream { + store_dir: "./data/store_leaf" + domain: LEAF +} + +leafnodes { + remotes: [ + { + urls: ["nats://admin:admin@nats-core:7422"] + account: "ADMIN" + } + ] +} + +include ./accounts.conf diff --git a/cluster/docker/nats.conf b/cluster/docker/nats.conf deleted file mode 100644 index cf5af290..00000000 --- a/cluster/docker/nats.conf +++ /dev/null @@ -1,46 +0,0 @@ -# Core settings -port = 4222 -http_port = 8222 - -# Jetstream settings -jetstream { - max_file_store = 536870912000 # 500GB - max_memory_store = 7516192768 # ~7.1GB -} - -# Max payload setting -max_payload = 8388608 # 8MB - -# Authorization settings -authorization { - timeout = 5 - ADMIN = { - publish = ">" - subscribe = ">" - } - default_permissions = { - subscribe = ">" - publish = { - deny = [ - "*.blocks.>", - "*.transactions.>", - "*.inputs.>", - "*.outputs.>", - "*.receipts.>", - "*.logs.>", - "*.utxos.>", - "$JS.API.STREAM.CREATE.>", - "$JS.API.STREAM.UPDATE.>", - "$JS.API.STREAM.DELETE.>", - "$JS.API.STREAM.PURGE.>", - "$JS.API.STREAM.RESTORE.>", - "$JS.API.STREAM.MSG.DELETE.>", - "$JS.API.CONSUMER.DURABLE.CREATE.>" - ] - } - } - users = [ - { user = admin, password = $NATS_ADMIN_PASS, permissions = $ADMIN } - { user = default_user } - ] -} diff --git a/crates/fuel-streams-core/src/stream/fuel_streams.rs b/crates/fuel-streams-core/src/stream/fuel_streams.rs index 945d2b5e..5e8781ba 100644 --- a/crates/fuel-streams-core/src/stream/fuel_streams.rs +++ b/crates/fuel-streams-core/src/stream/fuel_streams.rs @@ -1,6 +1,10 @@ use std::sync::Arc; -use async_nats::{jetstream::stream::State as StreamState, RequestErrorKind}; +use async_nats::{ + jetstream::{context::CreateStreamErrorKind, stream::State as StreamState}, + RequestErrorKind, +}; +use futures::stream::BoxStream; use crate::prelude::*; @@ -15,6 +19,41 @@ pub struct FuelStreams { pub logs: Stream, } +pub struct FuelStreamsUtils; +impl FuelStreamsUtils { + pub fn is_within_subject_names(subject_name: &str) -> bool { + let subject_names = Self::subjects_names(); + subject_names.contains(&subject_name) + } + + pub fn subjects_names() -> &'static [&'static str] { + &[ + Transaction::NAME, + Block::NAME, + Input::NAME, + Receipt::NAME, + Utxo::NAME, + Log::NAME, + ] + } + + pub fn wildcards() -> Vec<&'static str> { + let nested_wildcards = [ + Transaction::WILDCARD_LIST, + Block::WILDCARD_LIST, + Input::WILDCARD_LIST, + Receipt::WILDCARD_LIST, + Utxo::WILDCARD_LIST, + Log::WILDCARD_LIST, + ]; + nested_wildcards + .into_iter() + .flatten() + .copied() + .collect::>() + } +} + impl FuelStreams { pub async fn new( nats_client: &NatsClient, @@ -42,6 +81,31 @@ impl FuelStreams { (core_stream, publisher_stream) } + pub async fn subscribe( + &self, + sub_subject: &str, + subscription_config: Option, + ) -> Result>, StreamError> { + match sub_subject { + Transaction::NAME => { + self.transactions.subscribe_raw(subscription_config).await + } + Block::NAME => self.blocks.subscribe_raw(subscription_config).await, + Input::NAME => self.inputs.subscribe_raw(subscription_config).await, + Output::NAME => { + self.outputs.subscribe_raw(subscription_config).await + } + Receipt::NAME => { + self.receipts.subscribe_raw(subscription_config).await + } + Utxo::NAME => self.utxos.subscribe_raw(subscription_config).await, + Log::NAME => self.logs.subscribe_raw(subscription_config).await, + _ => Err(StreamError::StreamCreation( + CreateStreamErrorKind::InvalidStreamName.into(), + )), + } + } + pub fn arc(self) -> Arc { Arc::new(self) } @@ -59,33 +123,6 @@ pub trait FuelStreamsExt: Sync + Send { async fn get_last_published_block(&self) -> anyhow::Result>; - fn subjects_wildcards(&self) -> &[&'static str] { - &[ - TransactionsSubject::WILDCARD, - BlocksSubject::WILDCARD, - InputsByIdSubject::WILDCARD, - InputsCoinSubject::WILDCARD, - InputsMessageSubject::WILDCARD, - InputsContractSubject::WILDCARD, - ReceiptsLogSubject::WILDCARD, - ReceiptsBurnSubject::WILDCARD, - ReceiptsByIdSubject::WILDCARD, - ReceiptsCallSubject::WILDCARD, - ReceiptsMintSubject::WILDCARD, - ReceiptsPanicSubject::WILDCARD, - ReceiptsReturnSubject::WILDCARD, - ReceiptsRevertSubject::WILDCARD, - ReceiptsLogDataSubject::WILDCARD, - ReceiptsTransferSubject::WILDCARD, - ReceiptsMessageOutSubject::WILDCARD, - ReceiptsReturnDataSubject::WILDCARD, - ReceiptsTransferOutSubject::WILDCARD, - ReceiptsScriptResultSubject::WILDCARD, - UtxosSubject::WILDCARD, - LogsSubject::WILDCARD, - ] - } - async fn get_consumers_and_state( &self, ) -> Result, StreamState)>, RequestErrorKind>; diff --git a/crates/fuel-streams-core/src/stream/stream_impl.rs b/crates/fuel-streams-core/src/stream/stream_impl.rs index 5976dc89..d5476f21 100644 --- a/crates/fuel-streams-core/src/stream/stream_impl.rs +++ b/crates/fuel-streams-core/src/stream/stream_impl.rs @@ -190,9 +190,9 @@ impl Stream { subject_name: &str, s3_path: &str, ) -> Result { + println!("publish_s3_path_to_nats: {:?}", s3_path.to_string()); let data = s3_path.to_string().into_bytes(); let data_size = data.len(); - let result = self.store.create(subject_name, data.into()).await; match result { diff --git a/crates/fuel-streams-executors/src/lib.rs b/crates/fuel-streams-executors/src/lib.rs index 4080d4b4..d5ece798 100644 --- a/crates/fuel-streams-executors/src/lib.rs +++ b/crates/fuel-streams-executors/src/lib.rs @@ -217,8 +217,8 @@ impl Executor { let permit = Arc::clone(&semaphore); // TODO: add telemetry back again + let packet = packet.clone(); tokio::spawn({ - let packet = packet.clone(); async move { let _permit = permit.acquire().await?; match stream.publish(&packet).await { @@ -228,7 +228,10 @@ impl Executor { ); Ok(()) } - Err(e) => Err(ExecutorError::PublishFailed(e.to_string())), + Err(e) => { + tracing::error!("Failed to publish for stream: {wildcard}, error: {e}"); + Err(ExecutorError::PublishFailed(e.to_string())) + } } } }) diff --git a/crates/fuel-streams-ws/Cargo.toml b/crates/fuel-streams-ws/Cargo.toml index 96f36779..9405795f 100644 --- a/crates/fuel-streams-ws/Cargo.toml +++ b/crates/fuel-streams-ws/Cargo.toml @@ -19,7 +19,6 @@ actix-web = { workspace = true } actix-ws = "0.3.0" anyhow = { workspace = true } async-nats = { workspace = true } -async-trait = { workspace = true } bytestring = "1.4.0" chrono = { workspace = true } clap = { workspace = true } diff --git a/crates/fuel-streams-ws/src/cli.rs b/crates/fuel-streams-ws/src/cli.rs index 4aed7400..4c1d457d 100644 --- a/crates/fuel-streams-ws/src/cli.rs +++ b/crates/fuel-streams-ws/src/cli.rs @@ -18,7 +18,7 @@ pub struct Cli { long, value_name = "NATS_URL", env = "NATS_URL", - default_value = "nats://localhost:4222", + default_value = "nats://localhost:4111", help = "NATS URL" )] pub nats_url: String, diff --git a/crates/fuel-streams-ws/src/main.rs b/crates/fuel-streams-ws/src/main.rs index e629bd31..5b340d69 100644 --- a/crates/fuel-streams-ws/src/main.rs +++ b/crates/fuel-streams-ws/src/main.rs @@ -18,7 +18,7 @@ async fn main() -> anyhow::Result<()> { .init(); if let Err(err) = dotenvy::dotenv() { - tracing::error!("File .env not found: {:?}", err); + tracing::warn!("File .env not found: {:?}", err); } let config = Config::load()?; diff --git a/crates/fuel-streams-ws/src/server/context.rs b/crates/fuel-streams-ws/src/server/context.rs index b57e251a..c0af7476 100644 --- a/crates/fuel-streams-ws/src/server/context.rs +++ b/crates/fuel-streams-ws/src/server/context.rs @@ -3,11 +3,7 @@ use std::{sync::Arc, time::Duration}; use fuel_streams_core::prelude::*; use fuel_streams_storage::S3Client; -use crate::{ - config::Config, - server::ws::fuel_streams::FuelStreams, - telemetry::Telemetry, -}; +use crate::{config::Config, telemetry::Telemetry}; pub const GRACEFUL_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(90); @@ -23,8 +19,9 @@ pub struct Context { impl Context { pub async fn new(config: &Config) -> anyhow::Result { - let nats_client_opts = - NatsClientOpts::admin_opts().with_url(config.nats.url.clone()); + let nats_client_opts = NatsClientOpts::admin_opts() + .with_url(config.nats.url.clone()) + .with_domain("CORE"); let nats_client = NatsClient::connect(&nats_client_opts).await?; let s3_client_opts = S3ClientOpts::admin_opts(); let s3_client = Arc::new(S3Client::new(&s3_client_opts).await?); diff --git a/crates/fuel-streams-ws/src/server/state.rs b/crates/fuel-streams-ws/src/server/state.rs index 8a2a3609..19e379d2 100644 --- a/crates/fuel-streams-ws/src/server/state.rs +++ b/crates/fuel-streams-ws/src/server/state.rs @@ -4,11 +4,11 @@ use std::{ }; use async_nats::jetstream::stream::State; +use fuel_streams_core::prelude::FuelStreamsExt; use parking_lot::RwLock; use serde::{Deserialize, Serialize}; use super::context::Context; -use crate::server::ws::fuel_streams::FuelStreamsExt; #[derive(Debug, Serialize, Deserialize, Clone)] pub struct StreamInfo { diff --git a/crates/fuel-streams-ws/src/server/ws/fuel_streams.rs b/crates/fuel-streams-ws/src/server/ws/fuel_streams.rs deleted file mode 100644 index 526550cb..00000000 --- a/crates/fuel-streams-ws/src/server/ws/fuel_streams.rs +++ /dev/null @@ -1,198 +0,0 @@ -use std::sync::Arc; - -use async_nats::{ - jetstream::{context::CreateStreamErrorKind, stream::State as StreamState}, - RequestErrorKind, -}; -use fuel_streams::types::Log; -use fuel_streams_core::{prelude::*, SubscriptionConfig}; -use futures::stream::BoxStream; - -#[derive(Clone)] -/// Streams we currently support publishing to. -pub struct FuelStreams { - pub transactions: Stream, - pub blocks: Stream, - pub inputs: Stream, - pub outputs: Stream, - pub receipts: Stream, - pub utxos: Stream, - pub logs: Stream, -} - -impl FuelStreams { - pub async fn new( - nats_client: &NatsClient, - s3_client: &Arc, - ) -> Self { - Self { - transactions: Stream::::new(nats_client, s3_client) - .await, - blocks: Stream::::new(nats_client, s3_client).await, - inputs: Stream::::new(nats_client, s3_client).await, - outputs: Stream::::new(nats_client, s3_client).await, - receipts: Stream::::new(nats_client, s3_client).await, - utxos: Stream::::new(nats_client, s3_client).await, - logs: Stream::::new(nats_client, s3_client).await, - } - } - - pub async fn subscribe( - &self, - sub_subject: &str, - subscription_config: Option, - ) -> Result>, StreamError> { - match sub_subject { - Transaction::NAME => { - self.transactions.subscribe_raw(subscription_config).await - } - Block::NAME => self.blocks.subscribe_raw(subscription_config).await, - Input::NAME => self.inputs.subscribe_raw(subscription_config).await, - Output::NAME => { - self.outputs.subscribe_raw(subscription_config).await - } - Receipt::NAME => { - self.receipts.subscribe_raw(subscription_config).await - } - Utxo::NAME => self.utxos.subscribe_raw(subscription_config).await, - Log::NAME => self.logs.subscribe_raw(subscription_config).await, - _ => Err(StreamError::StreamCreation( - CreateStreamErrorKind::InvalidStreamName.into(), - )), - } - } -} - -#[async_trait::async_trait] -pub trait FuelStreamsExt: Sync + Send + 'static { - fn blocks(&self) -> &Stream; - fn transactions(&self) -> &Stream; - fn inputs(&self) -> &Stream; - fn outputs(&self) -> &Stream; - fn receipts(&self) -> &Stream; - fn utxos(&self) -> &Stream; - fn logs(&self) -> &Stream; - - async fn get_last_published_block(&self) -> anyhow::Result>; - - fn subjects_names() -> &'static [&'static str] { - &[ - Transaction::NAME, - Block::NAME, - Input::NAME, - Receipt::NAME, - Utxo::NAME, - Log::NAME, - ] - } - - fn is_within_subject_names(subject_name: &str) -> bool { - let subject_names = Self::subjects_names(); - subject_names.contains(&subject_name) - } - - fn subjects_wildcards(&self) -> &[&'static str] { - &[ - TransactionsSubject::WILDCARD, - BlocksSubject::WILDCARD, - InputsByIdSubject::WILDCARD, - InputsCoinSubject::WILDCARD, - InputsMessageSubject::WILDCARD, - InputsContractSubject::WILDCARD, - ReceiptsLogSubject::WILDCARD, - ReceiptsBurnSubject::WILDCARD, - ReceiptsByIdSubject::WILDCARD, - ReceiptsCallSubject::WILDCARD, - ReceiptsMintSubject::WILDCARD, - ReceiptsPanicSubject::WILDCARD, - ReceiptsReturnSubject::WILDCARD, - ReceiptsRevertSubject::WILDCARD, - ReceiptsLogDataSubject::WILDCARD, - ReceiptsTransferSubject::WILDCARD, - ReceiptsMessageOutSubject::WILDCARD, - ReceiptsReturnDataSubject::WILDCARD, - ReceiptsTransferOutSubject::WILDCARD, - ReceiptsScriptResultSubject::WILDCARD, - UtxosSubject::WILDCARD, - LogsSubject::WILDCARD, - ] - } - - fn wildcards() -> Vec<&'static str> { - let nested_wildcards = [ - Transaction::WILDCARD_LIST, - Block::WILDCARD_LIST, - Input::WILDCARD_LIST, - Receipt::WILDCARD_LIST, - Utxo::WILDCARD_LIST, - Log::WILDCARD_LIST, - ]; - nested_wildcards - .into_iter() - .flatten() - .copied() - .collect::>() - } - - async fn get_consumers_and_state( - &self, - ) -> Result, StreamState)>, RequestErrorKind>; - - #[cfg(feature = "test-helpers")] - async fn is_empty(&self) -> bool; -} - -#[async_trait::async_trait] -impl FuelStreamsExt for FuelStreams { - fn blocks(&self) -> &Stream { - &self.blocks - } - fn transactions(&self) -> &Stream { - &self.transactions - } - fn inputs(&self) -> &Stream { - &self.inputs - } - fn outputs(&self) -> &Stream { - &self.outputs - } - fn receipts(&self) -> &Stream { - &self.receipts - } - fn utxos(&self) -> &Stream { - &self.utxos - } - fn logs(&self) -> &Stream { - &self.logs - } - - async fn get_last_published_block(&self) -> anyhow::Result> { - Ok(self - .blocks - .get_last_published(BlocksSubject::WILDCARD) - .await?) - } - - async fn get_consumers_and_state( - &self, - ) -> Result, StreamState)>, RequestErrorKind> { - Ok(vec![ - self.transactions.get_consumers_and_state().await?, - self.blocks.get_consumers_and_state().await?, - self.inputs.get_consumers_and_state().await?, - self.outputs.get_consumers_and_state().await?, - self.receipts.get_consumers_and_state().await?, - self.utxos.get_consumers_and_state().await?, - self.logs.get_consumers_and_state().await?, - ]) - } - - #[cfg(feature = "test-helpers")] - async fn is_empty(&self) -> bool { - self.blocks.is_empty(BlocksSubject::WILDCARD).await - && self - .transactions - .is_empty(TransactionsSubject::WILDCARD) - .await - } -} diff --git a/crates/fuel-streams-ws/src/server/ws/mod.rs b/crates/fuel-streams-ws/src/server/ws/mod.rs index c1f05088..bb1b9404 100644 --- a/crates/fuel-streams-ws/src/server/ws/mod.rs +++ b/crates/fuel-streams-ws/src/server/ws/mod.rs @@ -1,5 +1,4 @@ pub mod errors; -pub mod fuel_streams; pub mod models; pub mod socket; pub mod state; diff --git a/crates/fuel-streams-ws/src/server/ws/socket.rs b/crates/fuel-streams-ws/src/server/ws/socket.rs index aa4b8055..c0716c76 100644 --- a/crates/fuel-streams-ws/src/server/ws/socket.rs +++ b/crates/fuel-streams-ws/src/server/ws/socket.rs @@ -14,23 +14,16 @@ use fuel_streams::{ StreamEncoder, Streamable, }; -use fuel_streams_core::SubscriptionConfig; +use fuel_streams_core::prelude::*; use fuel_streams_nats::DeliverPolicy; use futures::StreamExt; use uuid::Uuid; -use super::{ - errors::WsSubscriptionError, - fuel_streams::FuelStreams, - models::ClientMessage, -}; +use super::{errors::WsSubscriptionError, models::ClientMessage}; use crate::{ server::{ state::ServerState, - ws::{ - fuel_streams::FuelStreamsExt, - models::{ServerMessage, SubscriptionPayload}, - }, + ws::models::{ServerMessage, SubscriptionPayload}, }, telemetry::Telemetry, }; @@ -84,167 +77,25 @@ pub async fn get_ws( } Message::Text(string) => { tracing::info!("Received text, {string}"); + let bytes = Bytes::from(string.as_bytes().to_vec()); + let _ = handle_binary_message( + bytes, + user_id, + session, + Arc::clone(&telemetry), + Arc::clone(&streams), + ) + .await; } Message::Binary(bytes) => { - tracing::info!("Received binary {:?}", bytes); - let client_message = match parse_client_message(bytes) { - Ok(msg) => msg, - Err(e) => { - close_socket_with_error( - e, user_id, session, None, telemetry, - ) - .await; - return; - } - }; - - // handle the client message - match client_message { - ClientMessage::Subscribe(payload) => { - tracing::info!( - "Received subscribe message: {:?}", - payload - ); - let subject_wildcard = payload.wildcard; - let deliver_policy = payload.deliver_policy; - - // verify the subject name - let sub_subject = - match verify_and_extract_subject_name( - &subject_wildcard, - ) { - Ok(res) => res, - Err(e) => { - close_socket_with_error( - e, - user_id, - session, - Some(subject_wildcard.clone()), - telemetry, - ) - .await; - return; - } - }; - - // start the streamer async - let mut stream_session = session.clone(); - - // reply to socket with subscription - send_message_to_socket( - &mut session, - ServerMessage::Subscribed( - SubscriptionPayload { - wildcard: subject_wildcard.clone(), - deliver_policy, - }, - ), - ) - .await; - - // receive streaming in a background thread - let streams = streams.clone(); - let telemetry = telemetry.clone(); - actix_web::rt::spawn(async move { - // update metrics - telemetry.update_user_subscription_metrics( - user_id, - &subject_wildcard, - ); - - // subscribe to the stream - let config = SubscriptionConfig { - deliver_policy: DeliverPolicy::All, - filter_subjects: vec![ - subject_wildcard.clone() - ], - }; - let mut sub = match streams - .subscribe(&sub_subject, Some(config)) - .await - { - Ok(sub) => sub, - Err(e) => { - close_socket_with_error( - WsSubscriptionError::Stream(e), - user_id, - session, - Some(subject_wildcard.clone()), - telemetry, - ) - .await; - return; - } - }; - - // consume and forward to the ws - while let Some(s3_serialized_payload) = - sub.next().await - { - // decode and serialize back to ws payload - let serialized_ws_payload = match decode( - &subject_wildcard, - s3_serialized_payload, - ) - .await - { - Ok(res) => res, - Err(e) => { - telemetry.update_error_metrics( - &subject_wildcard, - &e.to_string(), - ); - tracing::error!("Error serializing received stream message: {:?}", e); - continue; - } - }; - - // send the payload over the stream - let _ = stream_session - .binary(serialized_ws_payload) - .await; - } - }); - } - ClientMessage::Unsubscribe(payload) => { - tracing::info!( - "Received unsubscribe message: {:?}", - payload - ); - let subject_wildcard = payload.wildcard; - - let deliver_policy = payload.deliver_policy; - - if let Err(e) = verify_and_extract_subject_name( - &subject_wildcard, - ) { - close_socket_with_error( - e, - user_id, - session, - Some(subject_wildcard.clone()), - telemetry, - ) - .await; - return; - } - - // TODO: implement session management for the same user_id - - // send a message to the client to confirm unsubscribing - send_message_to_socket( - &mut session, - ServerMessage::Unsubscribed( - SubscriptionPayload { - wildcard: subject_wildcard, - deliver_policy, - }, - ), - ) - .await; - return; - } - } + let _ = handle_binary_message( + bytes, + user_id, + session, + Arc::clone(&telemetry), + Arc::clone(&streams), + ) + .await; } Message::Close(reason) => { tracing::info!( @@ -286,6 +137,150 @@ pub async fn get_ws( Ok(response) } +async fn handle_binary_message( + msg: Bytes, + user_id: uuid::Uuid, + mut session: Session, + telemetry: Arc, + streams: Arc, +) -> Result<(), WsSubscriptionError> { + tracing::info!("Received binary {:?}", msg); + let client_message = match parse_client_message(msg) { + Ok(msg) => msg, + Err(e) => { + close_socket_with_error(e, user_id, session, None, telemetry).await; + return Ok(()); + } + }; + + tracing::info!("Message parsed: {:?}", client_message); + // handle the client message + match client_message { + ClientMessage::Subscribe(payload) => { + tracing::info!("Received subscribe message: {:?}", payload); + let subject_wildcard = payload.wildcard; + let deliver_policy = payload.deliver_policy; + + // verify the subject name + let sub_subject = + match verify_and_extract_subject_name(&subject_wildcard) { + Ok(res) => res, + Err(e) => { + close_socket_with_error( + e, + user_id, + session, + Some(subject_wildcard.clone()), + telemetry, + ) + .await; + return Ok(()); + } + }; + + // start the streamer async + let mut stream_session = session.clone(); + + // reply to socket with subscription + send_message_to_socket( + &mut session, + ServerMessage::Subscribed(SubscriptionPayload { + wildcard: subject_wildcard.clone(), + deliver_policy, + }), + ) + .await; + + // receive streaming in a background thread + let streams = streams.clone(); + let telemetry = telemetry.clone(); + actix_web::rt::spawn(async move { + // update metrics + telemetry.update_user_subscription_metrics( + user_id, + &subject_wildcard, + ); + + // subscribe to the stream + let config = SubscriptionConfig { + deliver_policy: DeliverPolicy::All, + filter_subjects: vec![subject_wildcard.clone()], + }; + let mut sub = + match streams.subscribe(&sub_subject, Some(config)).await { + Ok(sub) => sub, + Err(e) => { + close_socket_with_error( + WsSubscriptionError::Stream(e), + user_id, + session, + Some(subject_wildcard.clone()), + telemetry, + ) + .await; + return; + } + }; + + // consume and forward to the ws + while let Some(s3_serialized_payload) = sub.next().await { + // decode and serialize back to ws payload + let serialized_ws_payload = match decode( + &subject_wildcard, + s3_serialized_payload, + ) + .await + { + Ok(res) => res, + Err(e) => { + telemetry.update_error_metrics( + &subject_wildcard, + &e.to_string(), + ); + tracing::error!("Error serializing received stream message: {:?}", e); + continue; + } + }; + + // send the payload over the stream + let _ = stream_session.binary(serialized_ws_payload).await; + } + }); + Ok(()) + } + ClientMessage::Unsubscribe(payload) => { + tracing::info!("Received unsubscribe message: {:?}", payload); + let subject_wildcard = payload.wildcard; + + let deliver_policy = payload.deliver_policy; + + if let Err(e) = verify_and_extract_subject_name(&subject_wildcard) { + close_socket_with_error( + e, + user_id, + session, + Some(subject_wildcard.clone()), + telemetry, + ) + .await; + return Ok(()); + } + + // TODO: implement session management for the same user_id + // send a message to the client to confirm unsubscribing + send_message_to_socket( + &mut session, + ServerMessage::Unsubscribed(SubscriptionPayload { + wildcard: subject_wildcard, + deliver_policy, + }), + ) + .await; + return Ok(()); + } + } +} + fn parse_client_message( msg: Bytes, ) -> Result { @@ -313,7 +308,7 @@ pub fn verify_and_extract_subject_name( )); } let subject_name = subject_parts.next().unwrap_or_default(); - if !FuelStreams::is_within_subject_names(subject_name) { + if !FuelStreamsUtils::is_within_subject_names(subject_name) { return Err(WsSubscriptionError::UnknownSubjectName( subject_wildcard.to_string(), )); diff --git a/crates/sv-consumer/Cargo.toml b/crates/sv-consumer/Cargo.toml index ed27f473..e52f84a9 100644 --- a/crates/sv-consumer/Cargo.toml +++ b/crates/sv-consumer/Cargo.toml @@ -19,6 +19,7 @@ path = "src/main.rs" anyhow = { workspace = true } async-nats = { workspace = true } clap = { workspace = true } +dotenvy = { workspace = true } fuel-core = { workspace = true, default-features = false, features = ["p2p", "relayer", "rocksdb"] } fuel-streams-core = { workspace = true, features = ["test-helpers"] } fuel-streams-executors = { workspace = true, features = ["test-helpers"] } diff --git a/crates/sv-consumer/src/main.rs b/crates/sv-consumer/src/main.rs index 97bc9764..cbc9d78d 100644 --- a/crates/sv-consumer/src/main.rs +++ b/crates/sv-consumer/src/main.rs @@ -51,7 +51,9 @@ pub enum ConsumerError { async fn main() -> anyhow::Result<()> { // Initialize tracing subscriber tracing_subscriber::fmt() - .with_env_filter("sv_consumer=trace,fuel_streams_executors=trace") + .with_env_filter( + "sv_consumer=trace,fuel_streams_executors=trace,fuel_streams_core=trace,fuel-streams-nats=trace,fuel-streams-storage=trace", + ) .with_timer(time::LocalTime::rfc_3339()) .with_target(false) .with_thread_ids(false) @@ -60,6 +62,10 @@ async fn main() -> anyhow::Result<()> { .with_level(true) .init(); + if let Err(err) = dotenvy::dotenv() { + tracing::warn!("File .env not found: {:?}", err); + } + let cli = Cli::parse(); let shutdown = Arc::new(ShutdownController::new()); shutdown.clone().spawn_signal_handler(); @@ -129,6 +135,7 @@ async fn process_messages( let (_, publisher_stream) = FuelStreams::setup_all(&core_client, &publisher_client, &s3_client) .await; + let fuel_streams: Arc = publisher_stream.arc(); while !token.is_cancelled() { let messages = consumer.fetch().max_messages(100).messages().await?; diff --git a/scripts/run_publisher.sh b/scripts/run_publisher.sh index b9e0a8ad..2cdbcd03 100755 --- a/scripts/run_publisher.sh +++ b/scripts/run_publisher.sh @@ -109,10 +109,6 @@ COMMON_ARGS=( "--peering-port" "30333" "--db-path" "./cluster/docker/db-${NETWORK}" "--snapshot" "./cluster/chain-config/${NETWORK}" - "--nats-url" "nats://localhost:4222" - "--port" "${PORT}" - "--telemetry-port" "${TELEMETRY_PORT}" - "--peering-port" "30333" "--utxo-validation" "--poa-instant" "false" "--enable-p2p" @@ -121,11 +117,13 @@ COMMON_ARGS=( "--relayer-da-deploy-height=${RELAYER_DA_DEPLOY_HEIGHT}" "--relayer-log-page-size=${RELAYER_LOG_PAGE_SIZE}" "--sync-block-stream-buffer-size" "50" - "--nats-url" "nats://localhost:4222" "--max-database-cache-size" "17179869184" "--state-rewind-duration" "136y" "--request-timeout" "60" "--graphql-max-complexity" "1000000000" + # Application specific + "--nats-url" "nats://localhost:4222" + # "--telemetry-port" "${TELEMETRY_PORT}" ) # Execute based on mode diff --git a/scripts/run_streamer.sh b/scripts/run_streamer.sh index 656ae57a..3eba6121 100755 --- a/scripts/run_streamer.sh +++ b/scripts/run_streamer.sh @@ -9,16 +9,18 @@ set -e usage() { echo "Usage: $0 [options]" echo "Options:" - echo " --mode : Specify the run mode (dev|profiling)" - echo " --config-path : Specify the toml config path" - echo " Default: config.toml" - echo " --extra-args : Optional additional arguments to append (in quotes)" + echo " --mode : Specify the run mode (dev|profiling)" + echo " --api-port : Port number for the API server (default: 9003)" + echo " --nats-url : NATS URL (default: nats://localhost:4222)" + echo " --s3-enabled : Enable S3 integration (default: true)" + echo " --jwt-secret : Secret key for JWT authentication (default: secret)" + echo " --use-metrics : Enable metrics (flag)" + echo " --extra-args : Optional additional arguments to append (in quotes)" echo "" echo "Examples:" - echo " $0 # Runs with all defaults" - echo " $0 --config-path # Runs with default config.toml" - echo " $0 --mode dev # Runs with dev mode" - echo " $0 --config-path ../config.toml --mode dev # Custom config toml path and mode" + echo " $0 # Runs with all defaults" + echo " $0 --mode dev --api-port 8080 # Custom port" + echo " $0 --mode dev --use-metrics # Enable metrics" exit 1 } @@ -28,10 +30,26 @@ while [[ "$#" -gt 0 ]]; do MODE="$2" shift 2 ;; - --config-path) - CONFIG_PATH="$2" + --api-port) + API_PORT="$2" shift 2 ;; + --nats-url) + NATS_URL="$2" + shift 2 + ;; + --s3-enabled) + S3_ENABLED="$2" + shift 2 + ;; + --jwt-secret) + JWT_SECRET="$2" + shift 2 + ;; + --use-metrics) + USE_METRICS="true" + shift + ;; --extra-args) EXTRA_ARGS="$2" shift 2 @@ -46,6 +64,14 @@ while [[ "$#" -gt 0 ]]; do esac done +# Load environment variables with defaults +API_PORT=${API_PORT:-9003} +NATS_URL=${NATS_URL:-nats://localhost:4222} +S3_ENABLED=${S3_ENABLED:-true} +JWT_SECRET=${JWT_SECRET:-secret} +USE_METRICS=${USE_METRICS:-false} +MODE=${MODE:-dev} + # ------------------------------ # Load Environment # ------------------------------ @@ -58,35 +84,36 @@ echo -e "==========================================" # Runtime Configuration echo "Runtime Settings:" -echo "→ Mode: $MODE" -if [ -n "$CONFIG_PATH" ]; then - echo "→ Config path: $CONFIG_PATH" -fi +echo "→ Mode: ${MODE:-dev}" +echo "→ API Port: ${API_PORT:-9003}" +echo "→ NATS URL: ${NATS_URL:-nats://localhost:4222}" +echo "→ S3 Enabled: ${S3_ENABLED:-true}" +echo "→ JWT Secret: ${JWT_SECRET:-secret}" +echo "→ Use Metrics: ${USE_METRICS:-false}" if [ -n "$EXTRA_ARGS" ]; then echo "→ Extra Arguments: $EXTRA_ARGS" fi -# Environment Variables -echo -e "\nEnvironment Variables:" -echo " → Use Metrics: ${USE_METRICS}" -echo " → Use Elastic Logging: $USE_ELASTIC_LOGGING" -echo " → AWS S3 Enabled: $AWS_S3_ENABLED" -echo " → AWS Access Key Id: $AWS_ACCESS_KEY_ID" -echo " → AWS Secret Access Key: $AWS_SECRET_ACCESS_KEY" -echo " → AWS Region: $AWS_REGION" -echo " → AWS Bucket: $AWS_S3_BUCKET_NAME" -echo " → AWS Endpoint: $AWS_ENDPOINT_URL" -echo " → Jwt Auth Secret: $JWT_AUTH_SECRET" -echo " → Nats Url: $NATS_URL" echo -e "==========================================\n" # Define common arguments COMMON_ARGS=( - "--config-path" "${CONFIG_PATH}" + "--api-port" "${API_PORT:-9003}" + "--nats-url" "${NATS_URL:-nats://localhost:4222}" + "--jwt-secret" "${JWT_SECRET:-secret}" ) +# Add boolean flags if enabled +if [ "${S3_ENABLED:-true}" = "true" ]; then + COMMON_ARGS+=("--s3-enabled") +fi + +if [ "${USE_METRICS:-false}" = "true" ]; then + COMMON_ARGS+=("--use-metrics") +fi + # Execute based on mode -if [ "$MODE" == "dev" ]; then +if [ "${MODE:-dev}" == "dev" ]; then cargo run -p fuel-streams-ws -- "${COMMON_ARGS[@]}" ${EXTRA_ARGS} else cargo build --profile profiling --package fuel-streams-ws diff --git a/scripts/set_env.sh b/scripts/set_env.sh index 207873f9..393115e0 100755 --- a/scripts/set_env.sh +++ b/scripts/set_env.sh @@ -64,7 +64,7 @@ export AWS_REGION="$(echo "$AWS_REGION")" export AWS_ENDPOINT_URL="$(echo "$AWS_ENDPOINT_URL")" export AWS_S3_BUCKET_NAME="$(echo "$AWS_S3_BUCKET_NAME")" export JWT_AUTH_SECRET="$(echo "$JWT_AUTH_SECRET")" -export NATS_URL="$(echo "$NATS_URL")" +# export NATS_URL="$(echo "$NATS_URL")" # Append network-specific variables to .env file { @@ -88,5 +88,5 @@ export NATS_URL="$(echo "$NATS_URL")" echo "AWS_ENDPOINT_URL=$AWS_ENDPOINT_URL" echo "AWS_S3_BUCKET_NAME=$AWS_S3_BUCKET_NAME" echo "JWT_AUTH_SECRET=$JWT_AUTH_SECRET" - echo "NATS_URL=$NATS_URL" + # echo "NATS_URL=$NATS_URL" } >> .env From 7d8d3e5b554de314f1a665280e683346e917311a Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 03:44:41 -0300 Subject: [PATCH 08/31] build(repo): adjust chart for new architecture --- cluster/charts/fuel-streams/Chart.yaml | 2 +- .../templates/consumer/statefulset.yaml | 10 +- .../templates/publisher/statefulset.yaml | 6 +- .../templates/webserver/deployment.yaml | 13 ++ cluster/charts/fuel-streams/values.yaml | 130 ++++++++---------- 5 files changed, 85 insertions(+), 76 deletions(-) diff --git a/cluster/charts/fuel-streams/Chart.yaml b/cluster/charts/fuel-streams/Chart.yaml index 61e1bdf8..4575e0d1 100755 --- a/cluster/charts/fuel-streams/Chart.yaml +++ b/cluster/charts/fuel-streams/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 appVersion: "1.0" description: A Helm chart for Kubernetes name: fuel-streams -version: 0.5.7 +version: 0.6.0 dependencies: - name: nats version: 1.2.8 diff --git a/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml b/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml index 5f15bb02..c9da855b 100644 --- a/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml +++ b/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml @@ -56,6 +56,12 @@ spec: {{- include "k8s.container-security-context" (dict "context" . "service" "consumer") | nindent 10 }} env: + - name: NATS_CORE_URL + value: "{{ include "fuel-streams.fullname" . }}-nats-core:4222" + - name: NATS_PUBLISHER_URL + value: "{{ include "fuel-streams.fullname" . }}-nats-publisher:4222" + - name: PORT + value: "{{ $consumer.port }}" {{- range $key, $value := $consumer.env }} - name: {{ $key }} value: {{ $value | quote }} @@ -66,10 +72,10 @@ spec: envFrom: - configMapRef: - name: {{ include "fuel-streams.fullname" $ }}-consumer + name: {{ include "fuel-streams.fullname" $ }} optional: true - secretRef: - name: {{ include "fuel-streams.fullname" $ }}-consumer + name: {{ include "fuel-streams.fullname" $ }} optional: true {{- with $consumer.envFrom }} {{- toYaml . | nindent 12 }} diff --git a/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml b/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml index 85de7960..bacc9950 100644 --- a/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml +++ b/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml @@ -152,6 +152,8 @@ spec: value: "/var/fuel-streams/tmp" - name: DB_PATH value: {{ $publisher.storage.mountPath | default "/mnt/db" | quote }} + - name: NATS_URL + value: "{{ include "fuel-streams.fullname" . }}-nats-publisher:4222" {{- range $key, $value := $publisher.env }} - name: {{ $key }} value: {{ $value | quote }} @@ -162,10 +164,10 @@ spec: envFrom: - configMapRef: - name: {{ include "fuel-streams.fullname" $ }}-publisher + name: {{ include "fuel-streams.fullname" $ }} optional: true - secretRef: - name: {{ include "fuel-streams.fullname" $ }}-publisher + name: {{ include "fuel-streams.fullname" $ }} optional: true {{- with $publisher.envFrom }} {{- toYaml . | nindent 12 }} diff --git a/cluster/charts/fuel-streams/templates/webserver/deployment.yaml b/cluster/charts/fuel-streams/templates/webserver/deployment.yaml index 778fb028..5b5cb052 100644 --- a/cluster/charts/fuel-streams/templates/webserver/deployment.yaml +++ b/cluster/charts/fuel-streams/templates/webserver/deployment.yaml @@ -53,6 +53,17 @@ spec: {{- include "k8s.probes" (dict "context" . "service" "webserver") | nindent 10 }} {{- include "k8s.container-security-context" (dict "context" . "service" "webserver") | nindent 10 }} + envFrom: + - configMapRef: + name: {{ include "fuel-streams.fullname" $ }} + optional: true + - secretRef: + name: {{ include "fuel-streams.fullname" $ }} + optional: true + {{- with $webserver.envFrom }} + {{- toYaml . | nindent 12 }} + {{- end }} + env: {{- range $key, $value := $webserver.env }} - name: {{ $key }} @@ -77,6 +88,8 @@ spec: value: "{{ include "fuel-streams.fullname" . }}-nats-publisher:4222" - name: NETWORK value: "{{ .Values.app.network }}" + - name: PORT + value: "{{ $webserver.port }}" {{- include "k8s.hpa" (dict "context" . "service" (dict "name" "webserver" "autoscaling" $webserver.autoscaling)) }} {{- end }} \ No newline at end of file diff --git a/cluster/charts/fuel-streams/values.yaml b/cluster/charts/fuel-streams/values.yaml index 01ceaaef..bc47696c 100755 --- a/cluster/charts/fuel-streams/values.yaml +++ b/cluster/charts/fuel-streams/values.yaml @@ -167,7 +167,6 @@ publisher: env: PORT: 8080 PUBLISHER_MAX_THREADS: "32" - NATS_URL: "fuel-streams-nats-publisher:4222" # ------------------------------------------------------------------------------------------------- # Consumer configuration @@ -186,11 +185,6 @@ consumer: - --nats-publisher-url - $(NATS_PUBLISHER_URL) - env: - PORT: 8080 - NATS_CORE_URL: "fuel-streams-nats-core:4222" - NATS_PUBLISHER_URL: "fuel-streams-nats-publisher:4222" - config: replicaCount: 3 labels: {} @@ -225,6 +219,65 @@ consumer: podValue: 4 periodSeconds: 15 +# ------------------------------------------------------------------------------------------------- +# WebServer configuration +# ------------------------------------------------------------------------------------------------- + +webserver: + enabled: false + port: 9003 + + service: + enabled: true + dns: "stream-dev.fuel.network" + + image: + repository: fuel-streams-webserver + pullPolicy: Never + tag: "latest" + + app: + network: testnet + streamerMaxWorkers: 10 + useElasticLogging: false + useMetrics: true + awsS3Enabled: true + jwtAuthSecret: "secret" + + config: + replicaCount: 1 + labels: {} + annotations: {} + podAnnotations: {} + nodeSelector: {} + tolerations: [] + affinity: {} + imagePullSecrets: [] + ports: [] + livenessProbe: {} + readinessProbe: {} + startupProbe: {} + securityContext: {} + containerSecurityContext: {} + resources: {} + + autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + targetMemoryUtilizationPercentage: 80 + behavior: + scaleDown: + stabilizationWindowSeconds: 300 + percentValue: 100 + periodSeconds: 15 + scaleUp: + stabilizationWindowSeconds: 0 + percentValue: 100 + podValue: 4 + periodSeconds: 15 + # ------------------------------------------------------------------------------------------------- # NATS Common Configuration # ------------------------------------------------------------------------------------------------- @@ -515,68 +568,3 @@ nats-client: merge: $tplYaml: | {{- include "nats-accounts" . | nindent 8 }} - -# ------------------------------------------------------------------------------------------------- -# WebServer configuration -# ------------------------------------------------------------------------------------------------- - -webserver: - enabled: false - port: 9003 - - service: - enabled: true - dns: "stream-dev.fuel.network" - - image: - repository: fuel-streams-webserver - pullPolicy: Never - tag: "latest" - - app: - network: testnet - streamerMaxWorkers: 10 - useElasticLogging: false - useMetrics: true - awsS3Enabled: true - jwtAuthSecret: "secret" - - config: - replicaCount: 1 - labels: {} - annotations: {} - podAnnotations: {} - nodeSelector: {} - tolerations: [] - affinity: {} - imagePullSecrets: [] - ports: [] - livenessProbe: {} - readinessProbe: {} - startupProbe: {} - securityContext: {} - containerSecurityContext: {} - resources: - requests: - cpu: 100m - memory: 64Mi - limits: - cpu: 500m - memory: 256Mi - - autoscaling: - enabled: false - minReplicas: 1 - maxReplicas: 5 - targetCPUUtilizationPercentage: 80 - targetMemoryUtilizationPercentage: 80 - behavior: - scaleDown: - stabilizationWindowSeconds: 300 - percentValue: 100 - periodSeconds: 15 - scaleUp: - stabilizationWindowSeconds: 0 - percentValue: 100 - podValue: 4 - periodSeconds: 15 From 2d12e1e2e8899a94a15846ae85b46cf4a6650d89 Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 04:12:49 -0300 Subject: [PATCH 09/31] build(repo): adjust chart --- cluster/charts/fuel-streams/Chart.yaml | 2 +- .../templates/consumer/statefulset.yaml | 20 ++++++++++-- .../templates/publisher/statefulset.yaml | 20 +++++++++--- .../templates/webserver/deployment.yaml | 32 +++++++++---------- cluster/charts/fuel-streams/values.yaml | 21 ++---------- 5 files changed, 54 insertions(+), 41 deletions(-) diff --git a/cluster/charts/fuel-streams/Chart.yaml b/cluster/charts/fuel-streams/Chart.yaml index 4575e0d1..c5682e80 100755 --- a/cluster/charts/fuel-streams/Chart.yaml +++ b/cluster/charts/fuel-streams/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 appVersion: "1.0" description: A Helm chart for Kubernetes name: fuel-streams -version: 0.6.0 +version: 0.6.1 dependencies: - name: nats version: 1.2.8 diff --git a/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml b/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml index c9da855b..dc357993 100644 --- a/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml +++ b/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml @@ -41,6 +41,10 @@ spec: image: "{{ $consumer.image.repository }}:{{ $consumer.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ $consumer.image.pullPolicy }} args: + - --nats-core-url + - $(NATS_CORE_URL) + - --nats-publisher-url + - $(NATS_PUBLISHER_URL)v {{- toYaml $consumer.image.args | nindent 12 }} ports: @@ -72,10 +76,22 @@ spec: envFrom: - configMapRef: - name: {{ include "fuel-streams.fullname" $ }} + name: {{ include "fuel-streams.fullname" $ }}-config optional: true - secretRef: - name: {{ include "fuel-streams.fullname" $ }} + name: {{ include "fuel-streams.fullname" $ }}-keys + optional: true + - configMapRef: + name: {{ include "fuel-streams.fullname" $ }}-consumer-config + optional: true + - secretRef: + name: {{ include "fuel-streams.fullname" $ }}-consumer-keys + optional: true + - configMapRef: + name: {{ include "fuel-streams.fullname" $ }}-aws-config + optional: true + - secretRef: + name: {{ include "fuel-streams.fullname" $ }}-nats-keys optional: true {{- with $consumer.envFrom }} {{- toYaml . | nindent 12 }} diff --git a/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml b/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml index bacc9950..7d8ec8cc 100644 --- a/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml +++ b/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml @@ -132,8 +132,8 @@ spec: - "--relayer-da-deploy-height" - "5827607" {{- end }} - {{- if $publisher.image.extraArgs }} - {{- toYaml $publisher.image.extraArgs | nindent 12 }} + {{- if $publisher.image.args }} + {{- toYaml $publisher.image.args | nindent 12 }} {{- end }} ports: - name: http @@ -164,10 +164,22 @@ spec: envFrom: - configMapRef: - name: {{ include "fuel-streams.fullname" $ }} + name: {{ include "fuel-streams.fullname" $ }}-config optional: true - secretRef: - name: {{ include "fuel-streams.fullname" $ }} + name: {{ include "fuel-streams.fullname" $ }}-keys + optional: true + - configMapRef: + name: {{ include "fuel-streams.fullname" $ }}-publisher-config + optional: true + - secretRef: + name: {{ include "fuel-streams.fullname" $ }}-publisher-keys + optional: true + - configMapRef: + name: {{ include "fuel-streams.fullname" $ }}-aws-config + optional: true + - secretRef: + name: {{ include "fuel-streams.fullname" $ }}-nats-keys optional: true {{- with $publisher.envFrom }} {{- toYaml . | nindent 12 }} diff --git a/cluster/charts/fuel-streams/templates/webserver/deployment.yaml b/cluster/charts/fuel-streams/templates/webserver/deployment.yaml index 5b5cb052..f5479535 100644 --- a/cluster/charts/fuel-streams/templates/webserver/deployment.yaml +++ b/cluster/charts/fuel-streams/templates/webserver/deployment.yaml @@ -55,10 +55,22 @@ spec: envFrom: - configMapRef: - name: {{ include "fuel-streams.fullname" $ }} + name: {{ include "fuel-streams.fullname" $ }}-config optional: true - secretRef: - name: {{ include "fuel-streams.fullname" $ }} + name: {{ include "fuel-streams.fullname" $ }}-keys + optional: true + - configMapRef: + name: {{ include "fuel-streams.fullname" $ }}-webserver-config + optional: true + - secretRef: + name: {{ include "fuel-streams.fullname" $ }}-webserver-keys + optional: true + - configMapRef: + name: {{ include "fuel-streams.fullname" $ }}-aws-config + optional: true + - secretRef: + name: {{ include "fuel-streams.fullname" $ }}-nats-keys optional: true {{- with $webserver.envFrom }} {{- toYaml . | nindent 12 }} @@ -72,22 +84,10 @@ spec: {{- with $webserver.extraEnv }} {{- toYaml . | nindent 12 }} {{- end }} - - name: STREAMER_MAX_WORKERS - value: "{{ .Values.app.streamerMaxWorkers }}" - - name: STREAMER_API_PORT - value: "{{ .Values.webserver.port }}" - - name: JWT_AUTH_SECRET - value: "{{ .Values.app.jwtAuthSecret }}" - - name: USE_ELASTIC_LOGGING - value: "{{ .Values.app.useElasticLogging }}" - - name: USE_METRICS - value: "{{ .Values.app.useMetrics }}" - - name: AWS_S3_ENABLED - value: "true" + - name: NETWORK + value: "{{ $webserver.network }}" - name: NATS_URL value: "{{ include "fuel-streams.fullname" . }}-nats-publisher:4222" - - name: NETWORK - value: "{{ .Values.app.network }}" - name: PORT value: "{{ $webserver.port }}" diff --git a/cluster/charts/fuel-streams/values.yaml b/cluster/charts/fuel-streams/values.yaml index bc47696c..642b0455 100755 --- a/cluster/charts/fuel-streams/values.yaml +++ b/cluster/charts/fuel-streams/values.yaml @@ -88,7 +88,7 @@ publisher: repository: ghcr.io/fuellabs/sv-emitter pullPolicy: Always tag: "latest" - extraArgs: [] + args: [] service: type: ClusterIP @@ -164,10 +164,6 @@ publisher: # - secretRef: # name: additional-secrets - env: - PORT: 8080 - PUBLISHER_MAX_THREADS: "32" - # ------------------------------------------------------------------------------------------------- # Consumer configuration # ------------------------------------------------------------------------------------------------- @@ -179,11 +175,7 @@ consumer: repository: ghcr.io/fuellabs/sv-consumer pullPolicy: Always tag: "latest" - args: - - --nats-core-url - - $(NATS_CORE_URL) - - --nats-publisher-url - - $(NATS_PUBLISHER_URL) + args: [] config: replicaCount: 3 @@ -226,6 +218,7 @@ consumer: webserver: enabled: false port: 9003 + network: mainnet service: enabled: true @@ -236,14 +229,6 @@ webserver: pullPolicy: Never tag: "latest" - app: - network: testnet - streamerMaxWorkers: 10 - useElasticLogging: false - useMetrics: true - awsS3Enabled: true - jwtAuthSecret: "secret" - config: replicaCount: 1 labels: {} From 525a6b2f94240bd015a438546bcc99b9c49d0533 Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 04:21:59 -0300 Subject: [PATCH 10/31] build(repo): fix chart --- cluster/charts/fuel-streams/Chart.yaml | 2 +- cluster/charts/fuel-streams/templates/webserver/service.yaml | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cluster/charts/fuel-streams/Chart.yaml b/cluster/charts/fuel-streams/Chart.yaml index c5682e80..cf011233 100755 --- a/cluster/charts/fuel-streams/Chart.yaml +++ b/cluster/charts/fuel-streams/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 appVersion: "1.0" description: A Helm chart for Kubernetes name: fuel-streams -version: 0.6.1 +version: 0.6.2 dependencies: - name: nats version: 1.2.8 diff --git a/cluster/charts/fuel-streams/templates/webserver/service.yaml b/cluster/charts/fuel-streams/templates/webserver/service.yaml index 9afa9374..2f571d7f 100644 --- a/cluster/charts/fuel-streams/templates/webserver/service.yaml +++ b/cluster/charts/fuel-streams/templates/webserver/service.yaml @@ -1,3 +1,4 @@ +{{- $webserver := .Values.webserver }} {{- $service := $webserver.service }} {{- if and $webserver.enabled $service.enabled }} --- @@ -25,8 +26,8 @@ spec: externalTrafficPolicy: Local ports: - name: webserver - port: {{ $webserver.port }} - targetPort: {{ $webserver.port }} + port: {{ $service.port }} + targetPort: {{ $service.port }} protocol: TCP appProtocol: tcp selector: From 6ec29ec666652edb13b1d9dda5cf70f8950dc21c Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 04:25:12 -0300 Subject: [PATCH 11/31] build(repo): fix chart --- cluster/charts/fuel-streams/Chart.yaml | 2 +- .../charts/fuel-streams/templates/webserver/deployment.yaml | 3 --- cluster/charts/fuel-streams/templates/webserver/service.yaml | 4 ++-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/cluster/charts/fuel-streams/Chart.yaml b/cluster/charts/fuel-streams/Chart.yaml index cf011233..993cb964 100755 --- a/cluster/charts/fuel-streams/Chart.yaml +++ b/cluster/charts/fuel-streams/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 appVersion: "1.0" description: A Helm chart for Kubernetes name: fuel-streams -version: 0.6.2 +version: 0.6.3 dependencies: - name: nats version: 1.2.8 diff --git a/cluster/charts/fuel-streams/templates/webserver/deployment.yaml b/cluster/charts/fuel-streams/templates/webserver/deployment.yaml index f5479535..ecdb061f 100644 --- a/cluster/charts/fuel-streams/templates/webserver/deployment.yaml +++ b/cluster/charts/fuel-streams/templates/webserver/deployment.yaml @@ -45,9 +45,6 @@ spec: - name: webserver containerPort: {{ $webserver.port }} protocol: TCP - {{- if $webserver.ports }} - {{- toYaml $webserver.ports | nindent 12 }} - {{- end }} {{- include "set-field-and-value" (dict "context" $webserver "field" "resources" "path" "config.resources") | nindent 10 }} {{- include "k8s.probes" (dict "context" . "service" "webserver") | nindent 10 }} diff --git a/cluster/charts/fuel-streams/templates/webserver/service.yaml b/cluster/charts/fuel-streams/templates/webserver/service.yaml index 2f571d7f..cc567369 100644 --- a/cluster/charts/fuel-streams/templates/webserver/service.yaml +++ b/cluster/charts/fuel-streams/templates/webserver/service.yaml @@ -26,8 +26,8 @@ spec: externalTrafficPolicy: Local ports: - name: webserver - port: {{ $service.port }} - targetPort: {{ $service.port }} + port: {{ $webserver.port }} + targetPort: {{ $webserver.port }} protocol: TCP appProtocol: tcp selector: From a392ce689150f24f2ccb7e00fb74dc5404a2af04 Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 04:35:23 -0300 Subject: [PATCH 12/31] build(repo): fix chart --- cluster/charts/fuel-streams/Chart.yaml | 2 +- cluster/charts/fuel-streams/templates/_blocks.tpl | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cluster/charts/fuel-streams/Chart.yaml b/cluster/charts/fuel-streams/Chart.yaml index 993cb964..0c0a1da2 100755 --- a/cluster/charts/fuel-streams/Chart.yaml +++ b/cluster/charts/fuel-streams/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 appVersion: "1.0" description: A Helm chart for Kubernetes name: fuel-streams -version: 0.6.3 +version: 0.6.4 dependencies: - name: nats version: 1.2.8 diff --git a/cluster/charts/fuel-streams/templates/_blocks.tpl b/cluster/charts/fuel-streams/templates/_blocks.tpl index 55e3bf07..c9055c12 100644 --- a/cluster/charts/fuel-streams/templates/_blocks.tpl +++ b/cluster/charts/fuel-streams/templates/_blocks.tpl @@ -68,13 +68,13 @@ data: accounts { SYS: { users: [ - {user: $NATS_SYS_USER, password: $NATS_SYS_PASSWORD} + {user: $NATS_SYS_USER, password: $NATS_SYS_PASS} ] } ADMIN: { jetstream: enabled users: [ - {user: $NATS_ADMIN_USER, password: $NATS_ADMIN_PASSWORD} + {user: $NATS_ADMIN_USER, password: $NATS_ADMIN_PASS} ] } PUBLIC: { @@ -82,7 +82,7 @@ data: users: [ { user: $NATS_PUBLIC_USER - password: $NATS_PUBLIC_PASSWORD + password: $NATS_PUBLIC_PASS permissions: { subscribe: ">" publish: { From 3705e7418403b2c7abbbca54b28cf6a57c2d81c5 Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 04:45:09 -0300 Subject: [PATCH 13/31] build(repo): fix chart --- cluster/charts/fuel-streams/Chart.yaml | 2 +- .../templates/consumer/statefulset.yaml | 10 +--------- .../templates/publisher/statefulset.yaml | 2 -- .../templates/webserver/deployment.yaml | 2 -- cluster/charts/fuel-streams/values.yaml | 16 +++++++++++++++- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/cluster/charts/fuel-streams/Chart.yaml b/cluster/charts/fuel-streams/Chart.yaml index 0c0a1da2..a72800fa 100755 --- a/cluster/charts/fuel-streams/Chart.yaml +++ b/cluster/charts/fuel-streams/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 appVersion: "1.0" description: A Helm chart for Kubernetes name: fuel-streams -version: 0.6.4 +version: 0.6.5 dependencies: - name: nats version: 1.2.8 diff --git a/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml b/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml index dc357993..77972f95 100644 --- a/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml +++ b/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml @@ -41,11 +41,7 @@ spec: image: "{{ $consumer.image.repository }}:{{ $consumer.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ $consumer.image.pullPolicy }} args: - - --nats-core-url - - $(NATS_CORE_URL) - - --nats-publisher-url - - $(NATS_PUBLISHER_URL)v - {{- toYaml $consumer.image.args | nindent 12 }} + {{- toYaml $consumer.args | nindent 12 }} ports: - name: consumer @@ -60,10 +56,6 @@ spec: {{- include "k8s.container-security-context" (dict "context" . "service" "consumer") | nindent 10 }} env: - - name: NATS_CORE_URL - value: "{{ include "fuel-streams.fullname" . }}-nats-core:4222" - - name: NATS_PUBLISHER_URL - value: "{{ include "fuel-streams.fullname" . }}-nats-publisher:4222" - name: PORT value: "{{ $consumer.port }}" {{- range $key, $value := $consumer.env }} diff --git a/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml b/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml index 7d8ec8cc..b93a0646 100644 --- a/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml +++ b/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml @@ -152,8 +152,6 @@ spec: value: "/var/fuel-streams/tmp" - name: DB_PATH value: {{ $publisher.storage.mountPath | default "/mnt/db" | quote }} - - name: NATS_URL - value: "{{ include "fuel-streams.fullname" . }}-nats-publisher:4222" {{- range $key, $value := $publisher.env }} - name: {{ $key }} value: {{ $value | quote }} diff --git a/cluster/charts/fuel-streams/templates/webserver/deployment.yaml b/cluster/charts/fuel-streams/templates/webserver/deployment.yaml index ecdb061f..8f8a9119 100644 --- a/cluster/charts/fuel-streams/templates/webserver/deployment.yaml +++ b/cluster/charts/fuel-streams/templates/webserver/deployment.yaml @@ -83,8 +83,6 @@ spec: {{- end }} - name: NETWORK value: "{{ $webserver.network }}" - - name: NATS_URL - value: "{{ include "fuel-streams.fullname" . }}-nats-publisher:4222" - name: PORT value: "{{ $webserver.port }}" diff --git a/cluster/charts/fuel-streams/values.yaml b/cluster/charts/fuel-streams/values.yaml index 642b0455..8980c60a 100755 --- a/cluster/charts/fuel-streams/values.yaml +++ b/cluster/charts/fuel-streams/values.yaml @@ -90,6 +90,9 @@ publisher: tag: "latest" args: [] + env: + NATS_URL: "fuel-streams-nats-core:4222" + service: type: ClusterIP port: 8080 @@ -175,7 +178,15 @@ consumer: repository: ghcr.io/fuellabs/sv-consumer pullPolicy: Always tag: "latest" - args: [] + args: + - --nats-core-url + - $(NATS_CORE_URL) + - --nats-publisher-url + - $(NATS_PUBLISHER_URL) + + env: + NATS_CORE_URL: "fuel-streams-nats-core:4222" + NATS_PUBLISHER_URL: "fuel-streams-nats-publisher:4222" config: replicaCount: 3 @@ -229,6 +240,9 @@ webserver: pullPolicy: Never tag: "latest" + env: + NATS_URL: "fuel-streams-nats-publisher:4222" + config: replicaCount: 1 labels: {} From a2c4bc4b71ecdb2d3aa1c3d24e6fd25534623b2e Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 04:59:00 -0300 Subject: [PATCH 14/31] build(repo): docker image --- .github/workflows/docker_publish.yaml | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/.github/workflows/docker_publish.yaml b/.github/workflows/docker_publish.yaml index 72f82d35..f8932722 100644 --- a/.github/workflows/docker_publish.yaml +++ b/.github/workflows/docker_publish.yaml @@ -2,17 +2,6 @@ name: Build and publish Docker image on: workflow_dispatch: - inputs: - service: - description: "Choose which service to build" - required: true - type: choice - options: - - sv-emitter - - sv-consumer - - fuel-streams-ws - - all - default: "all" push: branches: - main @@ -34,19 +23,22 @@ jobs: strategy: matrix: package: + - name: fuel-streams-ws + image: cluster/docker/fuel-streams-ws.Dockerfile - name: sv-emitter image: cluster/docker/fuel-core.Dockerfile - name: sv-consumer image: cluster/docker/sv-consumer.Dockerfile - - name: fuel-streams-ws - image: cluster/docker/fuel-streams-ws.Dockerfile steps: - uses: actions/checkout@v4 - - name: Build and push Docker for ${{ matrix.package.name }} + - name: Get short SHA + id: sha + run: echo "short_sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + + - name: Build and push Docker (${{ steps.sha.outputs.short_sha }}) uses: ./.github/actions/docker-publish - if: github.event_name != 'workflow_dispatch' || github.event.inputs.service == 'all' || github.event.inputs.service - == matrix.package.name + id: publish with: username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} From ad1eee317781fce468f3a355206ce256d795a5f1 Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 05:25:44 -0300 Subject: [PATCH 15/31] build(repo): bump chart --- cluster/charts/fuel-streams/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cluster/charts/fuel-streams/Chart.yaml b/cluster/charts/fuel-streams/Chart.yaml index a72800fa..2cd4aa78 100755 --- a/cluster/charts/fuel-streams/Chart.yaml +++ b/cluster/charts/fuel-streams/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 appVersion: "1.0" description: A Helm chart for Kubernetes name: fuel-streams -version: 0.6.5 +version: 0.6.6 dependencies: - name: nats version: 1.2.8 From ac3390c0ff205de6f550aa88bc9db3fa4db01c6d Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 12:15:47 -0300 Subject: [PATCH 16/31] build(repo): fix emitter Dockerimage --- .github/workflows/docker_publish.yaml | 6 ++---- Tiltfile | 4 ++-- ...l-core.Dockerfile => sv-emitter.Dockerfile} | 18 ++++++++---------- cluster/scripts/build_docker.sh | 4 ++-- 4 files changed, 14 insertions(+), 18 deletions(-) rename cluster/docker/{fuel-core.Dockerfile => sv-emitter.Dockerfile} (78%) diff --git a/.github/workflows/docker_publish.yaml b/.github/workflows/docker_publish.yaml index f8932722..48fadcf3 100644 --- a/.github/workflows/docker_publish.yaml +++ b/.github/workflows/docker_publish.yaml @@ -26,7 +26,7 @@ jobs: - name: fuel-streams-ws image: cluster/docker/fuel-streams-ws.Dockerfile - name: sv-emitter - image: cluster/docker/fuel-core.Dockerfile + image: cluster/docker/sv-emitter.Dockerfile - name: sv-consumer image: cluster/docker/sv-consumer.Dockerfile steps: @@ -36,7 +36,7 @@ jobs: id: sha run: echo "short_sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT - - name: Build and push Docker (${{ steps.sha.outputs.short_sha }}) + - name: Build and push Docker for ${matrix.package.name} (${{ steps.sha.outputs.short_sha }}) uses: ./.github/actions/docker-publish id: publish with: @@ -44,5 +44,3 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} image: ghcr.io/fuellabs/${{ matrix.package.name }} dockerfile: ${{ matrix.package.image }} - build-args: |- - PACKAGE_NAME=${{ matrix.package.name }} diff --git a/Tiltfile b/Tiltfile index f564d8f1..c3ddcc54 100755 --- a/Tiltfile +++ b/Tiltfile @@ -18,14 +18,14 @@ custom_build( command=[ './cluster/scripts/build_docker.sh', '--image-name', 'sv-emitter', - '--dockerfile', './cluster/docker/fuel-core.Dockerfile', + '--dockerfile', './cluster/docker/sv-emitter.Dockerfile', '--build-args', '--build-arg PACKAGE_NAME=sv-emitter' ], deps=[ './src', './Cargo.toml', './Cargo.lock', - './cluster/docker/fuel-core.Dockerfile' + './cluster/docker/sv-emitter.Dockerfile' ], live_update=[ sync('./src', '/usr/src'), diff --git a/cluster/docker/fuel-core.Dockerfile b/cluster/docker/sv-emitter.Dockerfile similarity index 78% rename from cluster/docker/fuel-core.Dockerfile rename to cluster/docker/sv-emitter.Dockerfile index 0ec3f52b..4cd045e5 100644 --- a/cluster/docker/fuel-core.Dockerfile +++ b/cluster/docker/sv-emitter.Dockerfile @@ -3,7 +3,6 @@ FROM --platform=$BUILDPLATFORM tonistiigi/xx AS xx FROM --platform=$BUILDPLATFORM rust:1.81.0 AS chef # Add package name as build argument -ARG PACKAGE_NAME ARG TARGETPLATFORM RUN cargo install cargo-chef && rustup target add wasm32-unknown-unknown @@ -42,7 +41,7 @@ RUN \ --mount=type=cache,target=/usr/local/cargo/registry/cache \ --mount=type=cache,target=/usr/local/cargo/git/db \ --mount=type=cache,target=/build/target \ - xx-cargo chef cook --release --no-default-features -p ${PACKAGE_NAME} --recipe-path recipe.json + xx-cargo chef cook --release --no-default-features -p sv-emitter --recipe-path recipe.json # Up to this point, if our dependency tree stays the same, # all layers should be cached. COPY . . @@ -52,15 +51,14 @@ RUN \ --mount=type=cache,target=/usr/local/cargo/registry/cache \ --mount=type=cache,target=/usr/local/cargo/git/db \ --mount=type=cache,target=/build/target \ - xx-cargo build --release --no-default-features -p ${PACKAGE_NAME} \ - && xx-verify ./target/$(xx-cargo --print-target-triple)/release/${PACKAGE_NAME} \ - && cp ./target/$(xx-cargo --print-target-triple)/release/${PACKAGE_NAME} /root/${PACKAGE_NAME} \ - && cp ./target/$(xx-cargo --print-target-triple)/release/${PACKAGE_NAME}.d /root/${PACKAGE_NAME}.d + xx-cargo build --release --no-default-features -p sv-emitter \ + && xx-verify ./target/$(xx-cargo --print-target-triple)/release/sv-emitter \ + && cp ./target/$(xx-cargo --print-target-triple)/release/sv-emitter /root/sv-emitter \ + && cp ./target/$(xx-cargo --print-target-triple)/release/sv-emitter.d /root/sv-emitter.d # Stage 2: Run FROM ubuntu:22.04 AS run -ARG PACKAGE_NAME ARG PORT=4000 ARG P2P_PORT=30333 ENV IP="${IP}" @@ -74,11 +72,11 @@ RUN apt-get update -y \ && apt-get clean -y \ && rm -rf /var/lib/apt/lists/* -COPY --from=builder /root/${PACKAGE_NAME} . -COPY --from=builder /root/${PACKAGE_NAME}.d . +COPY --from=builder /root/sv-emitter /usr/local/bin/ +COPY --from=builder /root/sv-emitter.d /usr/local/bin/ COPY /cluster/chain-config ./chain-config EXPOSE ${PORT} EXPOSE ${P2P_PORT} -ENTRYPOINT ["./${PACKAGE_NAME}"] +ENTRYPOINT /usr/local/bin/sv-emitter diff --git a/cluster/scripts/build_docker.sh b/cluster/scripts/build_docker.sh index a70f23f2..aa650139 100755 --- a/cluster/scripts/build_docker.sh +++ b/cluster/scripts/build_docker.sh @@ -12,7 +12,7 @@ Build a Docker image using specified parameters. Options: --image-name Name for the Docker image (default: sv-emitter) - --dockerfile Path to Dockerfile (default: cluster/docker/fuel-core.Dockerfile) + --dockerfile Path to Dockerfile (default: cluster/docker/sv-emitter.Dockerfile) --build-args Additional Docker build arguments (optional) -h, --help Show this help message @@ -34,7 +34,7 @@ fi # Default values IMAGE_NAME="sv-emitter" -DOCKERFILE="cluster/docker/fuel-core.Dockerfile" +DOCKERFILE="cluster/docker/sv-emitter.Dockerfile" BUILD_ARGS="" TAG=${TAG:-"latest"} # From environment variable with default From 82cf6790866ffa069565b68824854f8411e7765e Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 12:21:50 -0300 Subject: [PATCH 17/31] build(repo): adjust workflow dispatch for docker --- .github/workflows/docker_publish.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/docker_publish.yaml b/.github/workflows/docker_publish.yaml index 48fadcf3..42e7f98d 100644 --- a/.github/workflows/docker_publish.yaml +++ b/.github/workflows/docker_publish.yaml @@ -2,6 +2,17 @@ name: Build and publish Docker image on: workflow_dispatch: + inputs: + package: + type: string + description: "Package to build and publish" + default: "sv-emitter" + required: true + options: + - sv-emitter + - fuel-streams-ws + - sv-consumer + - all push: branches: - main @@ -37,6 +48,9 @@ jobs: run: echo "short_sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT - name: Build and push Docker for ${matrix.package.name} (${{ steps.sha.outputs.short_sha }}) + if: | + (github.event_name == 'workflow_dispatch' && (github.event.inputs.package == 'all' || github.event.inputs.package == matrix.package.name)) || + github.event_name != 'workflow_dispatch' uses: ./.github/actions/docker-publish id: publish with: From ff334ed69368a6dcab62ce91841a073de39bdd1d Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 12:22:37 -0300 Subject: [PATCH 18/31] build(repo): docker action --- .github/workflows/docker_publish.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker_publish.yaml b/.github/workflows/docker_publish.yaml index 42e7f98d..780c22ef 100644 --- a/.github/workflows/docker_publish.yaml +++ b/.github/workflows/docker_publish.yaml @@ -4,7 +4,7 @@ on: workflow_dispatch: inputs: package: - type: string + type: choice description: "Package to build and publish" default: "sv-emitter" required: true From bbc7f613b73cb6a490e244ac69dd7eb2106434dc Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 15:43:27 -0300 Subject: [PATCH 19/31] build(repo): fix publisher config --- .env.sample | 1 + .github/workflows/ci.yaml | 13 +- .github/workflows/helm_publish.yaml | 34 ++-- .gitignore | 2 +- Makefile | 16 +- Tiltfile | 115 +++++++------- .../charts/fuel-streams-publisher/.helmignore | 23 --- .../charts/fuel-streams-publisher/Chart.yaml | 21 --- .../templates/_helpers.tpl | 62 -------- .../fuel-streams-publisher/templates/hpa.yaml | 32 ---- .../templates/service.yaml | 17 -- .../templates/serviceaccount.yaml | 13 -- .../templates/statefulset.yaml | 147 ------------------ .../charts/fuel-streams-publisher/values.yaml | 124 --------------- .../fuel-streams/templates/_helpers.tpl | 2 +- .../fuel-streams/templates/common-config.yaml | 21 +++ .../templates/consumer/statefulset.yaml | 33 ++-- .../templates/nats/accounts-secret.yaml | 15 -- .../templates/publisher/statefulset.yaml | 144 ++++++++--------- .../templates/webserver/deployment.yaml | 34 ++-- .../tests/webserver/deployment_test.yaml | 2 +- cluster/charts/fuel-streams/values-local.yaml | 31 ++-- cluster/charts/fuel-streams/values.yaml | 102 ++++++------ cluster/docker/docker-compose.yml | 26 +--- cluster/docker/fuel-streams-ws.Dockerfile | 2 +- cluster/docker/sv-consumer.Dockerfile | 3 +- cluster/docker/sv-emitter.Dockerfile | 9 +- cluster/scripts/build_docker.sh | 4 +- cluster/scripts/gen_env_secret.sh | 17 +- cluster/scripts/setup_k8s.sh | 39 ----- cluster/scripts/setup_minikube.sh | 50 ++++++ crates/fuel-streams-ws/src/cli.rs | 2 +- crates/sv-consumer/src/cli.rs | 10 +- crates/sv-consumer/src/lib.rs | 2 +- scripts/run_streamer.sh | 4 +- scripts/set_env.sh | 22 +-- 36 files changed, 329 insertions(+), 865 deletions(-) delete mode 100644 cluster/charts/fuel-streams-publisher/.helmignore delete mode 100644 cluster/charts/fuel-streams-publisher/Chart.yaml delete mode 100644 cluster/charts/fuel-streams-publisher/templates/_helpers.tpl delete mode 100644 cluster/charts/fuel-streams-publisher/templates/hpa.yaml delete mode 100644 cluster/charts/fuel-streams-publisher/templates/service.yaml delete mode 100644 cluster/charts/fuel-streams-publisher/templates/serviceaccount.yaml delete mode 100644 cluster/charts/fuel-streams-publisher/templates/statefulset.yaml delete mode 100644 cluster/charts/fuel-streams-publisher/values.yaml create mode 100644 cluster/charts/fuel-streams/templates/common-config.yaml delete mode 100644 cluster/charts/fuel-streams/templates/nats/accounts-secret.yaml delete mode 100755 cluster/scripts/setup_k8s.sh diff --git a/.env.sample b/.env.sample index 928ab29f..c111ace9 100644 --- a/.env.sample +++ b/.env.sample @@ -12,6 +12,7 @@ AWS_S3_BUCKET_NAME=fuel-streams-local # NATS Configuration NATS_URL=nats://localhost:4222 +NATS_PUBLISHER_URL=nats://localhost:4333 NATS_SYSTEM_USER=sys NATS_SYSTEM_PASS=sys NATS_ADMIN_USER=admin diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8cf5f15d..d51d0d2c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -214,8 +214,13 @@ jobs: runs-on: ubuntu-latest env: NATS_URL: nats://127.0.0.1:4222 - NATS_ADMIN_PASS: secret - NATS_PUBLIC_PASS: secret + NATS_PUBLISHER_URL: nats://127.0.0.1:4333 + NATS_SYSTEM_USER: sys + NATS_SYSTEM_PASSWORD: sys + NATS_ADMIN_USER: admin + NATS_ADMIN_PASS: admin + NATS_PUBLIC_USER: default_user + NATS_PUBLIC_PASS: "" AWS_ACCESS_KEY_ID: test AWS_SECRET_ACCESS_KEY: test AWS_REGION: us-east-1 @@ -225,12 +230,12 @@ jobs: fail-fast: false matrix: package: - # - fuel-data-parser + - fuel-data-parser - fuel-streams - fuel-streams-core - fuel-streams-macros - fuel-streams-ws - + - sv-emitter steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/helm_publish.yaml b/.github/workflows/helm_publish.yaml index 59dfe12d..8dc9de93 100644 --- a/.github/workflows/helm_publish.yaml +++ b/.github/workflows/helm_publish.yaml @@ -2,16 +2,6 @@ name: Build and Publish Helm Chart on: workflow_dispatch: - inputs: - chart: - description: "Choose which chart to build" - required: true - type: choice - options: - - fuel-streams-publisher - - fuel-streams - - all - default: "all" push: branches: - main @@ -19,6 +9,10 @@ on: types: - published +env: + CHART_NAME: fuel-streams + CHART_PATH: cluster/charts/fuel-streams + permissions: contents: read packages: write @@ -30,29 +24,19 @@ concurrency: jobs: helm-release: runs-on: ubuntu-latest - strategy: - matrix: - chart: - - name: fuel-streams-publisher - path: cluster/charts/fuel-streams-publisher - - name: fuel-streams - path: cluster/charts/fuel-streams steps: - uses: actions/checkout@v4 - - name: Helm Dependencies Update run: | - cd ${{ matrix.chart.path }} && helm dependency update + cd ${{ env.CHART_PATH }} && helm dependency update - name: Get chart version id: version run: | - version=$(awk '/^version:/ {print $2}' ${{ matrix.chart.path }}/Chart.yaml) + version=$(awk '/^version:/ {print $2}' ${{ env.CHART_PATH }}/Chart.yaml) echo "version=$version" >> $GITHUB_OUTPUT - - name: "Build chart: [${{ matrix.chart.name }} v${{ steps.version.outputs.version }}]" - if: github.event_name != 'workflow_dispatch' || github.event.inputs.chart == 'all' || github.event.inputs.chart - == matrix.chart.name + - name: "Build chart: [${{ env.CHART_NAME }} v${{ steps.version.outputs.version }}]" uses: bsord/helm-push@v4.1.0 with: useOCIRegistry: true @@ -60,11 +44,11 @@ jobs: username: ${{ github.repository_owner }} access-token: ${{ secrets.GITHUB_TOKEN }} force: true - chart-folder: ${{ matrix.chart.path }} + chart-folder: ${{ env.CHART_PATH }} - name: Build Summary run: |- echo "### Helm Charts Build Summary 📊" >> $GITHUB_STEP_SUMMARY echo "| Chart | Version | Status |" >> $GITHUB_STEP_SUMMARY echo "|-------|---------|--------|" >> $GITHUB_STEP_SUMMARY - echo "| ${{ matrix.chart.name }} | ${{ steps.version.outputs.version }} | ✅ Published |" >> $GITHUB_STEP_SUMMARY + echo "| ${{ env.CHART_NAME }} | ${{ steps.version.outputs.version }} | ✅ Published |" >> $GITHUB_STEP_SUMMARY diff --git a/.gitignore b/.gitignore index 58058830..8607f4ff 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,7 @@ profile.json coverage/ docs/ **/**/charts/**.tgz -values-publisher-secrets.yaml +values-secrets.yaml values-publisher-env.yaml localstack-data .vscode diff --git a/Makefile b/Makefile index eef9f35c..035b0e05 100644 --- a/Makefile +++ b/Makefile @@ -234,11 +234,11 @@ run-publisher-testnet-profiling: # Consumer Run Commands # ------------------------------------------------------------ -run-consumer: NATS_CORE_URL="localhost:4222" -run-consumer: NATS_PUBLISHER_URL="localhost:4223" +run-consumer: NATS_URL="localhost:4222" +run-consumer: NATS_PUBLISHER_URL="localhost:4333" run-consumer: cargo run --package sv-consumer --profile dev -- \ - --nats-core-url $(NATS_CORE_URL) \ + --nats-url $(NATS_URL) \ --nats-publisher-url $(NATS_PUBLISHER_URL) # ------------------------------------------------------------ @@ -334,15 +334,10 @@ minikube-delete: @echo "Deleting minikube..." @minikube delete -k8s-setup: - @echo "Setting up k8s..." - @./cluster/scripts/setup_k8s.sh $(NAMESPACE) - helm-setup: @cd cluster/charts/fuel-streams && helm dependency update - @cd cluster/charts/fuel-streams-publisher && helm dependency update -cluster-setup: minikube-setup k8s-setup helm-setup +cluster-setup: minikube-setup helm-setup pre-cluster: @./scripts/set_env.sh @@ -355,5 +350,4 @@ cluster-up: pre-cluster cluster-down: pre-cluster CLUSTER_MODE=$(MODE) tilt --file ./Tiltfile down -cluster-reset: pre-cluster - CLUSTER_MODE=$(MODE) tilt --file ./Tiltfile reset +cluster-reset: cluster-down cluster-up diff --git a/Tiltfile b/Tiltfile index c3ddcc54..759da19e 100755 --- a/Tiltfile +++ b/Tiltfile @@ -33,53 +33,50 @@ custom_build( sync('./Cargo.lock', '/usr/src/Cargo.lock'), run('cargo build', trigger=['./src', './Cargo.toml', './Cargo.lock']) ], - skips_local_docker=True, ignore=['./target'] ) # Build sv-consumer -custom_build( - ref='sv-consumer:latest', - command=[ - './cluster/scripts/build_docker.sh', - '--image-name', 'sv-consumer', - '--dockerfile', './cluster/docker/sv-consumer.Dockerfile' - ], - deps=[ - './src', - './Cargo.toml', - './Cargo.lock', - './cluster/docker/sv-consumer.Dockerfile' - ], - live_update=[ - sync('./src', '/usr/src'), - sync('./Cargo.toml', '/usr/src/Cargo.toml'), - sync('./Cargo.lock', '/usr/src/Cargo.lock'), - run('cargo build', trigger=['./src', './Cargo.toml', './Cargo.lock']) - ], - skips_local_docker=True, - ignore=['./target'] -) +# custom_build( +# ref='sv-consumer:latest', +# command=[ +# './cluster/scripts/build_docker.sh', +# '--image-name', 'sv-consumer', +# '--dockerfile', './cluster/docker/sv-consumer.Dockerfile' +# ], +# deps=[ +# './src', +# './Cargo.toml', +# './Cargo.lock', +# './cluster/docker/sv-consumer.Dockerfile' +# ], +# live_update=[ +# sync('./src', '/usr/src'), +# sync('./Cargo.toml', '/usr/src/Cargo.toml'), +# sync('./Cargo.lock', '/usr/src/Cargo.lock'), +# run('cargo build', trigger=['./src', './Cargo.toml', './Cargo.lock']) +# ], +# ignore=['./target'] +# ) -# Build streamer ws image with proper configuration for Minikube -custom_build( - ref='fuel-streams-ws:latest', - command=['./cluster/scripts/build_streamer.sh'], - deps=[ - './src', - './Cargo.toml', - './Cargo.lock', - './docker/fuel-streams-ws.Dockerfile' - ], - live_update=[ - sync('./src', '/usr/src'), - sync('./Cargo.toml', '/usr/src/Cargo.toml'), - sync('./Cargo.lock', '/usr/src/Cargo.lock'), - run('cargo build', trigger=['./src', './Cargo.toml', './Cargo.lock']) - ], - skips_local_docker=True, - ignore=['./target'] -) +# # Build streamer ws image with proper configuration for Minikube +# custom_build( +# ref='fuel-streams-ws:latest', +# command=['./cluster/scripts/build_streamer.sh'], +# deps=[ +# './src', +# './Cargo.toml', +# './Cargo.lock', +# './docker/fuel-streams-ws.Dockerfile' +# ], +# live_update=[ +# sync('./src', '/usr/src'), +# sync('./Cargo.toml', '/usr/src/Cargo.toml'), +# sync('./Cargo.lock', '/usr/src/Cargo.lock'), +# run('cargo build', trigger=['./src', './Cargo.toml', './Cargo.lock']) +# ], +# ignore=['./target'] +# ) # Deploy the Helm chart with values from .env # Get deployment mode from environment variable, default to 'full' @@ -89,34 +86,34 @@ config_mode = os.getenv('CLUSTER_MODE', 'full') RESOURCES = { 'publisher': { 'name': 'fuel-streams-publisher', - 'ports': ['4000:4000', '8080:8080'], + 'ports': ['8080:8080'], 'labels': 'publisher', 'config_mode': ['minimal', 'full'] }, - 'consumer': { - 'name': 'fuel-streams-sv-consumer', - 'ports': ['8082:8082'], - 'labels': 'consumer', - 'config_mode': ['minimal', 'full'] - }, + # 'consumer': { + # 'name': 'fuel-streams-sv-consumer', + # 'ports': ['8081:8080'], + # 'labels': 'consumer', + # 'config_mode': ['minimal', 'full'] + # }, 'nats-core': { 'name': 'fuel-streams-nats-core', - 'ports': ['4222:4222', '6222:6222', '7422:7422'], + 'ports': ['4222:4222'], 'labels': 'nats', 'config_mode': ['minimal', 'full'] }, - 'nats-client': { - 'name': 'fuel-streams-nats-client', - 'ports': ['14222:4222', '17422:7422', '8443:8443'], + 'nats-publisher': { + 'name': 'fuel-streams-nats-publisher', + 'ports': ['4333:4222'], 'labels': 'nats', 'config_mode': ['minimal', 'full'] }, - 'nats-publisher': { - 'name': 'fuel-streams-nats-publisher', - 'ports': ['24222:4222', '27422:7422'], + 'nats-client': { + 'name': 'fuel-streams-nats-client', + 'ports': ['4444:4222'], 'labels': 'nats', 'config_mode': ['minimal', 'full'] - } + }, } k8s_yaml(helm( @@ -124,9 +121,9 @@ k8s_yaml(helm( name='fuel-streams', namespace='fuel-streams', values=[ - 'cluster/charts/fuel-streams/values-publisher-secrets.yaml', 'cluster/charts/fuel-streams/values.yaml', - 'cluster/charts/fuel-streams/values-local.yaml' + 'cluster/charts/fuel-streams/values-local.yaml', + 'cluster/charts/fuel-streams/values-secrets.yaml' ] )) diff --git a/cluster/charts/fuel-streams-publisher/.helmignore b/cluster/charts/fuel-streams-publisher/.helmignore deleted file mode 100644 index 0e8a0eb3..00000000 --- a/cluster/charts/fuel-streams-publisher/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*.orig -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ diff --git a/cluster/charts/fuel-streams-publisher/Chart.yaml b/cluster/charts/fuel-streams-publisher/Chart.yaml deleted file mode 100644 index 1628fc80..00000000 --- a/cluster/charts/fuel-streams-publisher/Chart.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: v2 -name: fuel-streams-publisher -description: A Helm chart for Kubernetes deployment of Fuel streams publisher service -# A chart can be either an 'application' or a 'library' chart. -# -# Application charts are a collection of templates that can be packaged into versioned archives -# to be deployed. -# -# Library charts provide useful utilities or functions for the chart developer. They're included as -# a dependency of application charts to inject those utilities and functions into the rendering -# pipeline. Library charts do not define any templates and therefore cannot be deployed. -type: application -# This is the chart version. This version number should be incremented each time you make changes -# to the chart and its templates, including the app version. -# Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.4.7 -# This is the version number of the application being deployed. This version number should be -# incremented each time you make changes to the application. Versions are not expected to -# follow Semantic Versioning. They should reflect the version the application is using. -# It is recommended to use it with quotes. -appVersion: 0.2.0 diff --git a/cluster/charts/fuel-streams-publisher/templates/_helpers.tpl b/cluster/charts/fuel-streams-publisher/templates/_helpers.tpl deleted file mode 100644 index 0bc5f455..00000000 --- a/cluster/charts/fuel-streams-publisher/templates/_helpers.tpl +++ /dev/null @@ -1,62 +0,0 @@ -{{/* -Expand the name of the chart. -*/}} -{{- define "fuel-streams-publisher.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "fuel-streams-publisher.fullname" -}} -{{- if .Values.fullnameOverride }} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- $name := default .Chart.Name .Values.nameOverride }} -{{- if contains $name .Release.Name }} -{{- .Release.Name | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} -{{- end }} -{{- end }} -{{- end }} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "fuel-streams-publisher.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Common labels -*/}} -{{- define "fuel-streams-publisher.labels" -}} -helm.sh/chart: {{ include "fuel-streams-publisher.chart" . }} -{{ include "fuel-streams-publisher.selectorLabels" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "fuel-streams-publisher.selectorLabels" -}} -app.kubernetes.io/name: {{ include "fuel-streams-publisher.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} - -{{/* -Create the name of the service account to use -*/}} -{{- define "fuel-streams-publisher.serviceAccountName" -}} -{{- if .Values.serviceAccount.create }} -{{- default (include "fuel-streams-publisher.fullname" .) .Values.serviceAccount.name }} -{{- else }} -{{- default "default" .Values.serviceAccount.name }} -{{- end }} -{{- end }} diff --git a/cluster/charts/fuel-streams-publisher/templates/hpa.yaml b/cluster/charts/fuel-streams-publisher/templates/hpa.yaml deleted file mode 100644 index b2759de2..00000000 --- a/cluster/charts/fuel-streams-publisher/templates/hpa.yaml +++ /dev/null @@ -1,32 +0,0 @@ -{{- if .Values.autoscaling.enabled }} -apiVersion: autoscaling/v2 -kind: HorizontalPodAutoscaler -metadata: - name: {{ include "fuel-streams-publisher.fullname" . }} - labels: - {{- include "fuel-streams-publisher.labels" . | nindent 4 }} -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: {{ include "fuel-streams-publisher.fullname" . }} - minReplicas: {{ .Values.autoscaling.minReplicas }} - maxReplicas: {{ .Values.autoscaling.maxReplicas }} - metrics: - {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} - - type: Resource - resource: - name: cpu - target: - type: Utilization - averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} - {{- end }} - {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} - - type: Resource - resource: - name: memory - target: - type: Utilization - averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} - {{- end }} -{{- end }} \ No newline at end of file diff --git a/cluster/charts/fuel-streams-publisher/templates/service.yaml b/cluster/charts/fuel-streams-publisher/templates/service.yaml deleted file mode 100644 index 49c7f6fe..00000000 --- a/cluster/charts/fuel-streams-publisher/templates/service.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: Service - -metadata: - name: {{ include "fuel-streams-publisher.fullname" . }} - labels: - {{- include "fuel-streams-publisher.labels" . | nindent 4 }} - -spec: - type: {{ .Values.service.type }} - ports: - - port: {{ .Values.service.port }} - targetPort: http - protocol: TCP - name: http - selector: - {{- include "fuel-streams-publisher.selectorLabels" . | nindent 4 }} diff --git a/cluster/charts/fuel-streams-publisher/templates/serviceaccount.yaml b/cluster/charts/fuel-streams-publisher/templates/serviceaccount.yaml deleted file mode 100644 index b3c456bb..00000000 --- a/cluster/charts/fuel-streams-publisher/templates/serviceaccount.yaml +++ /dev/null @@ -1,13 +0,0 @@ -{{- if .Values.serviceAccount.create -}} -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ include "fuel-streams-publisher.serviceAccountName" . }} - labels: - {{- include "fuel-streams-publisher.labels" . | nindent 4 }} - {{- with .Values.serviceAccount.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -automountServiceAccountToken: {{ .Values.serviceAccount.automount }} -{{- end }} diff --git a/cluster/charts/fuel-streams-publisher/templates/statefulset.yaml b/cluster/charts/fuel-streams-publisher/templates/statefulset.yaml deleted file mode 100644 index b0d6b039..00000000 --- a/cluster/charts/fuel-streams-publisher/templates/statefulset.yaml +++ /dev/null @@ -1,147 +0,0 @@ -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: {{ include "fuel-streams-publisher.fullname" . }} - labels: - {{- include "fuel-streams-publisher.labels" . | nindent 4 }} -spec: - # Define the headless service that governs this StatefulSet - serviceName: {{ include "fuel-streams-publisher.fullname" . | quote }} - # Handle replica count unless autoscaling is enabled - {{- if not .Values.autoscaling.enabled }} - replicas: {{ .Values.config.replicaCount }} - {{- end }} - selector: - matchLabels: - {{- include "fuel-streams-publisher.selectorLabels" . | nindent 6 }} - template: - metadata: - annotations: - # Prometheus scraping configuration - {{- if .Values.prometheus.enabled }} - prometheus.io/scrape: {{ .Values.prometheus.scrape | quote }} - prometheus.io/port: {{ .Values.service.port | quote }} - prometheus.io/path: {{ .Values.prometheus.path | quote }} - {{- end }} - # Add checksums to force pod restart when configs change - {{/* checksum/config: {{ include (print $.Template.BasePath "/env-configmap.yaml") . | sha256sum }} */}} - {{/* checksum/secrets: {{ include (print $.Template.BasePath "/env-secrets.yaml") . | sha256sum }} */}} - {{- with .Values.config.annotations }} - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- include "fuel-streams-publisher.labels" . | nindent 8 }} - {{- with .Values.config.labels }} - {{- toYaml . | nindent 8 }} - {{- end }} - spec: - {{- with .Values.config.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} - serviceAccountName: {{ include "fuel-streams-publisher.serviceAccountName" . }} - securityContext: - {{- toYaml .Values.config.podSecurityContext | nindent 8 }} - # Initialize persistent volumes with correct permissions - {{- if .Values.persistence.enabled }} - initContainers: - - name: {{ .Values.persistence.data.containerName }} - image: alpine:latest - imagePullPolicy: IfNotPresent - command: ["/bin/chown"] - args: ["-R", "1000:1000", "{{ .Values.persistence.data.mountPath }}"] - volumeMounts: - - name: {{ .Values.persistence.data.name }} - mountPath: {{ .Values.persistence.data.mountPath }} - - name: {{ .Values.persistence.temp.containerName }} - image: alpine:latest - imagePullPolicy: IfNotPresent - command: ["/bin/chown"] - args: ["-R", "1000:1000", "{{ .Values.persistence.temp.mountPath }}"] - volumeMounts: - - name: {{ .Values.persistence.temp.name }} - mountPath: {{ .Values.persistence.temp.mountPath }} - {{- end }} - # Main application container - containers: - - name: {{ .Chart.Name }} - securityContext: - {{- toYaml .Values.securityContext | nindent 12 }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - # Define container ports for application and metrics - ports: - - name: http - containerPort: {{ int .Values.service.port }} - protocol: TCP - # Health check probes - livenessProbe: - {{- toYaml .Values.livenessProbe | nindent 12 }} - readinessProbe: - {{- toYaml .Values.readinessProbe | nindent 12 }} - resources: - {{- toYaml .Values.config.resources | nindent 12 }} - env: - {{- range $key, $value := .Values.env }} - - name: {{ $key }} - value: {{ $value | quote }} - {{- end }} - {{- if .Values.extraEnv }} - {{- toYaml .Values.extraEnv | nindent 12 }} - {{- end }} - envFrom: - - configMapRef: - name: {{ include "fuel-streams-publisher.fullname" . }} - optional: true - - secretRef: - name: {{ include "fuel-streams-publisher.fullname" . }} - optional: true - {{- if .Values.envFrom }} - {{- toYaml .Values.envFrom | nindent 12 }} - {{- end }} - - # Mount persistent volumes if enabled - {{- if .Values.persistence.enabled }} - volumeMounts: - - name: {{ .Values.persistence.data.name }} - mountPath: {{ .Values.persistence.data.mountPath }} - readOnly: false - - name: {{ .Values.persistence.temp.name }} - mountPath: {{ .Values.persistence.temp.mountPath }} - readOnly: false - {{- end }} - # Node assignment rules - {{- with .Values.config.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.config.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.config.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} - # Persistent volume claims configuration - {{- if .Values.persistence.enabled }} - volumeClaimTemplates: - - metadata: - name: {{ .Values.persistence.data.name }} - spec: - accessModes: - - {{ .Values.persistence.data.accessMode }} - storageClassName: {{ .Values.persistence.data.storageClass }} - resources: - requests: - storage: {{ .Values.persistence.data.size }} - - metadata: - name: {{ .Values.persistence.temp.name }} - spec: - accessModes: - - {{ .Values.persistence.temp.accessMode }} - storageClassName: {{ .Values.persistence.temp.storageClass }} - resources: - requests: - storage: {{ .Values.persistence.temp.size }} - {{- end }} diff --git a/cluster/charts/fuel-streams-publisher/values.yaml b/cluster/charts/fuel-streams-publisher/values.yaml deleted file mode 100644 index 91ca6eef..00000000 --- a/cluster/charts/fuel-streams-publisher/values.yaml +++ /dev/null @@ -1,124 +0,0 @@ -# Default values for fuel-streams-publisher -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# These are custom resource definitions that can be overridden by the user -# nameOverride: "" -# fullnameOverride: "" - -# general configurations -config: - replicaCount: 1 - imagePullSecrets: [] - annotations: {} - labels: {} - nodeSelector: {} - tolerations: [] - affinity: {} - resources: {} - podSecurityContext: {} - # We usually recommend not to specify default resources and to leave this as a conscious - # choice for the user. This also increases chances charts run on environments with little - # resources, such as Minikube. If you do want to specify resources, uncomment the following - # lines, adjust them as necessary, and remove the curly braces after 'resources:'. - # resources: - # limits: - # cpu: 100m - # memory: 128Mi - # requests: - # cpu: 100m - # memory: 128Mi - -image: - repository: ghcr.io/fuellabs/fuel-streams-publisher - pullPolicy: Always - tag: "latest" - -serviceAccount: - create: true - automount: true - # annotations: {} - # The name of the service account to use. - # If not set and create is true, a name is generated using the fullname template - # name: "" - -service: - type: ClusterIP - port: 8080 - -prometheus: - enabled: true - scrape: true - path: /metrics - -securityContext: - capabilities: - drop: [ALL] - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 1000 - -livenessProbe: {} -readinessProbe: {} - -autoscaling: - enabled: false - minReplicas: 1 - maxReplicas: 3 - targetCPUUtilizationPercentage: 80 - targetMemoryUtilizationPercentage: 80 - -persistence: - enabled: true - data: - name: rocks-db-vol - containerName: update-rocks-db-vol - mountPath: /mnt/db - size: 500Gi - storageClass: gp3-generic - accessMode: ReadWriteOnce - temp: - name: tmp-vol - containerName: update-tmp-vol - mountPath: /tmp - size: 5Gi - storageClass: gp3-generic - accessMode: ReadWriteOnce - -# Additional environment variables with complex structures -# extraEnv: -# - name: RELAYER -# valueFrom: -# secretKeyRef: -# name: fuel-streams-publisher -# key: RELAYER -# - name: KEYPAIR -# valueFrom: -# secretKeyRef: -# name: fuel-streams-publisher -# key: KEYPAIR -# - name: NATS_ADMIN_PASS -# valueFrom: -# secretKeyRef: -# name: fuel-streams-publisher -# key: NATS_ADMIN_PASS -# Optional: Bulk environment references -# envFrom: -# - configMapRef: -# name: additional-config -# - secretRef: -# name: additional-secrets - -env: - RELAYER_V2_LISTENING_CONTRACTS: "0xAEB0c00D0125A8a788956ade4f4F12Ead9f65DDf" - RELAYER_DA_DEPLOY_HEIGHT: "20620434" - RELAYER_LOG_PAGE_SIZE: "2000" - SYNC_HEADER_BATCH_SIZE: "100" - P2P_PORT: "30333" - RESERVED_NODES: "/dnsaddr/mainnet.fuel.network" - CHAIN_CONFIG: "mainnet" - PUBLISHER_MAX_THREADS: "32" - DB_PATH: "/mnt/db/" - POA_INSTANT: "false" - SERVICE_NAME: "NATS Publisher Node" - NATS_URL: "nats:4222" diff --git a/cluster/charts/fuel-streams/templates/_helpers.tpl b/cluster/charts/fuel-streams/templates/_helpers.tpl index 24026951..e3de60d9 100644 --- a/cluster/charts/fuel-streams/templates/_helpers.tpl +++ b/cluster/charts/fuel-streams/templates/_helpers.tpl @@ -217,4 +217,4 @@ Returns: Value if it exists and is not empty {{- if and $value (not (empty $value)) (not (eq (kindOf $value) "invalid")) }} {{- toYaml $value | nindent 0 }} {{- end }} -{{- end }} +{{- end }} \ No newline at end of file diff --git a/cluster/charts/fuel-streams/templates/common-config.yaml b/cluster/charts/fuel-streams/templates/common-config.yaml new file mode 100644 index 00000000..0ffe75dd --- /dev/null +++ b/cluster/charts/fuel-streams/templates/common-config.yaml @@ -0,0 +1,21 @@ +{{- if .Values.commonConfigMap.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: fuel-streams-config + labels: + app.kubernetes.io/instance: fuel-streams +data: + {{ .Values.commonConfigMap.data | toYaml | nindent 2 }} +{{- end }} +{{- if .Values.localSecrets.enabled }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: fuel-streams-keys + labels: + app.kubernetes.io/instance: fuel-streams +stringData: + {{ .Values.localSecrets.data | toYaml | nindent 2 }} +{{- end }} diff --git a/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml b/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml index 77972f95..a1f73522 100644 --- a/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml +++ b/cluster/charts/fuel-streams/templates/consumer/statefulset.yaml @@ -40,15 +40,22 @@ spec: - name: consumer image: "{{ $consumer.image.repository }}:{{ $consumer.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ $consumer.image.pullPolicy }} + command: ["/usr/src/sv-consumer"] args: - {{- toYaml $consumer.args | nindent 12 }} + - "--nats-url" + - "$(NATS_URL)" + - "--nats-publisher-url" + - "$(NATS_PUBLISHER_URL)" + {{- with $consumer.image.args }} + {{- toYaml . | nindent 10 }} + {{- end }} ports: - name: consumer containerPort: {{ $consumer.port }} protocol: TCP - {{- if $consumer.ports }} - {{- toYaml $consumer.ports | nindent 12 }} + {{- with $consumer.config.ports }} + {{- toYaml . | nindent 12 }} {{- end }} {{- include "set-field-and-value" (dict "context" $consumer "field" "resources" "path" "config.resources") | nindent 10 }} @@ -57,12 +64,8 @@ spec: env: - name: PORT - value: "{{ $consumer.port }}" - {{- range $key, $value := $consumer.env }} - - name: {{ $key }} - value: {{ $value | quote }} - {{- end }} - {{- with $consumer.extraEnv }} + value: {{ $consumer.port | quote }} + {{- with $consumer.env }} {{- toYaml . | nindent 12 }} {{- end }} @@ -73,18 +76,6 @@ spec: - secretRef: name: {{ include "fuel-streams.fullname" $ }}-keys optional: true - - configMapRef: - name: {{ include "fuel-streams.fullname" $ }}-consumer-config - optional: true - - secretRef: - name: {{ include "fuel-streams.fullname" $ }}-consumer-keys - optional: true - - configMapRef: - name: {{ include "fuel-streams.fullname" $ }}-aws-config - optional: true - - secretRef: - name: {{ include "fuel-streams.fullname" $ }}-nats-keys - optional: true {{- with $consumer.envFrom }} {{- toYaml . | nindent 12 }} {{- end }} diff --git a/cluster/charts/fuel-streams/templates/nats/accounts-secret.yaml b/cluster/charts/fuel-streams/templates/nats/accounts-secret.yaml deleted file mode 100644 index f5b8c743..00000000 --- a/cluster/charts/fuel-streams/templates/nats/accounts-secret.yaml +++ /dev/null @@ -1,15 +0,0 @@ -{{- $secret := .Values.natsAccountsSecret }} -{{- if $secret.enabled }} -apiVersion: v1 -kind: Secret -metadata: - {{- include "k8s.metadata" (dict "context" . "suffix" "-nats-accounts") | nindent 2 }} - labels: - {{- include "fuel-streams.labels" (dict "name" "nats-accounts" "context" .) | nindent 4 }} - app.kubernetes.io/component: nats -type: Opaque -data: - {{- if $secret.data }} - {{- toYaml $secret.data | nindent 2 }} - {{- end }} -{{- end }} diff --git a/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml b/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml index b93a0646..d594e871 100644 --- a/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml +++ b/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml @@ -77,70 +77,74 @@ spec: - name: publisher image: "{{ $publisher.image.repository }}:{{ $publisher.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ $publisher.image.pullPolicy }} + command: ["/usr/src/sv-emitter"] args: - # Common arguments - - "--enable-relayer" - - "--enable-p2p" - - "--keypair" - - "$(KEYPAIR)" - - "--relayer" - - "$(RELAYER)" - - "--ip" - - "0.0.0.0" - - "--port" - - "$(PORT)" - - "--db-path" - - "$(DB_PATH)" - - "--nats-url" - - "$(NATS_URL)" - - "--sync-header-batch-size" - - "100" - - "--relayer-log-page-size" - - "2000" - - "--sync-block-stream-buffer-size" - - "50" - - "--max-database-cache-size" - - "17179869184" - - "--state-rewind-duration" - - "136y" - - "--request-timeout" - - "60" - - "--graphql-max-complexity" - - "1000000000" - {{- if eq $publisher.network "mainnet" }} - # Mainnet specific args - - "--service-name" - - "Publisher Node (Mainnet)" - - "--snapshot" - - "./chain-config/mainnet" - - "--reserved-nodes" - - "/dnsaddr/mainnet.fuel.network" - - "--relayer-v2-listening-contracts" - - "0xAEB0c00D0125A8a788956ade4f4F12Ead9f65DDf" - - "--relayer-da-deploy-height" - - "20620434" - {{- else if eq $publisher.network "testnet" }} - # Testnet specific args - - "--service-name" - - "Publisher Node (Testnet)" - - "--snapshot" - - "./chain-config/testnet" - - "--reserved-nodes" - - "/dns4/p2p-testnet.fuel.network/tcp/30333/p2p/16Uiu2HAmDxoChB7AheKNvCVpD4PHJwuDGn8rifMBEHmEynGHvHrf,/dns4/p2p-testnet.fuel.network/tcp/30333/p2p/16Uiu2HAmHnANNk4HjAxQV66BNCRxd2MBUU89ijboZkE69aLuSn1g,/dns4/p2p-testnet.fuel.network/tcp/30333/p2p/16Uiu2HAmVE468rpkh2X1kzz8qQXmqNFiPxU5Lrya28nZdbRUdVJX" - - "--relayer-v2-listening-contracts" - - "0x01855B78C1f8868DE70e84507ec735983bf262dA" - - "--relayer-da-deploy-height" - - "5827607" - {{- end }} - {{- if $publisher.image.args }} - {{- toYaml $publisher.image.args | nindent 12 }} - {{- end }} + # Common arguments + - "--enable-relayer" + - "--enable-p2p" + - "--keypair" + - "$(KEYPAIR)" + - "--relayer" + - "$(RELAYER)" + - "--ip" + - "0.0.0.0" + - "--port" + - "$(PORT)" + - "--peering-port" + - "30333" + - "--utxo-validation" + - "--poa-instant" + - "false" + - "--db-path" + - "$(DB_PATH)" + - "--nats-url" + - "$(NATS_URL)" + - "--sync-header-batch-size" + - "100" + - "--relayer-log-page-size" + - "2000" + - "--sync-block-stream-buffer-size" + - "50" + - "--max-database-cache-size" + - "17179869184" + - "--state-rewind-duration" + - "136y" + - "--request-timeout" + - "60" + - "--graphql-max-complexity" + - "1000000000" + {{- if eq $publisher.network "mainnet" }} + # Mainnet specific args + - "--service-name" + - "Publisher Node (Mainnet)" + - "--snapshot" + - "./chain-config/mainnet" + - "--reserved-nodes" + - "/dnsaddr/mainnet.fuel.network" + - "--relayer-v2-listening-contracts" + - "0xAEB0c00D0125A8a788956ade4f4F12Ead9f65DDf" + - "--relayer-da-deploy-height" + - "20620434" + {{- else if eq $publisher.network "testnet" }} + # Testnet specific args + - "--service-name" + - "Publisher Node (Testnet)" + - "--snapshot" + - "./chain-config/testnet" + - "--reserved-nodes" + - "/dns4/p2p-testnet.fuel.network/tcp/30333/p2p/16Uiu2HAmDxoChB7AheKNvCVpD4PHJwuDGn8rifMBEHmEynGHvHrf,/dns4/p2p-testnet.fuel.network/tcp/30333/p2p/16Uiu2HAmHnANNk4HjAxQV66BNCRxd2MBUU89ijboZkE69aLuSn1g,/dns4/p2p-testnet.fuel.network/tcp/30333/p2p/16Uiu2HAmVE468rpkh2X1kzz8qQXmqNFiPxU5Lrya28nZdbRUdVJX" + - "--relayer-v2-listening-contracts" + - "0x01855B78C1f8868DE70e84507ec735983bf262dA" + - "--relayer-da-deploy-height" + - "5827607" + {{- end }} + ports: - name: http - containerPort: {{ int $publisher.service.port }} + containerPort: {{ int $publisher.port }} protocol: TCP - {{- if $publisher.ports }} - {{- toYaml $publisher.ports | nindent 12 }} + {{- with $publisher.config.ports }} + {{- toYaml . | nindent 12 }} {{- end }} {{- include "set-field-and-value" (dict "context" $publisher "field" "resources" "path" "config.resources") | nindent 10 }} @@ -152,11 +156,9 @@ spec: value: "/var/fuel-streams/tmp" - name: DB_PATH value: {{ $publisher.storage.mountPath | default "/mnt/db" | quote }} - {{- range $key, $value := $publisher.env }} - - name: {{ $key }} - value: {{ $value | quote }} - {{- end }} - {{- with $publisher.extraEnv }} + - name: PORT + value: {{ $publisher.port | quote }} + {{- with $publisher.env }} {{- toYaml . | nindent 12 }} {{- end }} @@ -167,18 +169,6 @@ spec: - secretRef: name: {{ include "fuel-streams.fullname" $ }}-keys optional: true - - configMapRef: - name: {{ include "fuel-streams.fullname" $ }}-publisher-config - optional: true - - secretRef: - name: {{ include "fuel-streams.fullname" $ }}-publisher-keys - optional: true - - configMapRef: - name: {{ include "fuel-streams.fullname" $ }}-aws-config - optional: true - - secretRef: - name: {{ include "fuel-streams.fullname" $ }}-nats-keys - optional: true {{- with $publisher.envFrom }} {{- toYaml . | nindent 12 }} {{- end }} diff --git a/cluster/charts/fuel-streams/templates/webserver/deployment.yaml b/cluster/charts/fuel-streams/templates/webserver/deployment.yaml index 8f8a9119..a8b93457 100644 --- a/cluster/charts/fuel-streams/templates/webserver/deployment.yaml +++ b/cluster/charts/fuel-streams/templates/webserver/deployment.yaml @@ -50,6 +50,15 @@ spec: {{- include "k8s.probes" (dict "context" . "service" "webserver") | nindent 10 }} {{- include "k8s.container-security-context" (dict "context" . "service" "webserver") | nindent 10 }} + env: + - name: NETWORK + value: {{ $webserver.network | quote }} + - name: PORT + value: {{ $webserver.port | quote }} + {{- with $webserver.env }} + {{- toYaml . | nindent 12 }} + {{- end }} + envFrom: - configMapRef: name: {{ include "fuel-streams.fullname" $ }}-config @@ -57,34 +66,9 @@ spec: - secretRef: name: {{ include "fuel-streams.fullname" $ }}-keys optional: true - - configMapRef: - name: {{ include "fuel-streams.fullname" $ }}-webserver-config - optional: true - - secretRef: - name: {{ include "fuel-streams.fullname" $ }}-webserver-keys - optional: true - - configMapRef: - name: {{ include "fuel-streams.fullname" $ }}-aws-config - optional: true - - secretRef: - name: {{ include "fuel-streams.fullname" $ }}-nats-keys - optional: true {{- with $webserver.envFrom }} {{- toYaml . | nindent 12 }} {{- end }} - env: - {{- range $key, $value := $webserver.env }} - - name: {{ $key }} - value: {{ $value | quote }} - {{- end }} - {{- with $webserver.extraEnv }} - {{- toYaml . | nindent 12 }} - {{- end }} - - name: NETWORK - value: "{{ $webserver.network }}" - - name: PORT - value: "{{ $webserver.port }}" - {{- include "k8s.hpa" (dict "context" . "service" (dict "name" "webserver" "autoscaling" $webserver.autoscaling)) }} {{- end }} \ No newline at end of file diff --git a/cluster/charts/fuel-streams/tests/webserver/deployment_test.yaml b/cluster/charts/fuel-streams/tests/webserver/deployment_test.yaml index 84833c59..70f1a285 100644 --- a/cluster/charts/fuel-streams/tests/webserver/deployment_test.yaml +++ b/cluster/charts/fuel-streams/tests/webserver/deployment_test.yaml @@ -186,4 +186,4 @@ tests: value: 50m - equal: path: spec.template.spec.containers[0].resources.requests.memory - value: 64Mi \ No newline at end of file + value: 64Mi diff --git a/cluster/charts/fuel-streams/values-local.yaml b/cluster/charts/fuel-streams/values-local.yaml index dc5af796..95d5d509 100644 --- a/cluster/charts/fuel-streams/values-local.yaml +++ b/cluster/charts/fuel-streams/values-local.yaml @@ -4,6 +4,11 @@ config: # Reduce storage requirements for local development publisher: + image: + repository: "sv-emitter" + tag: "latest" + pullPolicy: "Always" + storage: size: 10Gi storageClass: "standard" # Use default storage class @@ -18,12 +23,8 @@ publisher: cpu: 500m memory: 512Mi - env: - PORT: 8080 - PUBLISHER_MAX_THREADS: "12" - NATS_URL: "fuel-streams-nats-publisher:4222" - consumer: + enabled: false config: replicaCount: 1 resources: @@ -36,6 +37,7 @@ consumer: # NATS Core configuration for local development nats-core: + enabled: false container: env: GOMEMLIMIT: 1GiB @@ -65,6 +67,7 @@ nats-core: # NATS Publisher configuration for local development nats-publisher: + enabled: false container: env: GOMEMLIMIT: 1GiB @@ -91,6 +94,7 @@ nats-publisher: # NATS Client configuration for local development nats-client: + enabled: false container: env: GOMEMLIMIT: 1GiB @@ -118,20 +122,3 @@ nats-client: # Disable external service for local development natsExternalService: enabled: false - -# Use simple passwords for local development -natsAccountsSecret: - enabled: true - data: - - name: NATS_SYS_USER - value: sys - - name: NATS_SYS_PASS - value: sys - - name: NATS_ADMIN_USER - value: admin - - name: NATS_ADMIN_PASS - value: admin - - name: NATS_PUBLISHER_USER - value: default_user - - name: NATS_PUBLISHER_PASS - value: "" diff --git a/cluster/charts/fuel-streams/values.yaml b/cluster/charts/fuel-streams/values.yaml index 8980c60a..3326f6ce 100755 --- a/cluster/charts/fuel-streams/values.yaml +++ b/cluster/charts/fuel-streams/values.yaml @@ -69,6 +69,33 @@ startupProbe: failureThreshold: 6 successThreshold: 1 +# ------------------------------------------------------------------------------------------------- +# Global ConfigMap +# ------------------------------------------------------------------------------------------------- + +commonConfigMap: + enabled: true + data: + AWS_S3_BUCKET_NAME: "fuel-streams-staging" + AWS_ENDPOINT_URL: "https://s3.us-east-1.amazonaws.com" + AWS_REGION: "us-east-1" + AWS_S3_ENABLED: "true" + USE_METRICS: "false" + NATS_URL: "fuel-streams-nats-core:4222" + NATS_PUBLISHER_URL: "fuel-streams-nats-publisher:4222" + NATS_SYSTEM_USER: "sys" + NATS_SYSTEM_PASS: "sys" + NATS_ADMIN_USER: "admin" + NATS_ADMIN_PASS: "admin" + NATS_PUBLISHER_USER: "default_user" + NATS_PUBLISHER_PASS: "" + +# This is a secret that is used for local development +# It is not used in production +localSecrets: + enabled: false + data: {} + # ------------------------------------------------------------------------------------------------- # Monitoring # ------------------------------------------------------------------------------------------------- @@ -83,6 +110,7 @@ monitoring: publisher: enabled: true network: mainnet + port: 8080 image: repository: ghcr.io/fuellabs/sv-emitter @@ -90,12 +118,10 @@ publisher: tag: "latest" args: [] - env: - NATS_URL: "fuel-streams-nats-core:4222" - - service: - type: ClusterIP - port: 8080 + # You can override the env variables for the container here + # using a map or an array of key-value pairs + env: [] + envFrom: [] prometheus: enabled: false @@ -143,30 +169,6 @@ publisher: podValue: 4 periodSeconds: 15 - # Additional environment variables with complex structures - # extraEnv: [] - # - name: RELAYER - # valueFrom: - # secretKeyRef: - # name: fuel-streams-publisher - # key: RELAYER - # - name: KEYPAIR - # valueFrom: - # secretKeyRef: - # name: fuel-streams-publisher - # key: KEYPAIR - # - name: NATS_ADMIN_PASS - # valueFrom: - # secretKeyRef: - # name: fuel-streams-publisher - # key: NATS_ADMIN_PASS - # Optional: Bulk environment references - # envFrom: {} - # - configMapRef: - # name: additional-config - # - secretRef: - # name: additional-secrets - # ------------------------------------------------------------------------------------------------- # Consumer configuration # ------------------------------------------------------------------------------------------------- @@ -178,15 +180,12 @@ consumer: repository: ghcr.io/fuellabs/sv-consumer pullPolicy: Always tag: "latest" - args: - - --nats-core-url - - $(NATS_CORE_URL) - - --nats-publisher-url - - $(NATS_PUBLISHER_URL) - - env: - NATS_CORE_URL: "fuel-streams-nats-core:4222" - NATS_PUBLISHER_URL: "fuel-streams-nats-publisher:4222" + args: [] + + # You can override the env variables for the container here + # using a map or an array of key-value pairs + env: [] + envFrom: [] config: replicaCount: 3 @@ -206,7 +205,7 @@ consumer: resources: {} autoscaling: - enabled: true + enabled: false minReplicas: 1 maxReplicas: 3 targetCPUUtilizationPercentage: 80 @@ -228,20 +227,23 @@ consumer: webserver: enabled: false - port: 9003 network: mainnet - service: - enabled: true - dns: "stream-dev.fuel.network" - image: repository: fuel-streams-webserver pullPolicy: Never tag: "latest" - env: - NATS_URL: "fuel-streams-nats-publisher:4222" + service: + enabled: true + type: LoadBalancer + port: 9003 + dns: "stream-dev.fuel.network" + + # You can override the env variables for the container here + # using a map or an array of key-value pairs + env: [] + envFrom: [] config: replicaCount: 1 @@ -294,12 +296,6 @@ natsExternalService: labels: {} annotations: {} -# This is just need to run locally, for production you need to -# create a secret with the correct values named fuel-streams-nats-accounts -natsAccountsSecret: - enabled: false - data: [] - # ------------------------------------------------------------------------------------------------- # NATS Core configuration # ------------------------------------------------------------------------------------------------- diff --git a/cluster/docker/docker-compose.yml b/cluster/docker/docker-compose.yml index 34f9c55e..34b76756 100644 --- a/cluster/docker/docker-compose.yml +++ b/cluster/docker/docker-compose.yml @@ -7,7 +7,7 @@ services: container_name: nats-core restart: always ports: - - 4111:4222 + - 4222:4222 volumes: - ./nats-config/core.conf:/etc/nats/nats.conf - ./nats-config/accounts.conf:/etc/nats/accounts.conf @@ -19,28 +19,6 @@ services: env_file: - ./../../.env - nats-client: - profiles: - - all - - nats - image: nats:latest - container_name: nats-client - restart: always - ports: - - 4333:4222 - volumes: - - ./nats-config/client.conf:/etc/nats/nats.conf - - ./nats-config/accounts.conf:/etc/nats/accounts.conf - command: - - --name=fuel-streams-nats-client - - --js - - --config=/etc/nats/nats.conf - - -D - env_file: - - ./../../.env - depends_on: - - nats-core - nats-publisher: profiles: - all @@ -49,7 +27,7 @@ services: container_name: nats-publisher restart: always ports: - - 4222:4222 + - 4333:4222 volumes: - ./nats-config/publisher.conf:/etc/nats/nats.conf - ./nats-config/accounts.conf:/etc/nats/accounts.conf diff --git a/cluster/docker/fuel-streams-ws.Dockerfile b/cluster/docker/fuel-streams-ws.Dockerfile index 435eb1f8..92103c4b 100644 --- a/cluster/docker/fuel-streams-ws.Dockerfile +++ b/cluster/docker/fuel-streams-ws.Dockerfile @@ -88,4 +88,4 @@ EXPOSE ${STREAMER_API_PORT} # https://stackoverflow.com/a/44671685 # https://stackoverflow.com/a/40454758 # hadolint ignore=DL3025 -CMD exec ./fuel-streams-ws +CMD ["./fuel-streams-ws"] diff --git a/cluster/docker/sv-consumer.Dockerfile b/cluster/docker/sv-consumer.Dockerfile index 533e8459..5b20d1cd 100644 --- a/cluster/docker/sv-consumer.Dockerfile +++ b/cluster/docker/sv-consumer.Dockerfile @@ -72,4 +72,5 @@ COPY --from=builder /root/sv-consumer.d . EXPOSE ${PORT} -ENTRYPOINT ["./sv-consumer"] +WORKDIR /usr/src +CMD ["./sv-consumer"] diff --git a/cluster/docker/sv-emitter.Dockerfile b/cluster/docker/sv-emitter.Dockerfile index 4cd045e5..ec75100a 100644 --- a/cluster/docker/sv-emitter.Dockerfile +++ b/cluster/docker/sv-emitter.Dockerfile @@ -61,7 +61,7 @@ FROM ubuntu:22.04 AS run ARG PORT=4000 ARG P2P_PORT=30333 -ENV IP="${IP}" +ARG DB_PATH=/mnt/db ENV PORT="${PORT}" WORKDIR /usr/src @@ -72,11 +72,12 @@ RUN apt-get update -y \ && apt-get clean -y \ && rm -rf /var/lib/apt/lists/* -COPY --from=builder /root/sv-emitter /usr/local/bin/ -COPY --from=builder /root/sv-emitter.d /usr/local/bin/ +COPY --from=builder /root/sv-emitter . +COPY --from=builder /root/sv-emitter.d . COPY /cluster/chain-config ./chain-config EXPOSE ${PORT} EXPOSE ${P2P_PORT} -ENTRYPOINT /usr/local/bin/sv-emitter +WORKDIR /usr/src +CMD ["./sv-emitter", "--port", "${PORT}", "--peering-port", "${P2P_PORT}", "--db-path", "${DB_PATH}"] diff --git a/cluster/scripts/build_docker.sh b/cluster/scripts/build_docker.sh index aa650139..31a26269 100755 --- a/cluster/scripts/build_docker.sh +++ b/cluster/scripts/build_docker.sh @@ -33,10 +33,10 @@ if [[ $# -eq 0 ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then fi # Default values -IMAGE_NAME="sv-emitter" DOCKERFILE="cluster/docker/sv-emitter.Dockerfile" +IMAGE_NAME=${EXPECTED_IMAGE:-"sv-emitter"} +TAG=${EXPECTED_TAG:-"latest"} BUILD_ARGS="" -TAG=${TAG:-"latest"} # From environment variable with default # Parse named arguments while [[ $# -gt 0 ]]; do diff --git a/cluster/scripts/gen_env_secret.sh b/cluster/scripts/gen_env_secret.sh index 2d4a1e6c..46a589f8 100755 --- a/cluster/scripts/gen_env_secret.sh +++ b/cluster/scripts/gen_env_secret.sh @@ -4,15 +4,12 @@ source .env # Generate the YAML configuration -cat << EOF > cluster/charts/fuel-streams/values-publisher-secrets.yaml -publisher: - extraEnv: - - name: RELAYER - value: "${RELAYER:-}" - - name: KEYPAIR - value: "${KEYPAIR:-}" - - name: NATS_ADMIN_PASS - value: "${NATS_ADMIN_PASS:-}" +cat << EOF > cluster/charts/fuel-streams/values-secrets.yaml +localSecrets: + enabled: true + data: + RELAYER: "${RELAYER:-}" + KEYPAIR: "${KEYPAIR:-}" EOF -echo "Generated values-publisher-secrets.yaml with environment variables" +echo "Generated values-secrets.yaml with environment variables" diff --git a/cluster/scripts/setup_k8s.sh b/cluster/scripts/setup_k8s.sh deleted file mode 100755 index 791c8595..00000000 --- a/cluster/scripts/setup_k8s.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash - -[[ $DEBUG = true ]] && set -x -set -euo pipefail - -# Parse command line arguments -NAMESPACE="${1:-fuel-streams}" # Use first argument, default to "fuel-streams" if not provided - -# Configure namespace and context -echo -e "\n\033[1;33mConfiguring ${NAMESPACE} namespace and context:\033[0m" - -# Check if namespace exists -if kubectl get namespace ${NAMESPACE} &> /dev/null; then - echo "Namespace ${NAMESPACE} already exists" -else - echo "Creating namespace ${NAMESPACE}..." - kubectl create namespace ${NAMESPACE} -fi - -# Switch to minikube context -if ! kubectl config current-context | grep -q "minikube"; then - echo "Switching to minikube context..." - kubectl config use-context minikube -else - echo "Already in minikube context" -fi - -# Set namespace for current context -CURRENT_NAMESPACE=$(kubectl config view --minify --output 'jsonpath={..namespace}') -if [ "$CURRENT_NAMESPACE" != "${NAMESPACE}" ]; then - echo "Setting current namespace to ${NAMESPACE}..." - kubectl config set-context --current --cluster=minikube --namespace=${NAMESPACE} -else - echo "Context namespace is already set to ${NAMESPACE}" -fi - -# Verify context configuration -echo -e "\n\033[1;33mVerifying cluster context:\033[0m" -kubectl config get-contexts diff --git a/cluster/scripts/setup_minikube.sh b/cluster/scripts/setup_minikube.sh index 55c63555..cf4009cd 100755 --- a/cluster/scripts/setup_minikube.sh +++ b/cluster/scripts/setup_minikube.sh @@ -28,6 +28,56 @@ minikube start \ --memory="$MEMORY" \ --cpus 8 +minikube addons enable metrics-server +minikube addons enable registry + +# Remove existing registry proxy container if running +if docker ps -a | grep -q "minikube-registry-proxy"; then + echo "Removing existing registry proxy container..." + docker rm -f minikube-registry-proxy +fi + +# Forward minikube registry to localhost +docker run --rm -d \ + --network=host \ + --name minikube-registry-proxy \ + alpine ash -c "apk add socat && socat TCP-LISTEN:5000,reuseaddr,fork TCP:$(minikube ip):5000" + # Display minikube status echo -e "\n\033[1;33mMinikube Status:\033[0m" minikube status + +# Parse command line arguments +NAMESPACE="${1:-fuel-streams}" # Use first argument, default to "fuel-streams" if not provided + +# Configure namespace and context +echo -e "\n\033[1;33mConfiguring ${NAMESPACE} namespace and context:\033[0m" + +# Check if namespace exists +if kubectl get namespace ${NAMESPACE} &> /dev/null; then + echo "Namespace ${NAMESPACE} already exists" +else + echo "Creating namespace ${NAMESPACE}..." + kubectl create namespace ${NAMESPACE} +fi + +# Switch to minikube context +if ! kubectl config current-context | grep -q "minikube"; then + echo "Switching to minikube context..." + kubectl config use-context minikube +else + echo "Already in minikube context" +fi + +# Set namespace for current context +CURRENT_NAMESPACE=$(kubectl config view --minify --output 'jsonpath={..namespace}') +if [ "$CURRENT_NAMESPACE" != "${NAMESPACE}" ]; then + echo "Setting current namespace to ${NAMESPACE}..." + kubectl config set-context --current --cluster=minikube --namespace=${NAMESPACE} +else + echo "Context namespace is already set to ${NAMESPACE}" +fi + +# Verify context configuration +echo -e "\n\033[1;33mVerifying cluster context:\033[0m" +kubectl config get-contexts diff --git a/crates/fuel-streams-ws/src/cli.rs b/crates/fuel-streams-ws/src/cli.rs index 4c1d457d..4aed7400 100644 --- a/crates/fuel-streams-ws/src/cli.rs +++ b/crates/fuel-streams-ws/src/cli.rs @@ -18,7 +18,7 @@ pub struct Cli { long, value_name = "NATS_URL", env = "NATS_URL", - default_value = "nats://localhost:4111", + default_value = "nats://localhost:4222", help = "NATS URL" )] pub nats_url: String, diff --git a/crates/sv-consumer/src/cli.rs b/crates/sv-consumer/src/cli.rs index 2f893567..6b51f6bf 100644 --- a/crates/sv-consumer/src/cli.rs +++ b/crates/sv-consumer/src/cli.rs @@ -5,17 +5,17 @@ pub struct Cli { /// Fuel Network to connect to. #[arg( long, - value_name = "NATS_CORE_URL", - env = "NATS_CORE_URL", + value_name = "NATS_URL", + env = "NATS_URL", default_value = "localhost:4222", - help = "NATS Core URL to connect to." + help = "NATS URL to connect to." )] - pub nats_core_url: String, + pub nats_url: String, #[arg( long, value_name = "NATS_PUBLISHER_URL", env = "NATS_PUBLISHER_URL", - default_value = "localhost:4222", + default_value = "localhost:4333", help = "NATS Publisher URL to connect to." )] pub nats_publisher_url: String, diff --git a/crates/sv-consumer/src/lib.rs b/crates/sv-consumer/src/lib.rs index ef3312c2..782b1918 100644 --- a/crates/sv-consumer/src/lib.rs +++ b/crates/sv-consumer/src/lib.rs @@ -14,7 +14,7 @@ pub enum Client { impl Client { pub fn url(&self, cli: &cli::Cli) -> String { match self { - Client::Core => cli.nats_core_url.clone(), + Client::Core => cli.nats_url.clone(), Client::Publisher => cli.nats_publisher_url.clone(), } } diff --git a/scripts/run_streamer.sh b/scripts/run_streamer.sh index 3eba6121..a58a3d1c 100755 --- a/scripts/run_streamer.sh +++ b/scripts/run_streamer.sh @@ -86,7 +86,7 @@ echo -e "==========================================" echo "Runtime Settings:" echo "→ Mode: ${MODE:-dev}" echo "→ API Port: ${API_PORT:-9003}" -echo "→ NATS URL: ${NATS_URL:-nats://localhost:4222}" +echo "→ NATS URL: ${NATS_URL:-"nats://localhost:4222"}" echo "→ S3 Enabled: ${S3_ENABLED:-true}" echo "→ JWT Secret: ${JWT_SECRET:-secret}" echo "→ Use Metrics: ${USE_METRICS:-false}" @@ -99,7 +99,7 @@ echo -e "==========================================\n" # Define common arguments COMMON_ARGS=( "--api-port" "${API_PORT:-9003}" - "--nats-url" "${NATS_URL:-nats://localhost:4222}" + "--nats-url" "${NATS_URL:-"nats://localhost:4222"}" "--jwt-secret" "${JWT_SECRET:-secret}" ) diff --git a/scripts/set_env.sh b/scripts/set_env.sh index 393115e0..36efa113 100755 --- a/scripts/set_env.sh +++ b/scripts/set_env.sh @@ -47,6 +47,7 @@ cleanup_env load_env # Set and export network-specific variables +export NETWORK=$NETWORK export RESERVED_NODES=$(eval echo "\$${NETWORK_UPPER}_RESERVED_NODES") export RELAYER_V2_LISTENING_CONTRACTS=$(eval echo "\$${NETWORK_UPPER}_RELAYER_V2_LISTENING_CONTRACTS") export RELAYER_DA_DEPLOY_HEIGHT=$(eval echo "\$${NETWORK_UPPER}_RELAYER_DA_DEPLOY_HEIGHT") @@ -54,17 +55,6 @@ export RELAYER=$(eval echo "\$${NETWORK_UPPER}_RELAYER") export SYNC_HEADER_BATCH_SIZE=$(eval echo "\$${NETWORK_UPPER}_SYNC_HEADER_BATCH_SIZE") export RELAYER_LOG_PAGE_SIZE=$(eval echo "\$${NETWORK_UPPER}_RELAYER_LOG_PAGE_SIZE") export CHAIN_CONFIG=$NETWORK -export NETWORK=$NETWORK -export USE_METRICS="$(echo "$USE_METRICS")" -export USE_ELASTIC_LOGGING="$(echo "$USE_ELASTIC_LOGGING")" -export AWS_S3_ENABLED="$(echo "$AWS_S3_ENABLED")" -export AWS_ACCESS_KEY_ID="$(echo "$AWS_ACCESS_KEY_ID")" -export AWS_SECRET_ACCESS_KEY="$(echo "$AWS_SECRET_ACCESS_KEY")" -export AWS_REGION="$(echo "$AWS_REGION")" -export AWS_ENDPOINT_URL="$(echo "$AWS_ENDPOINT_URL")" -export AWS_S3_BUCKET_NAME="$(echo "$AWS_S3_BUCKET_NAME")" -export JWT_AUTH_SECRET="$(echo "$JWT_AUTH_SECRET")" -# export NATS_URL="$(echo "$NATS_URL")" # Append network-specific variables to .env file { @@ -79,14 +69,4 @@ export JWT_AUTH_SECRET="$(echo "$JWT_AUTH_SECRET")" echo "SYNC_HEADER_BATCH_SIZE=$SYNC_HEADER_BATCH_SIZE" echo "RELAYER_LOG_PAGE_SIZE=$RELAYER_LOG_PAGE_SIZE" echo "CHAIN_CONFIG=$CHAIN_CONFIG" - echo "USE_METRICS=$USE_METRICS" - echo "USE_ELASTIC_LOGGING=$USE_ELASTIC_LOGGING" - echo "AWS_S3_ENABLED=$AWS_S3_ENABLED" - echo "AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID" - echo "AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY" - echo "AWS_REGION=$AWS_REGION" - echo "AWS_ENDPOINT_URL=$AWS_ENDPOINT_URL" - echo "AWS_S3_BUCKET_NAME=$AWS_S3_BUCKET_NAME" - echo "JWT_AUTH_SECRET=$JWT_AUTH_SECRET" - # echo "NATS_URL=$NATS_URL" } >> .env From 6e842c41151410703a60afda9dea79cdfddd5143 Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 15:44:17 -0300 Subject: [PATCH 20/31] build(repo): bump chart --- cluster/charts/fuel-streams/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cluster/charts/fuel-streams/Chart.yaml b/cluster/charts/fuel-streams/Chart.yaml index 2cd4aa78..a45dfec4 100755 --- a/cluster/charts/fuel-streams/Chart.yaml +++ b/cluster/charts/fuel-streams/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 appVersion: "1.0" description: A Helm chart for Kubernetes name: fuel-streams -version: 0.6.6 +version: 0.6.7 dependencies: - name: nats version: 1.2.8 From 55013f29e94a625f12d086b0bb0cf3d18c37fbc8 Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 16:50:08 -0300 Subject: [PATCH 21/31] build(repo): general fixes and adjustments --- Makefile | 4 +- Tiltfile | 122 ++++++++-------- cluster/charts/fuel-streams/Chart.yaml | 5 - .../charts/fuel-streams/templates/_blocks.tpl | 2 +- .../templates/nats/certificate.yaml | 57 -------- .../templates/nats/external-service.yaml | 40 ----- .../templates/webserver/deployment.yaml | 23 +-- .../templates/webserver/service.yaml | 32 ++-- cluster/charts/fuel-streams/values-local.yaml | 85 ++++++----- cluster/charts/fuel-streams/values.yaml | 138 +++--------------- cluster/docker/fuel-streams-ws.Dockerfile | 22 +-- cluster/scripts/build_docker.sh | 9 +- .../fuel-streams-nats/src/nats_client_opts.rs | 8 +- crates/fuel-streams-ws/src/cli.rs | 4 +- crates/fuel-streams-ws/src/config.rs | 2 +- scripts/run_streamer.sh | 14 +- 16 files changed, 181 insertions(+), 386 deletions(-) delete mode 100644 cluster/charts/fuel-streams/templates/nats/certificate.yaml delete mode 100644 cluster/charts/fuel-streams/templates/nats/external-service.yaml diff --git a/Makefile b/Makefile index 035b0e05..37784110 100644 --- a/Makefile +++ b/Makefile @@ -247,7 +247,7 @@ run-consumer: run-streamer: NETWORK="testnet" run-streamer: MODE="dev" -run-streamer: API_PORT="9003" +run-streamer: PORT="9003" run-streamer: NATS_URL="nats://localhost:4222" run-streamer: S3_ENABLED="true" run-streamer: JWT_SECRET="secret" @@ -255,7 +255,7 @@ run-streamer: USE_METRICS="false" run-streamer: check-network @./scripts/run_streamer.sh \ --mode $(MODE) \ - --api-port $(API_PORT) \ + --port $(PORT) \ --nats-url $(NATS_URL) \ --s3-enabled $(S3_ENABLED) \ --jwt-secret $(JWT_SECRET) \ diff --git a/Tiltfile b/Tiltfile index 759da19e..e72db71c 100755 --- a/Tiltfile +++ b/Tiltfile @@ -17,9 +17,7 @@ custom_build( ref='sv-emitter:latest', command=[ './cluster/scripts/build_docker.sh', - '--image-name', 'sv-emitter', - '--dockerfile', './cluster/docker/sv-emitter.Dockerfile', - '--build-args', '--build-arg PACKAGE_NAME=sv-emitter' + '--dockerfile', './cluster/docker/sv-emitter.Dockerfile' ], deps=[ './src', @@ -37,46 +35,50 @@ custom_build( ) # Build sv-consumer -# custom_build( -# ref='sv-consumer:latest', -# command=[ -# './cluster/scripts/build_docker.sh', -# '--image-name', 'sv-consumer', -# '--dockerfile', './cluster/docker/sv-consumer.Dockerfile' -# ], -# deps=[ -# './src', -# './Cargo.toml', -# './Cargo.lock', -# './cluster/docker/sv-consumer.Dockerfile' -# ], -# live_update=[ -# sync('./src', '/usr/src'), -# sync('./Cargo.toml', '/usr/src/Cargo.toml'), -# sync('./Cargo.lock', '/usr/src/Cargo.lock'), -# run('cargo build', trigger=['./src', './Cargo.toml', './Cargo.lock']) -# ], -# ignore=['./target'] -# ) +custom_build( + ref='sv-consumer:latest', + image_deps=['sv-emitter:latest'], + command=[ + './cluster/scripts/build_docker.sh', + '--dockerfile', './cluster/docker/sv-consumer.Dockerfile' + ], + deps=[ + './src', + './Cargo.toml', + './Cargo.lock', + './cluster/docker/sv-consumer.Dockerfile' + ], + live_update=[ + sync('./src', '/usr/src'), + sync('./Cargo.toml', '/usr/src/Cargo.toml'), + sync('./Cargo.lock', '/usr/src/Cargo.lock'), + run('cargo build', trigger=['./src', './Cargo.toml', './Cargo.lock']) + ], + ignore=['./target'] +) -# # Build streamer ws image with proper configuration for Minikube -# custom_build( -# ref='fuel-streams-ws:latest', -# command=['./cluster/scripts/build_streamer.sh'], -# deps=[ -# './src', -# './Cargo.toml', -# './Cargo.lock', -# './docker/fuel-streams-ws.Dockerfile' -# ], -# live_update=[ -# sync('./src', '/usr/src'), -# sync('./Cargo.toml', '/usr/src/Cargo.toml'), -# sync('./Cargo.lock', '/usr/src/Cargo.lock'), -# run('cargo build', trigger=['./src', './Cargo.toml', './Cargo.lock']) -# ], -# ignore=['./target'] -# ) +# Build streamer ws image with proper configuration for Minikube +custom_build( + ref='fuel-streams-ws:latest', + image_deps=['sv-consumer:latest', 'sv-emitter:latest'], + command=[ + './cluster/scripts/build_docker.sh', + '--dockerfile', './cluster/docker/fuel-streams-ws.Dockerfile' + ], + deps=[ + './src', + './Cargo.toml', + './Cargo.lock', + './cluster/docker/fuel-streams-ws.Dockerfile' + ], + live_update=[ + sync('./src', '/usr/src'), + sync('./Cargo.toml', '/usr/src/Cargo.toml'), + sync('./Cargo.lock', '/usr/src/Cargo.lock'), + run('cargo build', trigger=['./src', './Cargo.toml', './Cargo.lock']) + ], + ignore=['./target'] +) # Deploy the Helm chart with values from .env # Get deployment mode from environment variable, default to 'full' @@ -88,31 +90,35 @@ RESOURCES = { 'name': 'fuel-streams-publisher', 'ports': ['8080:8080'], 'labels': 'publisher', - 'config_mode': ['minimal', 'full'] + 'config_mode': ['minimal', 'full'], + 'deps': ['fuel-streams-nats-core', 'fuel-streams-nats-publisher'] + }, + 'consumer': { + 'name': 'fuel-streams-sv-consumer', + 'ports': ['8081:8080'], + 'labels': 'consumer', + 'config_mode': ['minimal', 'full'], + 'deps': ['fuel-streams-nats-core', 'fuel-streams-nats-publisher', 'fuel-streams-publisher'] + }, + 'fuel-streams-ws': { + 'name': 'fuel-streams-ws', + 'ports': ['9003:9003'], + 'labels': 'ws', + 'config_mode': ['minimal', 'full'], + 'deps': ['fuel-streams-nats-core', 'fuel-streams-nats-publisher'] }, - # 'consumer': { - # 'name': 'fuel-streams-sv-consumer', - # 'ports': ['8081:8080'], - # 'labels': 'consumer', - # 'config_mode': ['minimal', 'full'] - # }, 'nats-core': { 'name': 'fuel-streams-nats-core', - 'ports': ['4222:4222'], + 'ports': ['4222:4222', '6222:6222', '7422:7422'], 'labels': 'nats', 'config_mode': ['minimal', 'full'] }, 'nats-publisher': { 'name': 'fuel-streams-nats-publisher', - 'ports': ['4333:4222'], + 'ports': ['4333:4222', '6333:6222', '7433:7422'], 'labels': 'nats', - 'config_mode': ['minimal', 'full'] - }, - 'nats-client': { - 'name': 'fuel-streams-nats-client', - 'ports': ['4444:4222'], - 'labels': 'nats', - 'config_mode': ['minimal', 'full'] + 'config_mode': ['minimal', 'full'], + 'deps': ['fuel-streams-nats-core'] }, } diff --git a/cluster/charts/fuel-streams/Chart.yaml b/cluster/charts/fuel-streams/Chart.yaml index a45dfec4..d2d74bc7 100755 --- a/cluster/charts/fuel-streams/Chart.yaml +++ b/cluster/charts/fuel-streams/Chart.yaml @@ -14,8 +14,3 @@ dependencies: repository: https://nats-io.github.io/k8s/helm/charts/ alias: nats-publisher condition: nats-publisher.enabled - - name: nats - version: 1.2.8 - repository: https://nats-io.github.io/k8s/helm/charts/ - alias: nats-client - condition: nats-client.enabled diff --git a/cluster/charts/fuel-streams/templates/_blocks.tpl b/cluster/charts/fuel-streams/templates/_blocks.tpl index c9055c12..580c16e6 100644 --- a/cluster/charts/fuel-streams/templates/_blocks.tpl +++ b/cluster/charts/fuel-streams/templates/_blocks.tpl @@ -68,7 +68,7 @@ data: accounts { SYS: { users: [ - {user: $NATS_SYS_USER, password: $NATS_SYS_PASS} + {user: $NATS_SYSTEM_USER, password: $NATS_SYSTEM_PASS} ] } ADMIN: { diff --git a/cluster/charts/fuel-streams/templates/nats/certificate.yaml b/cluster/charts/fuel-streams/templates/nats/certificate.yaml deleted file mode 100644 index 46b00bba..00000000 --- a/cluster/charts/fuel-streams/templates/nats/certificate.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- $cert := .Values.natsExternalService.certificate}} -{{- $service := .Values.natsExternalService.service }} -{{- if and .Values.natsExternalService.enabled $service.dns }} -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - {{- include "k8s.metadata" (dict "context" . "suffix" "-nats-cert") | nindent 2 }} - annotations: - {{- include "set-value" (dict "context" $cert "path" "annotations") | nindent 4 }} - labels: - {{- include "fuel-streams.labels" (dict "name" "nats-client" "context" .) | nindent 4 }} - {{- include "set-value" (dict "context" $cert "path" "labels") | nindent 4 }} - app.kubernetes.io/component: nats -spec: - secretName: {{ include "fuel-streams.fullname" . }}-nats-tls - duration: {{ $cert.duration }} - renewBefore: {{ $cert.renewBefore }} - dnsNames: - - {{ $service.dns }} - issuerRef: - name: {{ $cert.issuer }} - kind: ClusterIssuer ---- -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - {{- include "k8s.metadata" (dict "context" . "suffix" "-nats-cert-validator") | nindent 2 }} - labels: - {{- include "fuel-streams.labels" (dict "name" "nats-client" "context" .) | nindent 4 }} - {{- include "set-value" (dict "context" $cert "path" "labels") | nindent 4 }} - app.kubernetes.io/component: nats - annotations: - cert-manager.io/cluster-issuer: {{ $cert.issuer }} - kubernetes.io/ingress.class: nginx - acme.cert-manager.io/http01-ingress-class: nginx - nginx.ingress.kubernetes.io/ssl-redirect: "false" - nginx.ingress.kubernetes.io/force-ssl-redirect: "false" - cert-manager.io/common-name: {{ $service.dns }} - {{- include "set-value" (dict "context" $cert "path" "annotations") | nindent 4 }} -spec: - ingressClassName: nginx - tls: - - hosts: - - {{ $service.dns }} - secretName: {{ include "fuel-streams.fullname" . }}-nats-tls - rules: - - host: {{ $service.dns }} - http: - paths: - - path: /.well-known/acme-challenge/ - pathType: Prefix - backend: - service: - name: cm-acme-http-solver - port: - number: 8089 -{{- end }} diff --git a/cluster/charts/fuel-streams/templates/nats/external-service.yaml b/cluster/charts/fuel-streams/templates/nats/external-service.yaml deleted file mode 100644 index 22231bbc..00000000 --- a/cluster/charts/fuel-streams/templates/nats/external-service.yaml +++ /dev/null @@ -1,40 +0,0 @@ -{{- $service := .Values.natsExternalService.service }} -{{- if and .Values.natsExternalService.enabled $service.dns }} -apiVersion: v1 -kind: Service -metadata: - {{- include "k8s.metadata" (dict "context" . "suffix" "-nats-client-nlb") | nindent 2 }} - annotations: - external-dns.alpha.kubernetes.io/hostname: {{ $service.dns }} - external-dns.alpha.kubernetes.io/cloudflare-proxied: "false" - service.beta.kubernetes.io/aws-load-balancer-attributes: load_balancing.cross_zone.enabled=true - service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp - service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip - service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing - service.beta.kubernetes.io/aws-load-balancer-target-group-attributes: preserve_client_ip.enabled=true,stickiness.enabled=true,stickiness.type=source_ip,load_balancing.cross_zone.enabled=true - service.beta.kubernetes.io/aws-load-balancer-type: external - service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags: "WebSocket=true" - {{- include "set-value" (dict "context" $service "path" "annotations") | nindent 2 }} - labels: - {{- include "fuel-streams.labels" (dict "name" "nats-client" "context" .) | nindent 4 }} - {{- include "set-value" (dict "context" $service "path" "labels") | nindent 4 }} - app.kubernetes.io/component: nats -spec: - type: LoadBalancer - loadBalancerClass: service.k8s.aws/nlb - externalTrafficPolicy: Local - ports: - - appProtocol: tcp - name: nats - port: 4222 - protocol: TCP - targetPort: nats - - appProtocol: tcp - name: wss - port: 8443 - protocol: TCP - targetPort: websocket - selector: - {{- include "fuel-streams.selectorLabels" (dict "name" "nats-client" "context" .) | nindent 4 }} - app.kubernetes.io/component: nats -{{- end }} diff --git a/cluster/charts/fuel-streams/templates/webserver/deployment.yaml b/cluster/charts/fuel-streams/templates/webserver/deployment.yaml index a8b93457..b669f5c5 100644 --- a/cluster/charts/fuel-streams/templates/webserver/deployment.yaml +++ b/cluster/charts/fuel-streams/templates/webserver/deployment.yaml @@ -1,4 +1,5 @@ {{- $webserver := .Values.webserver -}} +{{- $service := $webserver.service -}} {{- if $webserver.enabled -}} apiVersion: apps/v1 kind: Deployment @@ -9,6 +10,7 @@ metadata: labels: {{- include "fuel-streams.labels" (dict "name" "webserver" "context" .) | nindent 4 }} {{- include "set-value" (dict "context" $webserver "path" "config.labels") | nindent 4 }} + app.kubernetes.io/component: webserver spec: {{- if not $webserver.autoscaling.enabled }} replicas: {{ $webserver.config.replicaCount }} @@ -24,6 +26,7 @@ spec: labels: {{- include "fuel-streams.labels" (dict "name" "webserver" "context" .) | nindent 8 }} {{- include "set-value" (dict "context" $webserver "path" "config.labels") | nindent 8 }} + app.kubernetes.io/component: webserver spec: {{- if .Values.serviceAccount.create }} @@ -43,22 +46,13 @@ spec: ports: - name: webserver - containerPort: {{ $webserver.port }} + containerPort: {{ $service.port }} protocol: TCP {{- include "set-field-and-value" (dict "context" $webserver "field" "resources" "path" "config.resources") | nindent 10 }} {{- include "k8s.probes" (dict "context" . "service" "webserver") | nindent 10 }} {{- include "k8s.container-security-context" (dict "context" . "service" "webserver") | nindent 10 }} - env: - - name: NETWORK - value: {{ $webserver.network | quote }} - - name: PORT - value: {{ $webserver.port | quote }} - {{- with $webserver.env }} - {{- toYaml . | nindent 12 }} - {{- end }} - envFrom: - configMapRef: name: {{ include "fuel-streams.fullname" $ }}-config @@ -70,5 +64,14 @@ spec: {{- toYaml . | nindent 12 }} {{- end }} + env: + - name: NETWORK + value: {{ $webserver.network | quote }} + - name: PORT + value: {{ $service.port | quote }} + {{- with $webserver.env }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- include "k8s.hpa" (dict "context" . "service" (dict "name" "webserver" "autoscaling" $webserver.autoscaling)) }} {{- end }} \ No newline at end of file diff --git a/cluster/charts/fuel-streams/templates/webserver/service.yaml b/cluster/charts/fuel-streams/templates/webserver/service.yaml index cc567369..345c03a4 100644 --- a/cluster/charts/fuel-streams/templates/webserver/service.yaml +++ b/cluster/charts/fuel-streams/templates/webserver/service.yaml @@ -1,35 +1,37 @@ -{{- $webserver := .Values.webserver }} -{{- $service := $webserver.service }} -{{- if and $webserver.enabled $service.enabled }} ---- +{{- $service := .Values.webserver.service }} +{{- if and .Values.webserver.enabled $service.enabled }} apiVersion: v1 kind: Service metadata: - {{- include "k8s.metadata" (dict "context" . "suffix" "-webserver") | nindent 2 }} + {{- include "k8s.metadata" (dict "context" . "suffix" "-webserver-nlb") | nindent 2 }} annotations: + {{- if $service.dns }} + external-dns.alpha.kubernetes.io/hostname: {{ $service.dns }} + external-dns.alpha.kubernetes.io/cloudflare-proxied: "false" + {{- end }} service.beta.kubernetes.io/aws-load-balancer-attributes: load_balancing.cross_zone.enabled=true service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing + service.beta.kubernetes.io/aws-load-balancer-target-group-attributes: preserve_client_ip.enabled=true,stickiness.enabled=true,stickiness.type=source_ip,load_balancing.cross_zone.enabled=true service.beta.kubernetes.io/aws-load-balancer-type: external - {{- if $service.dns }} - external-dns.alpha.kubernetes.io/hostname: {{ $service.dns }} - external-dns.alpha.kubernetes.io/cloudflare-proxied: "false" - {{- end }} - {{- include "set-value" (dict "context" $service "path" "annotations") | nindent 4 }} + service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags: "WebSocket=true" + {{- include "set-value" (dict "context" $service "path" "annotations") | nindent 2 }} labels: {{- include "fuel-streams.labels" (dict "name" "webserver" "context" .) | nindent 4 }} {{- include "set-value" (dict "context" $service "path" "labels") | nindent 4 }} + app.kubernetes.io/component: webserver spec: - type: LoadBalancer + type: {{ $service.type }} loadBalancerClass: service.k8s.aws/nlb externalTrafficPolicy: Local ports: - - name: webserver - port: {{ $webserver.port }} - targetPort: {{ $webserver.port }} + - appProtocol: tcp + name: websocket + port: {{ $service.port }} protocol: TCP - appProtocol: tcp + targetPort: {{ $service.port }} selector: {{- include "fuel-streams.selectorLabels" (dict "name" "webserver" "context" .) | nindent 4 }} + app.kubernetes.io/component: webserver {{- end }} diff --git a/cluster/charts/fuel-streams/values-local.yaml b/cluster/charts/fuel-streams/values-local.yaml index 95d5d509..ca264fab 100644 --- a/cluster/charts/fuel-streams/values-local.yaml +++ b/cluster/charts/fuel-streams/values-local.yaml @@ -2,12 +2,29 @@ config: createRoles: true healthChecks: true +commonConfigMap: + enabled: true + data: + AWS_S3_BUCKET_NAME: "fuel-streams-staging" + AWS_ENDPOINT_URL: "https://localhost:9000" + AWS_REGION: "us-east-1" + AWS_S3_ENABLED: "false" + USE_METRICS: "false" + NATS_URL: "fuel-streams-nats-core:4222" + NATS_PUBLISHER_URL: "fuel-streams-nats-publisher:4222" + NATS_SYSTEM_USER: "sys" + NATS_SYSTEM_PASS: "sys" + NATS_ADMIN_USER: "admin" + NATS_ADMIN_PASS: "admin" + NATS_PUBLIC_USER: "default_user" + NATS_PUBLIC_PASS: "" + # Reduce storage requirements for local development publisher: image: - repository: "sv-emitter" - tag: "latest" - pullPolicy: "Always" + repository: sv-emitter + pullPolicy: IfNotPresent + tag: latest storage: size: 10Gi @@ -24,7 +41,12 @@ publisher: memory: 512Mi consumer: - enabled: false + enabled: true + image: + repository: sv-consumer + pullPolicy: IfNotPresent + tag: latest + config: replicaCount: 1 resources: @@ -35,13 +57,30 @@ consumer: cpu: 500m memory: 512Mi +webserver: + enabled: true + image: + repository: fuel-streams-ws + pullPolicy: IfNotPresent + tag: latest + + service: + enabled: true + port: 9003 + + tls: + enabled: false + # NATS Core configuration for local development nats-core: - enabled: false + enabled: true container: env: GOMEMLIMIT: 1GiB merge: + envFrom: + - configMapRef: + name: fuel-streams-config resources: requests: cpu: 100m @@ -67,38 +106,14 @@ nats-core: # NATS Publisher configuration for local development nats-publisher: - enabled: false - container: - env: - GOMEMLIMIT: 1GiB - merge: - resources: - requests: - cpu: 100m - memory: 512Mi - limits: - cpu: 500m - memory: 1Gi - - config: - jetstream: - fileStore: - pvc: - size: 10Gi - storageClassName: "standard" - - merge: - jetstream: - max_file_store: << 10GiB >> - max_memory_store: << 1GiB >> - -# NATS Client configuration for local development -nats-client: - enabled: false + enabled: true container: env: GOMEMLIMIT: 1GiB merge: + envFrom: + - configMapRef: + name: fuel-streams-config resources: requests: cpu: 100m @@ -118,7 +133,3 @@ nats-client: jetstream: max_file_store: << 10GiB >> max_memory_store: << 1GiB >> - -# Disable external service for local development -natsExternalService: - enabled: false diff --git a/cluster/charts/fuel-streams/values.yaml b/cluster/charts/fuel-streams/values.yaml index 3326f6ce..3ab558df 100755 --- a/cluster/charts/fuel-streams/values.yaml +++ b/cluster/charts/fuel-streams/values.yaml @@ -87,8 +87,8 @@ commonConfigMap: NATS_SYSTEM_PASS: "sys" NATS_ADMIN_USER: "admin" NATS_ADMIN_PASS: "admin" - NATS_PUBLISHER_USER: "default_user" - NATS_PUBLISHER_PASS: "" + NATS_PUBLIC_USER: "default_user" + NATS_PUBLIC_PASS: "" # This is a secret that is used for local development # It is not used in production @@ -115,7 +115,7 @@ publisher: image: repository: ghcr.io/fuellabs/sv-emitter pullPolicy: Always - tag: "latest" + tag: latest args: [] # You can override the env variables for the container here @@ -179,7 +179,7 @@ consumer: image: repository: ghcr.io/fuellabs/sv-consumer pullPolicy: Always - tag: "latest" + tag: latest args: [] # You can override the env variables for the container here @@ -230,15 +230,25 @@ webserver: network: mainnet image: - repository: fuel-streams-webserver - pullPolicy: Never - tag: "latest" + repository: ghcr.io/fuellabs/fuel-streams-ws + pullPolicy: Always + tag: latest service: enabled: true type: LoadBalancer port: 9003 dns: "stream-dev.fuel.network" + annotations: {} + labels: {} + + tls: + enabled: true + issuer: "letsencrypt-prod" + duration: "2160h" + renewBefore: "360h" + annotations: {} + labels: {} # You can override the env variables for the container here # using a map or an array of key-value pairs @@ -279,23 +289,6 @@ webserver: podValue: 4 periodSeconds: 15 -# ------------------------------------------------------------------------------------------------- -# NATS Common Configuration -# ------------------------------------------------------------------------------------------------- - -natsExternalService: - enabled: true - certificate: - issuer: "letsencrypt-prod" - duration: "2160h" - renewBefore: "360h" - annotations: {} - labels: {} - service: - dns: "stream-dev.fuel.network" - labels: {} - annotations: {} - # ------------------------------------------------------------------------------------------------- # NATS Core configuration # ------------------------------------------------------------------------------------------------- @@ -466,100 +459,3 @@ nats-publisher: merge: $tplYaml: | {{- include "nats-accounts" . | nindent 8 }} - -# ------------------------------------------------------------------------------------------------- -# NATS Client configuration -# ------------------------------------------------------------------------------------------------- - -nats-client: - enabled: true - - natsBox: - enabled: false - - statefulSet: - merge: - spec: - replicas: 3 - - container: - image: - repository: nats - tag: 2.10.24-alpine - env: - GOMEMLIMIT: 7GiB - merge: - resources: - requests: - cpu: 2 - memory: 8Gi - - service: - enabled: true - ports: - nats: - enabled: true - websocket: - enabled: true - leafnodes: - enabled: true - monitor: - enabled: false - mqtt: - enabled: false - - config: - jetstream: - enabled: true - fileStore: - dir: /data - pvc: - enabled: true - size: 100Gi - storageClassName: "gp3-generic" - - leafnodes: - enabled: true - port: 7422 - merge: - remotes: - - urls: ["nats-leaf://admin:admin@fuel-streams-nats-core:7422"] - account: ADMIN - - websocket: - enabled: true - port: 8443 - # This is just enable if the natsExternalService is enabled - # and the DNS is set to the correct value - tls: - enabled: true - dir: /etc/nats-certs/websocket - cert: tls.crt - key: tls.key - secretName: fuel-streams-nats-tls - merge: - no_tls: false - same_origin: false - compression: false - handshake_timeout: "20s" - no_auth_user: default_user - - monitor: - enabled: false - port: 8222 - - merge: - max_payload: << 32MiB >> - jetstream: - domain: CLIENT - sync_interval: << 30s >> - max_outstanding_catchup: << 512MiB >> - max_file_store: << 100GiB >> - max_memory_store: << 7GiB >> - system_account: SYS - $include: auth.conf - - configMap: - merge: - $tplYaml: | - {{- include "nats-accounts" . | nindent 8 }} diff --git a/cluster/docker/fuel-streams-ws.Dockerfile b/cluster/docker/fuel-streams-ws.Dockerfile index 92103c4b..bfe396dd 100644 --- a/cluster/docker/fuel-streams-ws.Dockerfile +++ b/cluster/docker/fuel-streams-ws.Dockerfile @@ -56,20 +56,8 @@ RUN \ # Stage 2: Run FROM ubuntu:22.04 AS run -ARG STREAMER_API_PORT=9003 - -ENV STREAMER_API_PORT=$STREAMER_API_PORT -ENV NATS_URL= -ENV NETWORK= -ENV USE_METRICS= -ENV USE_ELASTIC_LOGGING= -ENV AWS_S3_ENABLED= -ENV AWS_ACCESS_KEY_ID= -ENV AWS_SECRET_ACCESS_KEY= -ENV AWS_REGION= -ENV AWS_ENDPOINT_URL= -ENV AWS_S3_BUCKET_NAME= -ENV JWT_AUTH_SECRET= +ARG PORT=9003 +ENV PORT=$PORT WORKDIR /usr/src @@ -83,9 +71,5 @@ RUN apt-get update -y \ COPY --from=builder /root/fuel-streams-ws . COPY --from=builder /root/fuel-streams-ws.d . -EXPOSE ${STREAMER_API_PORT} - -# https://stackoverflow.com/a/44671685 -# https://stackoverflow.com/a/40454758 -# hadolint ignore=DL3025 +EXPOSE ${PORT} CMD ["./fuel-streams-ws"] diff --git a/cluster/scripts/build_docker.sh b/cluster/scripts/build_docker.sh index 31a26269..78163422 100755 --- a/cluster/scripts/build_docker.sh +++ b/cluster/scripts/build_docker.sh @@ -11,7 +11,6 @@ Usage: $(basename "$0") [OPTIONS] Build a Docker image using specified parameters. Options: - --image-name Name for the Docker image (default: sv-emitter) --dockerfile Path to Dockerfile (default: cluster/docker/sv-emitter.Dockerfile) --build-args Additional Docker build arguments (optional) -h, --help Show this help message @@ -21,8 +20,8 @@ Environment variables: DOCKER_HOST Docker daemon socket (optional) Examples: - $(basename "$0") --image-name my-image --dockerfile ./Dockerfile - $(basename "$0") --image-name my-image --dockerfile ./Dockerfile --build-args "--build-arg KEY=VALUE" + $(basename "$0") --dockerfile ./Dockerfile + $(basename "$0") --dockerfile ./Dockerfile --build-args "--build-arg KEY=VALUE" EOF exit 1 } @@ -41,10 +40,6 @@ BUILD_ARGS="" # Parse named arguments while [[ $# -gt 0 ]]; do case $1 in - --image-name) - IMAGE_NAME="$2" - shift 2 - ;; --dockerfile) DOCKERFILE="$2" shift 2 diff --git a/crates/fuel-streams-nats/src/nats_client_opts.rs b/crates/fuel-streams-nats/src/nats_client_opts.rs index ef196b34..f6aaa0a3 100644 --- a/crates/fuel-streams-nats/src/nats_client_opts.rs +++ b/crates/fuel-streams-nats/src/nats_client_opts.rs @@ -23,10 +23,10 @@ impl NatsAuth { .expect("NATS_ADMIN_PASS must be set"), ), NatsAuth::System => ( - dotenvy::var("NATS_SYS_USER") - .expect("NATS_SYS_USER must be set"), - dotenvy::var("NATS_SYS_PASS") - .expect("NATS_SYS_PASS must be set"), + dotenvy::var("NATS_SYSTEM_USER") + .expect("NATS_SYSTEM_USER must be set"), + dotenvy::var("NATS_SYSTEM_PASS") + .expect("NATS_SYSTEM_PASS must be set"), ), NatsAuth::Public => ("default_user".to_string(), "".to_string()), NatsAuth::Custom(user, pass) => { diff --git a/crates/fuel-streams-ws/src/cli.rs b/crates/fuel-streams-ws/src/cli.rs index 4aed7400..37cad8bd 100644 --- a/crates/fuel-streams-ws/src/cli.rs +++ b/crates/fuel-streams-ws/src/cli.rs @@ -7,11 +7,11 @@ pub struct Cli { #[arg( long, value_name = "PORT", - env = "API_PORT", + env = "PORT", default_value = "9003", help = "Port number for the API server" )] - pub api_port: u16, + pub port: u16, /// NATS URL #[arg( diff --git a/crates/fuel-streams-ws/src/config.rs b/crates/fuel-streams-ws/src/config.rs index eeb01ce0..eeaada1b 100644 --- a/crates/fuel-streams-ws/src/config.rs +++ b/crates/fuel-streams-ws/src/config.rs @@ -54,7 +54,7 @@ impl Config { fn from_cli(cli: &crate::cli::Cli) -> Result { Ok(Config { api: ApiConfig { - port: cli.api_port, + port: cli.port, tls: None, }, auth: AuthConfig { diff --git a/scripts/run_streamer.sh b/scripts/run_streamer.sh index a58a3d1c..0cdf6e01 100755 --- a/scripts/run_streamer.sh +++ b/scripts/run_streamer.sh @@ -10,7 +10,7 @@ usage() { echo "Usage: $0 [options]" echo "Options:" echo " --mode : Specify the run mode (dev|profiling)" - echo " --api-port : Port number for the API server (default: 9003)" + echo " --port : Port number for the API server (default: 9003)" echo " --nats-url : NATS URL (default: nats://localhost:4222)" echo " --s3-enabled : Enable S3 integration (default: true)" echo " --jwt-secret : Secret key for JWT authentication (default: secret)" @@ -19,7 +19,7 @@ usage() { echo "" echo "Examples:" echo " $0 # Runs with all defaults" - echo " $0 --mode dev --api-port 8080 # Custom port" + echo " $0 --mode dev --port 8080 # Custom port" echo " $0 --mode dev --use-metrics # Enable metrics" exit 1 } @@ -30,8 +30,8 @@ while [[ "$#" -gt 0 ]]; do MODE="$2" shift 2 ;; - --api-port) - API_PORT="$2" + --port) + PORT="$2" shift 2 ;; --nats-url) @@ -65,7 +65,7 @@ while [[ "$#" -gt 0 ]]; do done # Load environment variables with defaults -API_PORT=${API_PORT:-9003} +PORT=${PORT:-9003} NATS_URL=${NATS_URL:-nats://localhost:4222} S3_ENABLED=${S3_ENABLED:-true} JWT_SECRET=${JWT_SECRET:-secret} @@ -85,7 +85,7 @@ echo -e "==========================================" # Runtime Configuration echo "Runtime Settings:" echo "→ Mode: ${MODE:-dev}" -echo "→ API Port: ${API_PORT:-9003}" +echo "→ API Port: ${PORT:-9003}" echo "→ NATS URL: ${NATS_URL:-"nats://localhost:4222"}" echo "→ S3 Enabled: ${S3_ENABLED:-true}" echo "→ JWT Secret: ${JWT_SECRET:-secret}" @@ -98,7 +98,7 @@ echo -e "==========================================\n" # Define common arguments COMMON_ARGS=( - "--api-port" "${API_PORT:-9003}" + "--port" "${PORT:-9003}" "--nats-url" "${NATS_URL:-"nats://localhost:4222"}" "--jwt-secret" "${JWT_SECRET:-secret}" ) From 9cbdbc3f6d6dca7b57b65b7f1fd3c383f7a82a49 Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 16:50:42 -0300 Subject: [PATCH 22/31] build(repo): bump chart --- cluster/charts/fuel-streams/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cluster/charts/fuel-streams/Chart.yaml b/cluster/charts/fuel-streams/Chart.yaml index d2d74bc7..165f8181 100755 --- a/cluster/charts/fuel-streams/Chart.yaml +++ b/cluster/charts/fuel-streams/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 appVersion: "1.0" description: A Helm chart for Kubernetes name: fuel-streams -version: 0.6.7 +version: 0.7.0 dependencies: - name: nats version: 1.2.8 From 485a318dbaa8b57471bbc12025f8f7ad7aba9df8 Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 21:18:39 -0300 Subject: [PATCH 23/31] fix(repo): s3 client workaround --- .github/actions/setup-rust/action.yaml | 12 +++- .github/workflows/ci.yaml | 70 +++++++++---------- .github/workflows/publish_release.yaml | 12 +--- Tiltfile | 2 +- cluster/charts/fuel-streams/values-local.yaml | 2 +- cluster/charts/fuel-streams/values.yaml | 2 +- crates/fuel-streams-core/src/stream/error.rs | 20 +++--- .../fuel-streams-storage/src/s3/s3_client.rs | 51 +++++++++----- .../fuel-streams-ws/src/server/ws/socket.rs | 2 +- knope.toml | 57 --------------- 10 files changed, 95 insertions(+), 135 deletions(-) diff --git a/.github/actions/setup-rust/action.yaml b/.github/actions/setup-rust/action.yaml index 11d83426..600f16ef 100644 --- a/.github/actions/setup-rust/action.yaml +++ b/.github/actions/setup-rust/action.yaml @@ -21,8 +21,16 @@ runs: - name: Create .env file with NATS environment variables shell: bash run: | - echo "NATS_ADMIN_PASS=${NATS_ADMIN_PASS:-default_pass}" >> .env - echo "NATS_PUBLIC_PASS=${NATS_PUBLIC_PASS:-temp-public-pass}" >> .env + set_env_var() { + echo "$1=${!1:-$2}" >> $GITHUB_ENV + echo "$1=${!1:-$2}" >> .env + } + set_env_var "NATS_SYSTEM_USER" "sys" + set_env_var "NATS_SYSTEM_PASS" "sys" + set_env_var "NATS_ADMIN_USER" "admin" + set_env_var "NATS_ADMIN_PASS" "admin" + set_env_var "NATS_PUBLIC_USER" "default_user" + set_env_var "NATS_PUBLIC_PASS" "" - name: Install Rust uses: dtolnay/rust-toolchain@master diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d51d0d2c..28d44ca0 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -340,34 +340,34 @@ jobs: rustup target add ${{ matrix.platform.target }} cargo build --release --locked --target ${{ matrix.platform.target }} --package ${{ matrix.package }} - - name: Strip binaries - run: ./scripts/strip-binary.sh "${{ matrix.platform.target }}" - - - name: Set Artifact Name - id: artifact-name - shell: bash - run: | - echo "value=${{ matrix.package }}-${{ matrix.platform.os_name }}" >> $GITHUB_OUTPUT - - - name: Package as archive - shell: bash - run: | - cd target/${{ matrix.platform.target }}/release - tar czvf ../../../${{ steps.artifact-name.outputs.value }}.tar.gz ${{ matrix.package }} - cd - - - - name: Publish release artifacts - uses: actions/upload-artifact@v4 - if: >- - (github.event_name == 'push' && - github.ref == 'refs/heads/main' && - contains(github.event.head_commit.message, 'ci(release): Preparing')) || - github.event_name == 'workflow_dispatch' - with: - name: ${{ steps.artifact-name.outputs.value }} - path: ${{ matrix.package }}-* - if-no-files-found: error - retention-days: 30 + # - name: Strip binaries + # run: ./scripts/strip-binary.sh "${{ matrix.platform.target }}" + + # - name: Set Artifact Name + # id: artifact-name + # shell: bash + # run: | + # echo "value=${{ matrix.package }}-${{ matrix.platform.os_name }}" >> $GITHUB_OUTPUT + + # - name: Package as archive + # shell: bash + # run: | + # cd target/${{ matrix.platform.target }}/release + # tar czvf ../../../${{ steps.artifact-name.outputs.value }}.tar.gz ${{ matrix.package }} + # cd - + + # - name: Publish release artifacts + # uses: actions/upload-artifact@v4 + # if: >- + # (github.event_name == 'push' && + # github.ref == 'refs/heads/main' && + # contains(github.event.head_commit.message, 'ci(release): Preparing')) || + # github.event_name == 'workflow_dispatch' + # with: + # name: ${{ steps.artifact-name.outputs.value }} + # path: ${{ matrix.package }}-* + # if-no-files-found: error + # retention-days: 30 release: name: Create Release with Knope @@ -388,14 +388,14 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - - name: Download Artifacts - uses: actions/download-artifact@v4 - with: - path: artifacts - merge-multiple: true + # - name: Download Artifacts + # uses: actions/download-artifact@v4 + # with: + # path: artifacts + # merge-multiple: true - - name: List Artifacts - run: ls -R artifacts + # - name: List Artifacts + # run: ls -R artifacts - name: Run Knope Action uses: knope-dev/action@v2.1.0 diff --git a/.github/workflows/publish_release.yaml b/.github/workflows/publish_release.yaml index 4dbc4f19..bd4edc6a 100644 --- a/.github/workflows/publish_release.yaml +++ b/.github/workflows/publish_release.yaml @@ -19,17 +19,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Set NATS environment variables - shell: bash - run: | - set_env_var() { - echo "$1=${!1:-$2}" >> $GITHUB_ENV - echo "$1=${!1:-$2}" >> .env - } - set_env_var "NATS_ADMIN_PASS" "null" - - name: Install toolchain - uses: dtolnay/rust-toolchain@master + - name: Install Rust + uses: ./.github/actions/setup-rust with: toolchain: ${{ env.RUST_VERSION }} target: x86_64-unknown-linux-gnu,wasm32-unknown-unknown diff --git a/Tiltfile b/Tiltfile index e72db71c..f0a4edb1 100755 --- a/Tiltfile +++ b/Tiltfile @@ -115,7 +115,7 @@ RESOURCES = { }, 'nats-publisher': { 'name': 'fuel-streams-nats-publisher', - 'ports': ['4333:4222', '6333:6222', '7433:7422'], + 'ports': ['4333:4222', '6222:6222', '7433:7422'], 'labels': 'nats', 'config_mode': ['minimal', 'full'], 'deps': ['fuel-streams-nats-core'] diff --git a/cluster/charts/fuel-streams/values-local.yaml b/cluster/charts/fuel-streams/values-local.yaml index ca264fab..b9290dd8 100644 --- a/cluster/charts/fuel-streams/values-local.yaml +++ b/cluster/charts/fuel-streams/values-local.yaml @@ -91,7 +91,7 @@ nats-core: config: cluster: - replicas: 1 # Single replica for local development + replicas: 3 jetstream: fileStore: diff --git a/cluster/charts/fuel-streams/values.yaml b/cluster/charts/fuel-streams/values.yaml index 3ab558df..2e2709c6 100755 --- a/cluster/charts/fuel-streams/values.yaml +++ b/cluster/charts/fuel-streams/values.yaml @@ -238,7 +238,7 @@ webserver: enabled: true type: LoadBalancer port: 9003 - dns: "stream-dev.fuel.network" + dns: "stream-staging.fuel.network" annotations: {} labels: {} diff --git a/crates/fuel-streams-core/src/stream/error.rs b/crates/fuel-streams-core/src/stream/error.rs index 27994989..168155da 100644 --- a/crates/fuel-streams-core/src/stream/error.rs +++ b/crates/fuel-streams-core/src/stream/error.rs @@ -12,37 +12,37 @@ use thiserror::Error; #[derive(Error, DisplayDoc, Debug)] pub enum StreamError { - /// Failed to publish to stream: {subject_name} + /// Failed to publish to stream: {subject_name}, error: {source} PublishFailed { subject_name: String, #[source] source: error::Error, }, - /// Failed to publish to S3 + /// Failed to publish to S3: {0} S3PublishError(#[from] fuel_streams_storage::s3::S3ClientError), - /// Failed to retrieve last published message from stream + /// Failed to retrieve last published message from stream: {0} GetLastPublishedFailed(#[from] error::Error), - /// Failed to create Key-Value Store + /// Failed to create Key-Value Store: {0} StoreCreation(#[from] error::Error), - /// Failed to publish item to Key-Value Store + /// Failed to publish item to Key-Value Store: {0} StorePublish(#[from] PutError), - /// Failed to subscribe to subject in Key-Value Store + /// Failed to subscribe to subject in Key-Value Store: {0} StoreSubscribe(#[from] error::Error), - /// Failed to publish item to stream + /// Failed to publish item to stream: {0} StreamPublish(#[from] CreateError), - /// Failed to create stream + /// Failed to create stream: {0} StreamCreation(#[from] error::Error), - /// Failed to create consumer for stream + /// Failed to create consumer for stream: {0} ConsumerCreate(#[from] error::Error), - /// Failed to consume messages from stream + /// Failed to consume messages from stream: {0} ConsumerMessages(#[from] error::Error), } diff --git a/crates/fuel-streams-storage/src/s3/s3_client.rs b/crates/fuel-streams-storage/src/s3/s3_client.rs index 6a031f1f..39a0c140 100644 --- a/crates/fuel-streams-storage/src/s3/s3_client.rs +++ b/crates/fuel-streams-storage/src/s3/s3_client.rs @@ -1,4 +1,4 @@ -use aws_config::{meta::region::RegionProviderChain, Region}; +use aws_config::{BehaviorVersion, Region}; use aws_sdk_s3::{ config::http::HttpResponse, operation::{ @@ -6,7 +6,9 @@ use aws_sdk_s3::{ delete_bucket::DeleteBucketError, delete_object::DeleteObjectError, get_object::GetObjectError, + put_bucket_policy::PutBucketPolicyError, put_object::PutObjectError, + put_public_access_block::PutPublicAccessBlockError, }, Client, }; @@ -34,6 +36,12 @@ pub enum S3ClientError { MissingEnvVar(String), #[error("Failed to stream objects because: {0}")] StreamingError(String), + #[error("Failed to put bucket policy: {0}")] + PutBucketPolicyError(#[from] SdkError), + #[error("Failed to put public access block: {0}")] + PutPublicAccessBlockError( + #[from] SdkError, + ), #[error("IO Error: {0}")] IoError(#[from] std::io::Error), } @@ -46,32 +54,41 @@ pub struct S3Client { impl S3Client { pub async fn new(opts: &S3ClientOpts) -> Result { - // Load AWS configuration - let mut aws_config = aws_config::from_env(); - aws_config = aws_config.endpoint_url(opts.endpoint_url()); - let region_provider = - RegionProviderChain::first_try(Region::new(opts.region())); - let region = region_provider.region().await.unwrap(); - - aws_config = aws_config.region(region); - - let s3_config = - aws_sdk_s3::config::Builder::from(&aws_config.load().await) - .force_path_style(true) - .build(); + let config = aws_config::defaults(BehaviorVersion::v2024_03_28()) + .endpoint_url(opts.endpoint_url().to_string()) + .region(Region::new(opts.region().to_string())) + // TODO: Remove this once we have a proper S3 bucket created + // for now this is a workaround to avoid signing requests + .no_credentials() + .load() + .await; + + // Create S3 config without signing + let s3_config = aws_sdk_s3::config::Builder::from(&config) + .force_path_style(true) + .build(); let client = aws_sdk_s3::Client::from_conf(s3_config); - - Ok(Self { + let s3_client = Self { client, bucket: opts.bucket(), - }) + }; + + Ok(s3_client) } pub fn arc(self) -> std::sync::Arc { std::sync::Arc::new(self) } + pub fn client(&self) -> &Client { + &self.client + } + + pub fn bucket(&self) -> &str { + &self.bucket + } + pub async fn put_object( &self, key: &str, diff --git a/crates/fuel-streams-ws/src/server/ws/socket.rs b/crates/fuel-streams-ws/src/server/ws/socket.rs index c0716c76..15e01909 100644 --- a/crates/fuel-streams-ws/src/server/ws/socket.rs +++ b/crates/fuel-streams-ws/src/server/ws/socket.rs @@ -276,7 +276,7 @@ async fn handle_binary_message( }), ) .await; - return Ok(()); + Ok(()) } } } diff --git a/knope.toml b/knope.toml index c5a56ee8..57f4fc54 100644 --- a/knope.toml +++ b/knope.toml @@ -19,63 +19,6 @@ extra_changelog_sections = [ ], name = "📝 Notes" }, ] -[[packages.fuel-streams.assets]] -path = "artifacts/fuel-streams-Linux-aarch64-gnu.tar.gz" - -[[packages.fuel-streams.assets]] -path = "artifacts/fuel-streams-Linux-aarch64-musl.tar.gz" - -[[packages.fuel-streams.assets]] -path = "artifacts/fuel-streams-Linux-x86_64-gnu.tar.gz" - -[[packages.fuel-streams.assets]] -path = "artifacts/fuel-streams-Linux-x86_64-musl.tar.gz" - -[[packages.fuel-streams.assets]] -path = "artifacts/fuel-streams-macOS-aarch64.tar.gz" - -[[packages.fuel-streams.assets]] -path = "artifacts/fuel-streams-macOS-x86_64.tar.gz" - -# ------------------------------------------------------------ -# Fuel-streams-ws package -# ------------------------------------------------------------ -[packages.fuel-streams-ws] -versioned_files = ["crates/fuel-streams-ws/Cargo.toml"] -changelog = "CHANGELOG.md" -extra_changelog_sections = [ - { types = [ - "major", - ], name = "⚠️ Breaking Change" }, - { types = [ - "minor", - ], name = "🚀 Features" }, - { types = [ - "patch", - ], name = "🐛 Fixes" }, - { footers = [ - "Changelog-Note", - ], name = "📝 Notes" }, -] - -[[packages.fuel-streams-ws.assets]] -path = "artifacts/fuel-streams-ws-Linux-aarch64-gnu.tar.gz" - -[[packages.fuel-streams-ws.assets]] -path = "artifacts/fuel-streams-ws-Linux-aarch64-musl.tar.gz" - -[[packages.fuel-streams-ws.assets]] -path = "artifacts/fuel-streams-ws-Linux-x86_64-gnu.tar.gz" - -[[packages.fuel-streams-ws.assets]] -path = "artifacts/fuel-streams-ws-Linux-x86_64-musl.tar.gz" - -[[packages.fuel-streams-ws.assets]] -path = "artifacts/fuel-streams-ws-macOS-aarch64.tar.gz" - -[[packages.fuel-streams-ws.assets]] -path = "artifacts/fuel-streams-ws-macOS-x86_64.tar.gz" - # ------------------------------------------------------------ # Workflow to get the current version # ------------------------------------------------------------ From ea4467609519db17689f8302c7043f811398899c Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 22:37:09 -0300 Subject: [PATCH 24/31] refactor(repo): rename crates to be consistent --- .github/workflows/ci.yaml | 8 +- .github/workflows/docker_publish.yaml | 14 +- .typos.toml | 2 +- Cargo.lock | 104 +- Cargo.toml | 4 +- Makefile | 2 +- Tiltfile | 22 +- .../templates/publisher/statefulset.yaml | 2 +- .../fuel-streams/tests/certificate_test.yaml | 2 +- .../tests/consumer/deployment_test.yaml | 8 +- .../tests/webserver/deployment_test.yaml | 10 +- cluster/charts/fuel-streams/values-local.yaml | 4 +- cluster/charts/fuel-streams/values.yaml | 4 +- ...ter.Dockerfile => sv-publisher.Dockerfile} | 30 +- ...-ws.Dockerfile => sv-webserver.Dockerfile} | 16 +- cluster/scripts/build_docker.sh | 6 +- cluster/scripts/build_streamer.sh | 4 +- crates/sv-consumer/Cargo.toml | 2 +- crates/sv-consumer/src/main.rs | 2 +- crates/sv-emitter/Cargo.lock | 7553 ----------------- .../{sv-emitter => sv-publisher}/Cargo.toml | 4 +- .../{sv-emitter => sv-publisher}/src/cli.rs | 0 .../{sv-emitter => sv-publisher}/src/lib.rs | 0 .../{sv-emitter => sv-publisher}/src/main.rs | 2 +- .../src/shutdown.rs | 0 .../Cargo.toml | 2 +- .../README.md | 2 +- .../src/cli.rs | 0 .../src/client/mod.rs | 0 .../src/config.rs | 0 .../src/lib.rs | 0 .../src/main.rs | 2 +- .../src/server/api.rs | 0 .../src/server/auth.rs | 0 .../src/server/context.rs | 0 .../src/server/http/handlers.rs | 0 .../src/server/http/mod.rs | 0 .../src/server/http/models.rs | 0 .../src/server/middlewares/auth.rs | 0 .../src/server/middlewares/mod.rs | 0 .../src/server/mod.rs | 0 .../src/server/state.rs | 0 .../src/server/ws/errors.rs | 0 .../src/server/ws/mod.rs | 0 .../src/server/ws/models.rs | 0 .../src/server/ws/socket.rs | 0 .../src/server/ws/state.rs | 0 .../src/telemetry/elastic_search.rs | 0 .../src/telemetry/metrics.rs | 0 .../src/telemetry/mod.rs | 0 .../src/telemetry/runtime.rs | 0 .../src/telemetry/system.rs | 0 examples/Cargo.toml | 2 +- examples/websockets.rs | 2 +- scripts/run_publisher.sh | 2 +- scripts/run_streamer.sh | 6 +- 56 files changed, 134 insertions(+), 7689 deletions(-) rename cluster/docker/{sv-emitter.Dockerfile => sv-publisher.Dockerfile} (77%) rename cluster/docker/{fuel-streams-ws.Dockerfile => sv-webserver.Dockerfile} (78%) delete mode 100644 crates/sv-emitter/Cargo.lock rename crates/{sv-emitter => sv-publisher}/Cargo.toml (97%) rename crates/{sv-emitter => sv-publisher}/src/cli.rs (100%) rename crates/{sv-emitter => sv-publisher}/src/lib.rs (100%) rename crates/{sv-emitter => sv-publisher}/src/main.rs (99%) rename crates/{sv-emitter => sv-publisher}/src/shutdown.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/Cargo.toml (99%) rename crates/{fuel-streams-ws => sv-webserver}/README.md (97%) rename crates/{fuel-streams-ws => sv-webserver}/src/cli.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/client/mod.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/config.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/lib.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/main.rs (98%) rename crates/{fuel-streams-ws => sv-webserver}/src/server/api.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/server/auth.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/server/context.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/server/http/handlers.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/server/http/mod.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/server/http/models.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/server/middlewares/auth.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/server/middlewares/mod.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/server/mod.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/server/state.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/server/ws/errors.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/server/ws/mod.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/server/ws/models.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/server/ws/socket.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/server/ws/state.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/telemetry/elastic_search.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/telemetry/metrics.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/telemetry/mod.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/telemetry/runtime.rs (100%) rename crates/{fuel-streams-ws => sv-webserver}/src/telemetry/system.rs (100%) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 28d44ca0..2055b492 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -234,8 +234,8 @@ jobs: - fuel-streams - fuel-streams-core - fuel-streams-macros - - fuel-streams-ws - - sv-emitter + - sv-webserver + - sv-publisher steps: - uses: actions/checkout@v4 @@ -270,8 +270,8 @@ jobs: matrix: package: - sv-consumer - - sv-emitter - - fuel-streams-ws + - sv-publisher + - sv-webserver is_release: - ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} platform: diff --git a/.github/workflows/docker_publish.yaml b/.github/workflows/docker_publish.yaml index 780c22ef..53a1bc4d 100644 --- a/.github/workflows/docker_publish.yaml +++ b/.github/workflows/docker_publish.yaml @@ -6,11 +6,11 @@ on: package: type: choice description: "Package to build and publish" - default: "sv-emitter" + default: "sv-publisher" required: true options: - - sv-emitter - - fuel-streams-ws + - sv-publisher + - sv-webserver - sv-consumer - all push: @@ -34,10 +34,10 @@ jobs: strategy: matrix: package: - - name: fuel-streams-ws - image: cluster/docker/fuel-streams-ws.Dockerfile - - name: sv-emitter - image: cluster/docker/sv-emitter.Dockerfile + - name: sv-webserver + image: cluster/docker/sv-webserver.Dockerfile + - name: sv-publisher + image: cluster/docker/sv-publisher.Dockerfile - name: sv-consumer image: cluster/docker/sv-consumer.Dockerfile steps: diff --git a/.typos.toml b/.typos.toml index 281d6d5c..87a65555 100644 --- a/.typos.toml +++ b/.typos.toml @@ -1,7 +1,7 @@ [files] extend-exclude = [ "pnpm-lock.yaml", - "crates/fuel-streams-ws/README.md", + "crates/sv-webserver/README.md", "docker/chain-config", "docker/monitoring", "cluster", diff --git a/Cargo.lock b/Cargo.lock index 3fc33980..2458ca5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4168,8 +4168,8 @@ dependencies = [ "anyhow", "fuel-core-types 0.40.2", "fuel-streams", - "fuel-streams-ws", "futures", + "sv-webserver", "tokio", ] @@ -4230,55 +4230,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "fuel-streams-ws" -version = "0.0.13" -dependencies = [ - "actix-cors", - "actix-server", - "actix-service", - "actix-web", - "actix-ws", - "anyhow", - "async-nats", - "bytestring", - "chrono", - "clap 4.5.23", - "derive_more 1.0.0", - "displaydoc", - "dotenvy", - "elasticsearch", - "fuel-streams", - "fuel-streams-core", - "fuel-streams-nats", - "fuel-streams-storage", - "futures", - "futures-util", - "jsonwebtoken 9.3.0", - "num_cpus", - "openssl", - "parking_lot", - "prometheus", - "rand", - "reqwest 0.12.9", - "rust_decimal", - "serde", - "serde_json", - "serde_prometheus", - "sysinfo", - "thiserror 2.0.8", - "time", - "tokio", - "tokio-tungstenite 0.24.0", - "tracing", - "tracing-actix-web", - "tracing-subscriber", - "url", - "urlencoding", - "uuid", - "validator", -] - [[package]] name = "fuel-tx" version = "0.56.0" @@ -9182,7 +9133,7 @@ dependencies = [ "futures", "openssl", "serde_json", - "sv-emitter", + "sv-publisher", "thiserror 2.0.8", "tokio", "tokio-util", @@ -9191,7 +9142,7 @@ dependencies = [ ] [[package]] -name = "sv-emitter" +name = "sv-publisher" version = "0.0.13" dependencies = [ "anyhow", @@ -9210,6 +9161,55 @@ dependencies = [ "tracing", ] +[[package]] +name = "sv-webserver" +version = "0.0.13" +dependencies = [ + "actix-cors", + "actix-server", + "actix-service", + "actix-web", + "actix-ws", + "anyhow", + "async-nats", + "bytestring", + "chrono", + "clap 4.5.23", + "derive_more 1.0.0", + "displaydoc", + "dotenvy", + "elasticsearch", + "fuel-streams", + "fuel-streams-core", + "fuel-streams-nats", + "fuel-streams-storage", + "futures", + "futures-util", + "jsonwebtoken 9.3.0", + "num_cpus", + "openssl", + "parking_lot", + "prometheus", + "rand", + "reqwest 0.12.9", + "rust_decimal", + "serde", + "serde_json", + "serde_prometheus", + "sysinfo", + "thiserror 2.0.8", + "time", + "tokio", + "tokio-tungstenite 0.24.0", + "tracing", + "tracing-actix-web", + "tracing-subscriber", + "url", + "urlencoding", + "uuid", + "validator", +] + [[package]] name = "symbolic-common" version = "12.12.4" diff --git a/Cargo.toml b/Cargo.toml index 43e054c8..a2ca7839 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,13 +73,13 @@ fuel-streams = { path = "crates/fuel-streams" } fuel-networks = { path = "crates/fuel-networks" } fuel-data-parser = { version = "0.0.13", path = "crates/fuel-data-parser" } fuel-streams-core = { version = "0.0.13", path = "crates/fuel-streams-core" } -fuel-streams-ws = { version = "0.0.13", path = "crates/fuel-streams-ws" } +sv-webserver = { version = "0.0.13", path = "crates/sv-webserver" } fuel-streams-macros = { version = "0.0.13", path = "crates/fuel-streams-macros" } fuel-streams-nats = { version = "0.0.13", path = "crates/fuel-streams-nats" } fuel-streams-storage = { version = "0.0.13", path = "crates/fuel-streams-storage" } subject-derive = { version = "0.0.13", path = "crates/fuel-streams-macros/subject-derive" } fuel-streams-executors = { version = "0.0.13", path = "crates/fuel-streams-executors" } -sv-emitter = { version = "0.0.13", path = "crates/sv-emitter" } +sv-publisher = { version = "0.0.13", path = "crates/sv-publisher" } sv-consumer = { version = "0.0.13", path = "crates/sv-consumer" } # Workspace projects diff --git a/Makefile b/Makefile index 37784110..5685b246 100644 --- a/Makefile +++ b/Makefile @@ -209,7 +209,7 @@ load-test: # ------------------------------------------------------------ run-publisher: NETWORK="testnet" -run-publisher: PACKAGE="sv-emitter" +run-publisher: PACKAGE="sv-publisher" run-publisher: MODE="dev" run-publisher: PORT="4000" run-publisher: TELEMETRY_PORT="8080" diff --git a/Tiltfile b/Tiltfile index f0a4edb1..7d819a83 100755 --- a/Tiltfile +++ b/Tiltfile @@ -12,18 +12,18 @@ dotenv() allow_k8s_contexts('minikube') -# Build sv-emitter +# Build sv-publisher custom_build( - ref='sv-emitter:latest', + ref='sv-publisher:latest', command=[ './cluster/scripts/build_docker.sh', - '--dockerfile', './cluster/docker/sv-emitter.Dockerfile' + '--dockerfile', './cluster/docker/sv-publisher.Dockerfile' ], deps=[ './src', './Cargo.toml', './Cargo.lock', - './cluster/docker/sv-emitter.Dockerfile' + './cluster/docker/sv-publisher.Dockerfile' ], live_update=[ sync('./src', '/usr/src'), @@ -37,7 +37,7 @@ custom_build( # Build sv-consumer custom_build( ref='sv-consumer:latest', - image_deps=['sv-emitter:latest'], + image_deps=['sv-publisher:latest'], command=[ './cluster/scripts/build_docker.sh', '--dockerfile', './cluster/docker/sv-consumer.Dockerfile' @@ -59,17 +59,17 @@ custom_build( # Build streamer ws image with proper configuration for Minikube custom_build( - ref='fuel-streams-ws:latest', - image_deps=['sv-consumer:latest', 'sv-emitter:latest'], + ref='sv-webserver:latest', + image_deps=['sv-consumer:latest', 'sv-publisher:latest'], command=[ './cluster/scripts/build_docker.sh', - '--dockerfile', './cluster/docker/fuel-streams-ws.Dockerfile' + '--dockerfile', './cluster/docker/sv-webserver.Dockerfile' ], deps=[ './src', './Cargo.toml', './Cargo.lock', - './cluster/docker/fuel-streams-ws.Dockerfile' + './cluster/docker/sv-webserver.Dockerfile' ], live_update=[ sync('./src', '/usr/src'), @@ -100,8 +100,8 @@ RESOURCES = { 'config_mode': ['minimal', 'full'], 'deps': ['fuel-streams-nats-core', 'fuel-streams-nats-publisher', 'fuel-streams-publisher'] }, - 'fuel-streams-ws': { - 'name': 'fuel-streams-ws', + 'sv-webserver': { + 'name': 'sv-webserver', 'ports': ['9003:9003'], 'labels': 'ws', 'config_mode': ['minimal', 'full'], diff --git a/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml b/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml index d594e871..9220c741 100644 --- a/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml +++ b/cluster/charts/fuel-streams/templates/publisher/statefulset.yaml @@ -77,7 +77,7 @@ spec: - name: publisher image: "{{ $publisher.image.repository }}:{{ $publisher.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ $publisher.image.pullPolicy }} - command: ["/usr/src/sv-emitter"] + command: ["/usr/src/sv-publisher"] args: # Common arguments - "--enable-relayer" diff --git a/cluster/charts/fuel-streams/tests/certificate_test.yaml b/cluster/charts/fuel-streams/tests/certificate_test.yaml index 179f8f4c..0c93d1ad 100644 --- a/cluster/charts/fuel-streams/tests/certificate_test.yaml +++ b/cluster/charts/fuel-streams/tests/certificate_test.yaml @@ -53,7 +53,7 @@ tests: documentIndex: 1 - equal: path: metadata.name - value: RELEASE-NAME-fuel-streams-ws-cert + value: RELEASE-NAME-sv-webserver-cert documentIndex: 1 - equal: path: spec.dnsNames[0] diff --git a/cluster/charts/fuel-streams/tests/consumer/deployment_test.yaml b/cluster/charts/fuel-streams/tests/consumer/deployment_test.yaml index 03334a73..534914e2 100644 --- a/cluster/charts/fuel-streams/tests/consumer/deployment_test.yaml +++ b/cluster/charts/fuel-streams/tests/consumer/deployment_test.yaml @@ -48,13 +48,13 @@ tests: - it: should set image configuration correctly set: consumer.enabled: true - consumer.image.repository: ghcr.io/fuellabs/fuel-streams-webserver + consumer.image.repository: ghcr.io/fuellabs/sv-webserver consumer.image.tag: latest consumer.image.pullPolicy: Always asserts: - equal: path: spec.template.spec.containers[0].image - value: ghcr.io/fuellabs/fuel-streams-webserver:latest + value: ghcr.io/fuellabs/sv-webserver:latest documentIndex: 0 - equal: path: spec.template.spec.containers[0].imagePullPolicy @@ -64,14 +64,14 @@ tests: - it: should use chart version when tag is not specified set: consumer.enabled: true - consumer.image.repository: ghcr.io/fuellabs/fuel-streams-webserver + consumer.image.repository: ghcr.io/fuellabs/sv-webserver consumer.image.tag: null Chart: Version: "1.0" asserts: - equal: path: spec.template.spec.containers[0].image - value: ghcr.io/fuellabs/fuel-streams-webserver:1.0 + value: ghcr.io/fuellabs/sv-webserver:1.0 documentIndex: 0 - it: should configure ports correctly diff --git a/cluster/charts/fuel-streams/tests/webserver/deployment_test.yaml b/cluster/charts/fuel-streams/tests/webserver/deployment_test.yaml index 70f1a285..9d5a148d 100644 --- a/cluster/charts/fuel-streams/tests/webserver/deployment_test.yaml +++ b/cluster/charts/fuel-streams/tests/webserver/deployment_test.yaml @@ -19,7 +19,7 @@ tests: of: apps/v1 - equal: path: metadata.name - value: RELEASE-NAME-fuel-streams-webserver + value: RELEASE-NAME-sv-webserver - equal: path: metadata.labels["app.kubernetes.io/component"] value: webserver @@ -40,13 +40,13 @@ tests: - it: should set image configuration correctly set: webserver.enabled: true - webserver.image.repository: ghcr.io/fuellabs/fuel-streams-webserver + webserver.image.repository: ghcr.io/fuellabs/sv-webserver webserver.image.tag: latest webserver.image.pullPolicy: Always asserts: - equal: path: spec.template.spec.containers[0].image - value: ghcr.io/fuellabs/fuel-streams-webserver:latest + value: ghcr.io/fuellabs/sv-webserver:latest - equal: path: spec.template.spec.containers[0].imagePullPolicy value: Always @@ -54,14 +54,14 @@ tests: - it: should use chart version when tag is not specified set: webserver.enabled: true - webserver.image.repository: ghcr.io/fuellabs/fuel-streams-webserver + webserver.image.repository: ghcr.io/fuellabs/sv-webserver webserver.image.tag: null Chart: Version: "1.0" asserts: - equal: path: spec.template.spec.containers[0].image - value: ghcr.io/fuellabs/fuel-streams-webserver:1.0 + value: ghcr.io/fuellabs/sv-webserver:1.0 - it: should configure ports correctly set: diff --git a/cluster/charts/fuel-streams/values-local.yaml b/cluster/charts/fuel-streams/values-local.yaml index b9290dd8..46254d83 100644 --- a/cluster/charts/fuel-streams/values-local.yaml +++ b/cluster/charts/fuel-streams/values-local.yaml @@ -22,7 +22,7 @@ commonConfigMap: # Reduce storage requirements for local development publisher: image: - repository: sv-emitter + repository: sv-publisher pullPolicy: IfNotPresent tag: latest @@ -60,7 +60,7 @@ consumer: webserver: enabled: true image: - repository: fuel-streams-ws + repository: sv-webserver pullPolicy: IfNotPresent tag: latest diff --git a/cluster/charts/fuel-streams/values.yaml b/cluster/charts/fuel-streams/values.yaml index 2e2709c6..be933eb5 100755 --- a/cluster/charts/fuel-streams/values.yaml +++ b/cluster/charts/fuel-streams/values.yaml @@ -113,7 +113,7 @@ publisher: port: 8080 image: - repository: ghcr.io/fuellabs/sv-emitter + repository: ghcr.io/fuellabs/sv-publisher pullPolicy: Always tag: latest args: [] @@ -230,7 +230,7 @@ webserver: network: mainnet image: - repository: ghcr.io/fuellabs/fuel-streams-ws + repository: ghcr.io/fuellabs/sv-webserver pullPolicy: Always tag: latest diff --git a/cluster/docker/sv-emitter.Dockerfile b/cluster/docker/sv-publisher.Dockerfile similarity index 77% rename from cluster/docker/sv-emitter.Dockerfile rename to cluster/docker/sv-publisher.Dockerfile index ec75100a..de9b042f 100644 --- a/cluster/docker/sv-emitter.Dockerfile +++ b/cluster/docker/sv-publisher.Dockerfile @@ -11,23 +11,21 @@ WORKDIR /build/ COPY --from=xx / / # hadolint ignore=DL3008 -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - lld \ - clang \ - libclang-dev \ - && xx-apt-get update \ +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + lld \ + clang \ + libclang-dev \ + && xx-apt-get update \ && xx-apt-get install -y libc6-dev g++ binutils \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* - FROM chef AS planner ENV CARGO_NET_GIT_FETCH_WITH_CLI=true COPY . . RUN cargo chef prepare --recipe-path recipe.json - FROM chef AS builder ARG PACKAGE_NAME ARG DEBUG_SYMBOLS=false @@ -41,7 +39,7 @@ RUN \ --mount=type=cache,target=/usr/local/cargo/registry/cache \ --mount=type=cache,target=/usr/local/cargo/git/db \ --mount=type=cache,target=/build/target \ - xx-cargo chef cook --release --no-default-features -p sv-emitter --recipe-path recipe.json + xx-cargo chef cook --release --no-default-features -p sv-publisher --recipe-path recipe.json # Up to this point, if our dependency tree stays the same, # all layers should be cached. COPY . . @@ -51,10 +49,10 @@ RUN \ --mount=type=cache,target=/usr/local/cargo/registry/cache \ --mount=type=cache,target=/usr/local/cargo/git/db \ --mount=type=cache,target=/build/target \ - xx-cargo build --release --no-default-features -p sv-emitter \ - && xx-verify ./target/$(xx-cargo --print-target-triple)/release/sv-emitter \ - && cp ./target/$(xx-cargo --print-target-triple)/release/sv-emitter /root/sv-emitter \ - && cp ./target/$(xx-cargo --print-target-triple)/release/sv-emitter.d /root/sv-emitter.d + xx-cargo build --release --no-default-features -p sv-publisher \ + && xx-verify ./target/$(xx-cargo --print-target-triple)/release/sv-publisher \ + && cp ./target/$(xx-cargo --print-target-triple)/release/sv-publisher /root/sv-publisher \ + && cp ./target/$(xx-cargo --print-target-triple)/release/sv-publisher.d /root/sv-publisher.d # Stage 2: Run FROM ubuntu:22.04 AS run @@ -72,12 +70,12 @@ RUN apt-get update -y \ && apt-get clean -y \ && rm -rf /var/lib/apt/lists/* -COPY --from=builder /root/sv-emitter . -COPY --from=builder /root/sv-emitter.d . +COPY --from=builder /root/sv-publisher . +COPY --from=builder /root/sv-publisher.d . COPY /cluster/chain-config ./chain-config EXPOSE ${PORT} EXPOSE ${P2P_PORT} WORKDIR /usr/src -CMD ["./sv-emitter", "--port", "${PORT}", "--peering-port", "${P2P_PORT}", "--db-path", "${DB_PATH}"] +CMD ["./sv-publisher", "--port", "${PORT}", "--peering-port", "${P2P_PORT}", "--db-path", "${DB_PATH}"] diff --git a/cluster/docker/fuel-streams-ws.Dockerfile b/cluster/docker/sv-webserver.Dockerfile similarity index 78% rename from cluster/docker/fuel-streams-ws.Dockerfile rename to cluster/docker/sv-webserver.Dockerfile index bfe396dd..75140bd4 100644 --- a/cluster/docker/fuel-streams-ws.Dockerfile +++ b/cluster/docker/sv-webserver.Dockerfile @@ -38,7 +38,7 @@ RUN \ --mount=type=cache,target=/usr/local/cargo/registry/cache \ --mount=type=cache,target=/usr/local/cargo/git/db \ --mount=type=cache,target=/build/target \ - xx-cargo chef cook --release --no-default-features -p fuel-streams-ws --recipe-path recipe.json + xx-cargo chef cook --release --no-default-features -p sv-webserver --recipe-path recipe.json # Up to this point, if our dependency tree stays the same, # all layers should be cached. COPY . . @@ -48,10 +48,10 @@ RUN \ --mount=type=cache,target=/usr/local/cargo/registry/cache \ --mount=type=cache,target=/usr/local/cargo/git/db \ --mount=type=cache,target=/build/target \ - xx-cargo build --release --no-default-features -p fuel-streams-ws \ - && xx-verify ./target/$(xx-cargo --print-target-triple)/release/fuel-streams-ws \ - && cp ./target/$(xx-cargo --print-target-triple)/release/fuel-streams-ws /root/fuel-streams-ws \ - && cp ./target/$(xx-cargo --print-target-triple)/release/fuel-streams-ws.d /root/fuel-streams-ws.d + xx-cargo build --release --no-default-features -p sv-webserver \ + && xx-verify ./target/$(xx-cargo --print-target-triple)/release/sv-webserver \ + && cp ./target/$(xx-cargo --print-target-triple)/release/sv-webserver /root/sv-webserver \ + && cp ./target/$(xx-cargo --print-target-triple)/release/sv-webserver.d /root/sv-webserver.d # Stage 2: Run FROM ubuntu:22.04 AS run @@ -68,8 +68,8 @@ RUN apt-get update -y \ && apt-get clean -y \ && rm -rf /var/lib/apt/lists/* -COPY --from=builder /root/fuel-streams-ws . -COPY --from=builder /root/fuel-streams-ws.d . +COPY --from=builder /root/sv-webserver . +COPY --from=builder /root/sv-webserver.d . EXPOSE ${PORT} -CMD ["./fuel-streams-ws"] +CMD ["./sv-webserver"] diff --git a/cluster/scripts/build_docker.sh b/cluster/scripts/build_docker.sh index 78163422..0a5eebb7 100755 --- a/cluster/scripts/build_docker.sh +++ b/cluster/scripts/build_docker.sh @@ -11,7 +11,7 @@ Usage: $(basename "$0") [OPTIONS] Build a Docker image using specified parameters. Options: - --dockerfile Path to Dockerfile (default: cluster/docker/sv-emitter.Dockerfile) + --dockerfile Path to Dockerfile (default: cluster/docker/sv-publisher.Dockerfile) --build-args Additional Docker build arguments (optional) -h, --help Show this help message @@ -32,8 +32,8 @@ if [[ $# -eq 0 ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then fi # Default values -DOCKERFILE="cluster/docker/sv-emitter.Dockerfile" -IMAGE_NAME=${EXPECTED_IMAGE:-"sv-emitter"} +DOCKERFILE="cluster/docker/sv-publisher.Dockerfile" +IMAGE_NAME=${EXPECTED_IMAGE:-"sv-publisher"} TAG=${EXPECTED_TAG:-"latest"} BUILD_ARGS="" diff --git a/cluster/scripts/build_streamer.sh b/cluster/scripts/build_streamer.sh index 48dd5375..90d90edd 100755 --- a/cluster/scripts/build_streamer.sh +++ b/cluster/scripts/build_streamer.sh @@ -3,9 +3,9 @@ set -euo pipefail # Use environment variables provided by Tilt if available -IMAGE_NAME=${EXPECTED_IMAGE:-"fuel-streams-ws"} +IMAGE_NAME=${EXPECTED_IMAGE:-"sv-webserver"} TAG=${EXPECTED_TAG:-"latest"} -DOCKERFILE="docker/fuel-streams-ws.Dockerfile" +DOCKERFILE="docker/sv-webserver.Dockerfile" # Ensure we're using minikube's docker daemon if not already set if [ -z "${DOCKER_HOST:-}" ]; then diff --git a/crates/sv-consumer/Cargo.toml b/crates/sv-consumer/Cargo.toml index e52f84a9..54234ebc 100644 --- a/crates/sv-consumer/Cargo.toml +++ b/crates/sv-consumer/Cargo.toml @@ -25,7 +25,7 @@ fuel-streams-core = { workspace = true, features = ["test-helpers"] } fuel-streams-executors = { workspace = true, features = ["test-helpers"] } futures = { workspace = true } serde_json = { workspace = true } -sv-emitter = { workspace = true } +sv-publisher = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true } tokio-util = "0.7.13" diff --git a/crates/sv-consumer/src/main.rs b/crates/sv-consumer/src/main.rs index cbc9d78d..d1e85e2d 100644 --- a/crates/sv-consumer/src/main.rs +++ b/crates/sv-consumer/src/main.rs @@ -13,7 +13,7 @@ use fuel_streams_core::prelude::*; use fuel_streams_executors::*; use futures::StreamExt; use sv_consumer::{cli::Cli, Client}; -use sv_emitter::shutdown::ShutdownController; +use sv_publisher::shutdown::ShutdownController; use tokio_util::sync::CancellationToken; use tracing_subscriber::fmt::time; diff --git a/crates/sv-emitter/Cargo.lock b/crates/sv-emitter/Cargo.lock deleted file mode 100644 index 046abc4a..00000000 --- a/crates/sv-emitter/Cargo.lock +++ /dev/null @@ -1,7553 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "Inflector" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -dependencies = [ - "lazy_static", - "regex", -] - -[[package]] -name = "addr2line" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "adler32" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" - -[[package]] -name = "aead" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" -dependencies = [ - "crypto-common", - "generic-array", -] - -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "aes-gcm" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "subtle", -] - -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "allocator-api2" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anstream" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" - -[[package]] -name = "anstyle-parse" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" -dependencies = [ - "anstyle", - "windows-sys 0.52.0", -] - -[[package]] -name = "anyhow" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" - -[[package]] -name = "arbitrary" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" - -[[package]] -name = "arrayref" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - -[[package]] -name = "asn1-rs" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ad1373757efa0f70ec53939aabc7152e1591cb485208052993070ac8d2429d" -dependencies = [ - "asn1-rs-derive", - "asn1-rs-impl", - "displaydoc", - "nom", - "num-traits", - "rusticata-macros", - "thiserror", - "time", -] - -[[package]] -name = "asn1-rs-derive" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7378575ff571966e99a744addeff0bff98b8ada0dedf1956d59e634db95eaac1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", - "synstructure", -] - -[[package]] -name = "asn1-rs-impl" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "asn1_der" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "155a5a185e42c6b77ac7b88a15143d930a9e9727a5b7b77eed417404ab15c247" - -[[package]] -name = "async-graphql" -version = "4.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9ed522678d412d77effe47b3c82314ac36952a35e6e852093dd48287c421f80" -dependencies = [ - "async-graphql-derive", - "async-graphql-parser", - "async-graphql-value", - "async-stream", - "async-trait", - "base64 0.13.1", - "bytes", - "fnv", - "futures-util", - "http", - "indexmap 1.9.3", - "mime", - "multer", - "num-traits", - "once_cell", - "pin-project-lite", - "regex", - "serde", - "serde_json", - "serde_urlencoded", - "static_assertions", - "tempfile", - "thiserror", - "tracing", - "tracing-futures", -] - -[[package]] -name = "async-graphql-derive" -version = "4.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c121a894495d7d3fc3d4e15e0a9843e422e4d1d9e3c514d8062a1c94b35b005d" -dependencies = [ - "Inflector", - "async-graphql-parser", - "darling 0.14.4", - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 1.0.109", - "thiserror", -] - -[[package]] -name = "async-graphql-parser" -version = "4.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b6c386f398145c6180206c1869c2279f5a3d45db5be4e0266148c6ac5c6ad68" -dependencies = [ - "async-graphql-value", - "pest", - "serde", - "serde_json", -] - -[[package]] -name = "async-graphql-value" -version = "4.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a941b499fead4a3fb5392cabf42446566d18c86313f69f2deab69560394d65f" -dependencies = [ - "bytes", - "indexmap 1.9.3", - "serde", - "serde_json", -] - -[[package]] -name = "async-io" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" -dependencies = [ - "async-lock", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix", - "slab", - "tracing", - "windows-sys 0.52.0", -] - -[[package]] -name = "async-lock" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" -dependencies = [ - "event-listener", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-nats" -version = "0.35.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab8df97cb8fc4a884af29ab383e9292ea0939cfcdd7d2a17179086dc6c427e7f" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures", - "memchr", - "nkeys", - "nuid", - "once_cell", - "portable-atomic", - "rand", - "regex", - "ring 0.17.8", - "rustls-native-certs", - "rustls-pemfile 2.1.2", - "rustls-webpki 0.102.4", - "serde", - "serde_json", - "serde_nanos", - "serde_repr", - "thiserror", - "time", - "tokio", - "tokio-rustls 0.26.0", - "tracing", - "tryhard", - "url", -] - -[[package]] -name = "async-stream" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "async-trait" -version = "0.1.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "async_io_stream" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" -dependencies = [ - "futures", - "pharos", - "rustc_version", -] - -[[package]] -name = "asynchronous-codec" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4057f2c32adbb2fc158e22fb38433c8e9bbf76b75a4732c7c0cbaf695fb65568" -dependencies = [ - "bytes", - "futures-sink", - "futures-util", - "memchr", - "pin-project-lite", -] - -[[package]] -name = "asynchronous-codec" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a860072022177f903e59730004fb5dc13db9275b79bb2aef7ba8ce831956c233" -dependencies = [ - "bytes", - "futures-sink", - "futures-util", - "memchr", - "pin-project-lite", -] - -[[package]] -name = "atomic-polyfill" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" -dependencies = [ - "critical-section", -] - -[[package]] -name = "attohttpc" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9a9bf8b79a749ee0b911b91b671cc2b6c670bdbc7e3dfd537576ddc94bb2a2" -dependencies = [ - "http", - "log", - "url", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - -[[package]] -name = "auto_impl" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "axum" -version = "0.5.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acee9fd5073ab6b045a275b3e709c163dd36c90685219cb21804a147b58dba43" -dependencies = [ - "async-trait", - "axum-core", - "bitflags 1.3.2", - "bytes", - "futures-util", - "http", - "http-body", - "hyper", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tower", - "tower-http", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e5939e02c56fecd5c017c37df4238c0a839fa76b7f97acdd7efb804fd181cc" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "mime", - "tower-layer", - "tower-service", -] - -[[package]] -name = "backtrace" -version = "0.3.71" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "serde", -] - -[[package]] -name = "base-x" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" - -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - -[[package]] -name = "bech32" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" - -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bindgen" -version = "0.65.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" -dependencies = [ - "bitflags 1.3.2", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "peeking_take_while", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.66", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" -dependencies = [ - "serde", -] - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[package]] -name = "blake2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bs58" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" -dependencies = [ - "sha2 0.10.8", - "tinyvec", -] - -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - -[[package]] -name = "byte-slice-cast" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" -dependencies = [ - "serde", -] - -[[package]] -name = "bzip2-sys" -version = "0.1.11+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - -[[package]] -name = "camino" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo-platform" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo_metadata" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" -dependencies = [ - "camino", - "cargo-platform", - "semver", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "cc" -version = "1.0.98" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" -dependencies = [ - "jobserver", - "libc", - "once_cell", -] - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chacha20" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "chacha20poly1305" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" -dependencies = [ - "aead", - "chacha20", - "cipher", - "poly1305", - "zeroize", -] - -[[package]] -name = "chrono" -version = "0.4.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "num-traits", - "serde", - "windows-targets 0.52.5", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", - "zeroize", -] - -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "clap" -version = "3.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" -dependencies = [ - "atty", - "bitflags 1.3.2", - "clap_derive 3.2.25", - "clap_lex 0.2.4", - "indexmap 1.9.3", - "once_cell", - "strsim 0.10.0", - "termcolor", - "textwrap", -] - -[[package]] -name = "clap" -version = "4.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" -dependencies = [ - "clap_builder", - "clap_derive 4.5.4", -] - -[[package]] -name = "clap_builder" -version = "4.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" -dependencies = [ - "anstream", - "anstyle", - "clap_lex 0.7.0", - "strsim 0.11.1", -] - -[[package]] -name = "clap_derive" -version = "3.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" -dependencies = [ - "heck 0.4.1", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "clap_derive" -version = "4.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] - -[[package]] -name = "clap_lex" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" - -[[package]] -name = "cobs" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" - -[[package]] -name = "coins-bip32" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b6be4a5df2098cd811f3194f64ddb96c267606bffd9689ac7b0160097b01ad3" -dependencies = [ - "bs58", - "coins-core", - "digest 0.10.7", - "hmac 0.12.1", - "k256", - "serde", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "coins-bip39" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db8fba409ce3dc04f7d804074039eb68b960b0829161f8e06c95fea3f122528" -dependencies = [ - "bitvec", - "coins-bip32", - "hmac 0.12.1", - "once_cell", - "pbkdf2", - "rand", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "coins-core" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5286a0843c21f8367f7be734f89df9b822e0321d8bcce8d6e735aadff7d74979" -dependencies = [ - "base64 0.21.7", - "bech32", - "bs58", - "digest 0.10.7", - "generic-array", - "hex", - "ripemd", - "serde", - "serde_derive", - "sha2 0.10.8", - "sha3", - "thiserror", -] - -[[package]] -name = "colorchoice" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" - -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "console" -version = "0.15.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" -dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "unicode-width", - "windows-sys 0.52.0", -] - -[[package]] -name = "const-hex" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6" -dependencies = [ - "cfg-if", - "cpufeatures", - "hex", - "proptest", - "serde", -] - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "const_format" -version = "0.2.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" -dependencies = [ - "const_format_proc_macros", -] - -[[package]] -name = "const_format_proc_macros" -version = "0.2.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - -[[package]] -name = "core2" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" -dependencies = [ - "memchr", -] - -[[package]] -name = "cpp_demangle" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8227005286ec39567949b33df9896bcadfa6051bccca2488129f108ca23119" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "cpufeatures" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" -dependencies = [ - "libc", -] - -[[package]] -name = "cranelift-bforest" -version = "0.105.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496c993b62bdfbe9b4c518b8b3e1fdba9f89ef89fcccc050ab61d91dfba9fbaf" -dependencies = [ - "cranelift-entity", -] - -[[package]] -name = "cranelift-codegen" -version = "0.105.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b922abb6be41fc383f5e9da65b58d32d0d0a32c87dfe3bbbcb61a09119506c" -dependencies = [ - "bumpalo", - "cranelift-bforest", - "cranelift-codegen-meta", - "cranelift-codegen-shared", - "cranelift-control", - "cranelift-entity", - "cranelift-isle", - "gimli", - "hashbrown 0.14.5", - "log", - "regalloc2", - "smallvec", - "target-lexicon", -] - -[[package]] -name = "cranelift-codegen-meta" -version = "0.105.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634c2ed9ef8a04ca42535a3e2e7917e4b551f2f306f4df2d935a6e71e346c167" -dependencies = [ - "cranelift-codegen-shared", -] - -[[package]] -name = "cranelift-codegen-shared" -version = "0.105.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00cde1425b4da28bb0d5ff010030ea9cc9be7aded342ae099b394284f17cefce" - -[[package]] -name = "cranelift-control" -version = "0.105.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1622125c99f1864aaf44e57971770c4a918d081d4b4af0bb597bdf624660ed66" -dependencies = [ - "arbitrary", -] - -[[package]] -name = "cranelift-entity" -version = "0.105.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea97887aca1c0cbe7f8513874dc3603e9744fb1cfa78840ca8897bd2766bd35b" -dependencies = [ - "serde", - "serde_derive", -] - -[[package]] -name = "cranelift-frontend" -version = "0.105.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cdade4c14183fe41482071ed77d6a38cb95a17c7a0a05e629152e6292c4f8cb" -dependencies = [ - "cranelift-codegen", - "log", - "smallvec", - "target-lexicon", -] - -[[package]] -name = "cranelift-isle" -version = "0.105.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbbe4d3ad7bd4bf4a8d916c8460b441cf92417f5cdeacce4dd1d96eee70b18a2" - -[[package]] -name = "cranelift-native" -version = "0.105.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c46be4ed1fc8f36df4e2a442b8c30a39d8c03c1868182978f4c04ba2c25c9d4f" -dependencies = [ - "cranelift-codegen", - "libc", - "target-lexicon", -] - -[[package]] -name = "cranelift-wasm" -version = "0.105.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d4c4a785a7866da89d20df159e3c4f96a5f14feb83b1f5998cfd5fe2e74d06" -dependencies = [ - "cranelift-codegen", - "cranelift-entity", - "cranelift-frontend", - "itertools 0.10.5", - "log", - "smallvec", - "wasmparser", - "wasmtime-types", -] - -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "critical-section" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" - -[[package]] -name = "crossbeam-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array", - "rand_core", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "rand_core", - "typenum", -] - -[[package]] -name = "crypto-mac" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - -[[package]] -name = "curve25519-dalek" -version = "4.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" -dependencies = [ - "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "digest 0.10.7", - "fiat-crypto", - "platforms", - "rustc_version", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "darling" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" -dependencies = [ - "darling_core 0.14.4", - "darling_macro 0.14.4", -] - -[[package]] -name = "darling" -version = "0.20.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" -dependencies = [ - "darling_core 0.20.9", - "darling_macro 0.20.9", -] - -[[package]] -name = "darling_core" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.10.0", - "syn 1.0.109", -] - -[[package]] -name = "darling_core" -version = "0.20.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.11.1", - "syn 2.0.66", -] - -[[package]] -name = "darling_macro" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" -dependencies = [ - "darling_core 0.14.4", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "darling_macro" -version = "0.20.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" -dependencies = [ - "darling_core 0.20.9", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "data-encoding" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" - -[[package]] -name = "data-encoding-macro" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1559b6cba622276d6d63706db152618eeb15b89b3e4041446b05876e352e639" -dependencies = [ - "data-encoding", - "data-encoding-macro-internal", -] - -[[package]] -name = "data-encoding-macro-internal" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "332d754c0af53bc87c108fed664d121ecf59207ec4196041f04d6ab9002ad33f" -dependencies = [ - "data-encoding", - "syn 1.0.109", -] - -[[package]] -name = "debugid" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" -dependencies = [ - "uuid", -] - -[[package]] -name = "der" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" -dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", -] - -[[package]] -name = "der-parser" -version = "9.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" -dependencies = [ - "asn1-rs", - "displaydoc", - "nom", - "num-bigint", - "num-traits", - "rusticata-macros", -] - -[[package]] -name = "deranged" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", - "serde", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 1.0.109", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "directories-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "displaydoc" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "dotenvy" -version = "0.15.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" - -[[package]] -name = "dtoa" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" - -[[package]] -name = "dunce" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" - -[[package]] -name = "ecdsa" -version = "0.16.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" -dependencies = [ - "der", - "digest 0.10.7", - "elliptic-curve", - "rfc6979", - "signature", - "spki", -] - -[[package]] -name = "ed25519" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" -dependencies = [ - "pkcs8", - "signature", -] - -[[package]] -name = "ed25519-dalek" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" -dependencies = [ - "curve25519-dalek", - "ed25519", - "rand_core", - "serde", - "sha2 0.10.8", - "signature", - "subtle", - "zeroize", -] - -[[package]] -name = "either" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" - -[[package]] -name = "elliptic-curve" -version = "0.13.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" -dependencies = [ - "base16ct", - "crypto-bigint", - "digest 0.10.7", - "ff", - "generic-array", - "group", - "pkcs8", - "rand_core", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "embedded-io" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" - -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - -[[package]] -name = "encoding_rs" -version = "0.8.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "enr" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a3d8dc56e02f954cac8eb489772c552c473346fc34f67412bb6244fd647f7e4" -dependencies = [ - "base64 0.21.7", - "bytes", - "hex", - "k256", - "log", - "rand", - "rlp", - "serde", - "sha3", - "zeroize", -] - -[[package]] -name = "enum-as-inner" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "enum-iterator" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fd242f399be1da0a5354aa462d57b4ab2b4ee0683cc552f7c007d2d12d36e94" -dependencies = [ - "enum-iterator-derive", -] - -[[package]] -name = "enum-iterator-derive" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "ethabi" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" -dependencies = [ - "ethereum-types", - "hex", - "once_cell", - "regex", - "serde", - "serde_json", - "sha3", - "thiserror", - "uint", -] - -[[package]] -name = "ethbloom" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" -dependencies = [ - "crunchy", - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "scale-info", - "tiny-keccak", -] - -[[package]] -name = "ethereum-types" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" -dependencies = [ - "ethbloom", - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "primitive-types", - "scale-info", - "uint", -] - -[[package]] -name = "ethers-contract" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fceafa3578c836eeb874af87abacfb041f92b4da0a78a5edd042564b8ecdaaa" -dependencies = [ - "const-hex", - "ethers-contract-abigen", - "ethers-contract-derive", - "ethers-core", - "futures-util", - "once_cell", - "pin-project", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "ethers-contract-abigen" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04ba01fbc2331a38c429eb95d4a570166781f14290ef9fdb144278a90b5a739b" -dependencies = [ - "Inflector", - "const-hex", - "dunce", - "ethers-core", - "eyre", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "serde", - "serde_json", - "syn 2.0.66", - "toml 0.8.13", - "walkdir", -] - -[[package]] -name = "ethers-contract-derive" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87689dcabc0051cde10caaade298f9e9093d65f6125c14575db3fd8c669a168f" -dependencies = [ - "Inflector", - "const-hex", - "ethers-contract-abigen", - "ethers-core", - "proc-macro2", - "quote", - "serde_json", - "syn 2.0.66", -] - -[[package]] -name = "ethers-core" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82d80cc6ad30b14a48ab786523af33b37f28a8623fc06afd55324816ef18fb1f" -dependencies = [ - "arrayvec", - "bytes", - "cargo_metadata", - "chrono", - "const-hex", - "elliptic-curve", - "ethabi", - "generic-array", - "k256", - "num_enum", - "once_cell", - "open-fastrlp", - "rand", - "rlp", - "serde", - "serde_json", - "strum 0.26.2", - "syn 2.0.66", - "tempfile", - "thiserror", - "tiny-keccak", - "unicode-xid", -] - -[[package]] -name = "ethers-providers" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6434c9a33891f1effc9c75472e12666db2fa5a0fec4b29af6221680a6fe83ab2" -dependencies = [ - "async-trait", - "auto_impl", - "base64 0.21.7", - "bytes", - "const-hex", - "enr", - "ethers-core", - "futures-channel", - "futures-core", - "futures-timer", - "futures-util", - "hashers", - "http", - "instant", - "jsonwebtoken", - "once_cell", - "pin-project", - "reqwest", - "serde", - "serde_json", - "thiserror", - "tokio", - "tokio-tungstenite", - "tracing", - "tracing-futures", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "ws_stream_wasm", -] - -[[package]] -name = "ethnum" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" - -[[package]] -name = "event-listener" -version = "4.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" -dependencies = [ - "event-listener", - "pin-project-lite", -] - -[[package]] -name = "eyre" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" -dependencies = [ - "indenter", - "once_cell", -] - -[[package]] -name = "fallible-iterator" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" - -[[package]] -name = "fastrand" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" - -[[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "rand_core", - "subtle", -] - -[[package]] -name = "fiat-crypto" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" - -[[package]] -name = "findshlibs" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b9e59cd0f7e0806cca4be089683ecb6434e602038df21fe6bf6711b2f07f64" -dependencies = [ - "cc", - "lazy_static", - "libc", - "winapi", -] - -[[package]] -name = "fixed-hash" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" -dependencies = [ - "byteorder", - "rand", - "rustc-hex", - "static_assertions", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "fuel-asm" -version = "0.49.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42df651415e443094f86102473b7f9fa23633ab6c3c98dd3f713adde251acf0f" -dependencies = [ - "bitflags 2.5.0", - "fuel-types", - "serde", - "strum 0.24.1", -] - -[[package]] -name = "fuel-core" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b030e12851d70598e12722886b899e28884d168367fc20d9a809951dd599004" -dependencies = [ - "anyhow", - "async-graphql", - "async-trait", - "axum", - "clap 4.5.4", - "derive_more", - "enum-iterator", - "fuel-core-chain-config", - "fuel-core-consensus-module", - "fuel-core-database", - "fuel-core-executor", - "fuel-core-importer", - "fuel-core-metrics", - "fuel-core-p2p", - "fuel-core-poa", - "fuel-core-producer", - "fuel-core-relayer", - "fuel-core-services", - "fuel-core-storage", - "fuel-core-sync", - "fuel-core-txpool", - "fuel-core-types", - "fuel-core-upgradable-executor", - "futures", - "hex", - "hyper", - "indicatif", - "itertools 0.12.1", - "num_cpus", - "rand", - "rocksdb", - "serde", - "serde_json", - "strum 0.25.0", - "strum_macros 0.25.3", - "tempfile", - "thiserror", - "tokio", - "tokio-stream", - "tokio-util", - "tower-http", - "tracing", - "uuid", -] - -[[package]] -name = "fuel-core-bin" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f5ff2b6ce36b11e79f338b22fe436962d8d587b60a8d751c6bef2b7cb5d89bb" -dependencies = [ - "anyhow", - "async-trait", - "clap 4.5.4", - "const_format", - "dirs", - "dotenvy", - "fuel-core", - "fuel-core-chain-config", - "fuel-core-types", - "hex", - "humantime", - "pyroscope", - "pyroscope_pprofrs", - "serde_json", - "tikv-jemallocator", - "tokio", - "tokio-util", - "tracing", - "tracing-subscriber", - "url", -] - -[[package]] -name = "fuel-core-chain-config" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d202fe1dfeb98882bdc5a0206a58e469d76fd09d952c4050bb979102bd690398" -dependencies = [ - "anyhow", - "bech32", - "derivative", - "fuel-core-storage", - "fuel-core-types", - "itertools 0.12.1", - "postcard", - "serde", - "serde_json", - "serde_with", - "tracing", -] - -[[package]] -name = "fuel-core-consensus-module" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f99179c08972efffe7628f0ff8d59028218b126347a6f9eba86f71e20966eeb" -dependencies = [ - "anyhow", - "fuel-core-chain-config", - "fuel-core-poa", - "fuel-core-storage", - "fuel-core-types", -] - -[[package]] -name = "fuel-core-database" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5b1fd08a72609ebf0c8106359a37a4b205055be15e9f4fc30a4c0b5f0644c6b" -dependencies = [ - "anyhow", - "derive_more", - "fuel-core-storage", - "fuel-core-types", -] - -[[package]] -name = "fuel-core-executor" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f98d89798007bc781d56e02681144683f5c645ee0725e7717e38694e8e5e31d" -dependencies = [ - "anyhow", - "fuel-core-storage", - "fuel-core-types", - "hex", - "parking_lot", - "serde", - "tracing", -] - -[[package]] -name = "fuel-core-importer" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51837a53f2d8b78a701aee61b99c7f1873f23e864f01f4b4d0644a06e1f7c41" -dependencies = [ - "anyhow", - "derive_more", - "fuel-core-metrics", - "fuel-core-storage", - "fuel-core-types", - "tokio", - "tokio-rayon", - "tracing", -] - -[[package]] -name = "fuel-core-metrics" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bacc62bc4fec2fe6a818a1a7145b892bd486d69266190ca8dd31a036a3a327b7" -dependencies = [ - "axum", - "once_cell", - "pin-project-lite", - "prometheus-client", - "regex", - "tracing", -] - -[[package]] -name = "fuel-streams-publisher" -version = "0.26.0" -dependencies = [ - "anyhow", - "async-nats", - "clap 4.5.4", - "fuel-core", - "fuel-core-bin", - "fuel-core-services", - "fuel-core-types", - "serde_json", - "tokio", - "tracing", -] - -[[package]] -name = "fuel-core-p2p" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6496068f0f5736f9e51bba8f8bb04cb83f68df2f6142e410fe62854b47621b3" -dependencies = [ - "anyhow", - "async-trait", - "fuel-core-chain-config", - "fuel-core-metrics", - "fuel-core-services", - "fuel-core-storage", - "fuel-core-types", - "futures", - "hex", - "ip_network", - "libp2p", - "libp2p-mplex", - "postcard", - "prometheus-client", - "quick-protobuf", - "quick-protobuf-codec", - "rand", - "serde", - "serde_with", - "sha2 0.10.8", - "thiserror", - "tokio", - "tracing", - "void", -] - -[[package]] -name = "fuel-core-poa" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68d189ecd635688ddc896b44c8497b29c04bb4a3719a24eea0ca9691a6f76d5e" -dependencies = [ - "anyhow", - "async-trait", - "fuel-core-chain-config", - "fuel-core-services", - "fuel-core-storage", - "fuel-core-types", - "tokio", - "tokio-stream", - "tracing", -] - -[[package]] -name = "fuel-core-producer" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d2901a7ba2c0e724bbb88a3111fdb9844f5faf9f0bd4005944f61f093730b4d" -dependencies = [ - "anyhow", - "async-trait", - "derive_more", - "fuel-core-storage", - "fuel-core-types", - "tokio", - "tokio-rayon", - "tracing", -] - -[[package]] -name = "fuel-core-relayer" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da1aa686ec4a05b77f4c4dfae68e6f17701b5bc21a49a8a505c6d9dc6dcf9183" -dependencies = [ - "anyhow", - "async-trait", - "enum-iterator", - "ethers-contract", - "ethers-core", - "ethers-providers", - "fuel-core-services", - "fuel-core-storage", - "fuel-core-types", - "futures", - "once_cell", - "strum 0.25.0", - "strum_macros 0.25.3", - "tokio", - "tracing", - "url", -] - -[[package]] -name = "fuel-core-services" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2ab4d3931b8cafdb2e69fe8ca97918a168d74c73c070481ca0e552cc37bb93" -dependencies = [ - "anyhow", - "async-trait", - "fuel-core-metrics", - "futures", - "parking_lot", - "tokio", - "tracing", -] - -[[package]] -name = "fuel-core-storage" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e039c1c6ebef314c74c34728e1f2199dcf9ede041d6f5c6e11479517c8f4d320" -dependencies = [ - "anyhow", - "derive_more", - "enum-iterator", - "fuel-core-types", - "fuel-vm", - "impl-tools", - "itertools 0.12.1", - "num_enum", - "paste", - "postcard", - "primitive-types", - "serde", - "strum 0.25.0", - "strum_macros 0.25.3", -] - -[[package]] -name = "fuel-core-sync" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7059ee4c3dbf1e9340d7cd88eccf2e10c631306d8038ab20160e6434deb79c1b" -dependencies = [ - "anyhow", - "async-trait", - "fuel-core-services", - "fuel-core-types", - "futures", - "rand", - "tokio", - "tracing", -] - -[[package]] -name = "fuel-core-txpool" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "985684e2d67d5018e9227a4f9ed79cac02b23b207e457ee95833ab047769c2ac" -dependencies = [ - "anyhow", - "async-trait", - "fuel-core-metrics", - "fuel-core-services", - "fuel-core-storage", - "fuel-core-types", - "futures", - "parking_lot", - "tokio", - "tokio-rayon", - "tokio-stream", - "tracing", -] - -[[package]] -name = "fuel-core-types" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf038dd8df8d3aa665a13295c9ef888ba8118600cccdf8fb4587410e0e102fdf" -dependencies = [ - "anyhow", - "bs58", - "derivative", - "derive_more", - "fuel-vm", - "secrecy", - "serde", - "tai64", - "thiserror", - "zeroize", -] - -[[package]] -name = "fuel-core-upgradable-executor" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc54c84a7dc13f76930761ebca391b167caa096dc2bdb2413b5a2400bf65f99d" -dependencies = [ - "anyhow", - "fuel-core-executor", - "fuel-core-storage", - "fuel-core-types", - "fuel-core-wasm-executor", - "parking_lot", - "postcard", - "tracing", - "wasmtime", -] - -[[package]] -name = "fuel-core-wasm-executor" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a201e4fa5f94efb36cda172947875483d90a88b060cb9c6f9a496313d171aae8" -dependencies = [ - "anyhow", - "fuel-core-executor", - "fuel-core-storage", - "fuel-core-types", - "postcard", - "serde", -] - -[[package]] -name = "fuel-crypto" -version = "0.49.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71cef93970fb8a26d3a683ae211833c6bbf391066887f501bd5859f29992b59a" -dependencies = [ - "coins-bip32", - "coins-bip39", - "ecdsa", - "ed25519-dalek", - "fuel-types", - "k256", - "lazy_static", - "p256", - "rand", - "secp256k1", - "serde", - "sha2 0.10.8", - "zeroize", -] - -[[package]] -name = "fuel-derive" -version = "0.49.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b85e8e508b26d088262075fcfe9921b7009c931fef1cc55fe1dafb116c99884" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", - "synstructure", -] - -[[package]] -name = "fuel-merkle" -version = "0.49.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5198b4eab5a19b0034971da88199dae7dd61806ebd8df366d6af1f17cda2e151" -dependencies = [ - "derive_more", - "digest 0.10.7", - "fuel-storage", - "hashbrown 0.13.2", - "hex", - "serde", - "sha2 0.10.8", -] - -[[package]] -name = "fuel-storage" -version = "0.49.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa738e9c244f3f312af09faef108ec9a285f02afcefbc579c19c242cea742dd0" - -[[package]] -name = "fuel-tx" -version = "0.49.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e4b4ea79ffe711af7bbf363b25f383fc6e481e652cf55a5ef8b5a458fcf4ef9" -dependencies = [ - "bitflags 2.5.0", - "derivative", - "derive_more", - "fuel-asm", - "fuel-crypto", - "fuel-merkle", - "fuel-types", - "hashbrown 0.14.5", - "itertools 0.10.5", - "postcard", - "rand", - "serde", - "serde_json", - "strum 0.24.1", - "strum_macros 0.24.3", -] - -[[package]] -name = "fuel-types" -version = "0.49.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455cf5275d96f6907e81ed1825c4e6a9dd79f7c1c37a4e15134562f83024c7e7" -dependencies = [ - "fuel-derive", - "hex", - "serde", -] - -[[package]] -name = "fuel-vm" -version = "0.49.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8811f949db8ce61cc68dcf81644047df4ee23be55879efcfe9f1aa5adc378965" -dependencies = [ - "async-trait", - "backtrace", - "bitflags 2.5.0", - "derivative", - "derive_more", - "ethnum", - "fuel-asm", - "fuel-crypto", - "fuel-merkle", - "fuel-storage", - "fuel-tx", - "fuel-types", - "hashbrown 0.14.5", - "itertools 0.10.5", - "libm", - "paste", - "percent-encoding", - "primitive-types", - "serde", - "serde_with", - "sha3", - "static_assertions", - "strum 0.24.1", - "tai64", -] - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-bounded" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e2774cc104e198ef3d3e1ff4ab40f86fa3245d6cb6a3a46174f21463cee173" -dependencies = [ - "futures-timer", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", - "num_cpus", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-lite" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" -dependencies = [ - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "futures-rustls" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35bd3cf68c183738046838e300353e4716c674dc5e56890de4826801a6622a28" -dependencies = [ - "futures-io", - "rustls 0.21.12", -] - -[[package]] -name = "futures-rustls" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" -dependencies = [ - "futures-io", - "rustls 0.23.8", - "rustls-pki-types", -] - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-ticker" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9763058047f713632a52e916cc7f6a4b3fc6e9fc1ff8c5b1dc49e5a89041682e" -dependencies = [ - "futures", - "futures-timer", - "instant", -] - -[[package]] -name = "futures-timer" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" -dependencies = [ - "gloo-timers", - "send_wrapper 0.4.0", -] - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "ghash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" -dependencies = [ - "opaque-debug", - "polyval", -] - -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" -dependencies = [ - "fallible-iterator", - "indexmap 2.2.6", - "stable_deref_trait", -] - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "rand_core", - "subtle", -] - -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 2.2.6", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hash32" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" -dependencies = [ - "byteorder", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", - "allocator-api2", - "serde", -] - -[[package]] -name = "hashers" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2bca93b15ea5a746f220e56587f71e73c6165eab783df9e26590069953e3c30" -dependencies = [ - "fxhash", -] - -[[package]] -name = "heapless" -version = "0.7.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" -dependencies = [ - "atomic-polyfill", - "hash32", - "rustc_version", - "serde", - "spin 0.9.8", - "stable_deref_trait", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[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.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -dependencies = [ - "serde", -] - -[[package]] -name = "hex_fmt" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" - -[[package]] -name = "hickory-proto" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07698b8420e2f0d6447a436ba999ec85d8fbf2a398bbd737b82cac4a2e96e512" -dependencies = [ - "async-trait", - "cfg-if", - "data-encoding", - "enum-as-inner", - "futures-channel", - "futures-io", - "futures-util", - "idna 0.4.0", - "ipnet", - "once_cell", - "rand", - "socket2", - "thiserror", - "tinyvec", - "tokio", - "tracing", - "url", -] - -[[package]] -name = "hickory-resolver" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28757f23aa75c98f254cf0405e6d8c25b831b32921b050a66692427679b1f243" -dependencies = [ - "cfg-if", - "futures-util", - "hickory-proto", - "ipconfig", - "lru-cache", - "once_cell", - "parking_lot", - "rand", - "resolv-conf", - "smallvec", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "hkdf" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac 0.12.1", -] - -[[package]] -name = "hmac" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" -dependencies = [ - "crypto-mac", - "digest 0.9.0", -] - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "hmac-drbg" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" -dependencies = [ - "digest 0.9.0", - "generic-array", - "hmac 0.8.1", -] - -[[package]] -name = "hostname" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -dependencies = [ - "libc", - "match_cfg", - "winapi", -] - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "http-range-header" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" - -[[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.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[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.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" -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-rustls" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" -dependencies = [ - "futures-util", - "http", - "hyper", - "rustls 0.21.12", - "tokio", - "tokio-rustls 0.24.1", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core 0.52.0", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "if-addrs" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cabb0019d51a643781ff15c9c8a3e5dedc365c47211270f4e8f82812fedd8f0a" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "if-watch" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6b0422c86d7ce0e97169cc42e04ae643caf278874a7a3c87b8150a220dc7e1e" -dependencies = [ - "async-io", - "core-foundation", - "fnv", - "futures", - "if-addrs", - "ipnet", - "log", - "rtnetlink", - "system-configuration", - "tokio", - "windows", -] - -[[package]] -name = "igd-next" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "064d90fec10d541084e7b39ead8875a5a80d9114a2b18791565253bae25f49e4" -dependencies = [ - "async-trait", - "attohttpc", - "bytes", - "futures", - "http", - "hyper", - "log", - "rand", - "tokio", - "url", - "xmltree", -] - -[[package]] -name = "impl-codec" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" -dependencies = [ - "parity-scale-codec", -] - -[[package]] -name = "impl-rlp" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" -dependencies = [ - "rlp", -] - -[[package]] -name = "impl-serde" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" -dependencies = [ - "serde", -] - -[[package]] -name = "impl-tools" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82c305b1081f1a99fda262883c788e50ab57d36c00830bdd7e0a82894ad965c" -dependencies = [ - "autocfg", - "impl-tools-lib", - "proc-macro-error", - "syn 2.0.66", -] - -[[package]] -name = "impl-tools-lib" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85d3946d886eaab0702fa0c6585adcced581513223fa9df7ccfabbd9fa331a88" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "indenter" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - -[[package]] -name = "indexmap" -version = "2.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" -dependencies = [ - "equivalent", - "hashbrown 0.14.5", - "serde", -] - -[[package]] -name = "indicatif" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" -dependencies = [ - "console", - "instant", - "number_prefix", - "portable-atomic", - "unicode-width", -] - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "ip_network" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1" - -[[package]] -name = "ipconfig" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" -dependencies = [ - "socket2", - "widestring", - "windows-sys 0.48.0", - "winreg", -] - -[[package]] -name = "ipnet" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "jobserver" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "json" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" - -[[package]] -name = "jsonwebtoken" -version = "8.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" -dependencies = [ - "base64 0.21.7", - "pem 1.1.1", - "ring 0.16.20", - "serde", - "serde_json", - "simple_asn1", -] - -[[package]] -name = "k256" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "once_cell", - "sha2 0.10.8", - "signature", -] - -[[package]] -name = "keccak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "leb128" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" - -[[package]] -name = "libc" -version = "0.2.155" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" - -[[package]] -name = "libflate" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ff4ae71b685bbad2f2f391fe74f6b7659a34871c08b210fdc039e43bee07d18" -dependencies = [ - "adler32", - "crc32fast", - "libflate_lz77", -] - -[[package]] -name = "libflate_lz77" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a52d3a8bfc85f250440e4424db7d857e241a3aebbbe301f3eb606ab15c39acbf" -dependencies = [ - "rle-decode-fast", -] - -[[package]] -name = "libloading" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" -dependencies = [ - "cfg-if", - "windows-targets 0.52.5", -] - -[[package]] -name = "libm" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" - -[[package]] -name = "libp2p" -version = "0.53.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681fb3f183edfbedd7a57d32ebe5dcdc0b9f94061185acf3c30249349cc6fc99" -dependencies = [ - "bytes", - "either", - "futures", - "futures-timer", - "getrandom", - "instant", - "libp2p-allow-block-list", - "libp2p-connection-limits", - "libp2p-core", - "libp2p-dns", - "libp2p-gossipsub", - "libp2p-identify", - "libp2p-identity", - "libp2p-kad", - "libp2p-mdns", - "libp2p-metrics", - "libp2p-noise", - "libp2p-quic", - "libp2p-request-response", - "libp2p-swarm", - "libp2p-tcp", - "libp2p-upnp", - "libp2p-websocket", - "libp2p-yamux", - "multiaddr", - "pin-project", - "rw-stream-sink", - "thiserror", -] - -[[package]] -name = "libp2p-allow-block-list" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "107b238b794cb83ab53b74ad5dcf7cca3200899b72fe662840cfb52f5b0a32e6" -dependencies = [ - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", - "void", -] - -[[package]] -name = "libp2p-connection-limits" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7cd50a78ccfada14de94cbacd3ce4b0138157f376870f13d3a8422cd075b4fd" -dependencies = [ - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", - "void", -] - -[[package]] -name = "libp2p-core" -version = "0.41.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8130a8269e65a2554d55131c770bdf4bcd94d2b8d4efb24ca23699be65066c05" -dependencies = [ - "either", - "fnv", - "futures", - "futures-timer", - "instant", - "libp2p-identity", - "multiaddr", - "multihash", - "multistream-select", - "once_cell", - "parking_lot", - "pin-project", - "quick-protobuf", - "rand", - "rw-stream-sink", - "smallvec", - "thiserror", - "tracing", - "unsigned-varint 0.8.0", - "void", -] - -[[package]] -name = "libp2p-dns" -version = "0.41.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d17cbcf7160ff35c3e8e560de4a068fe9d6cb777ea72840e48eb76ff9576c4b6" -dependencies = [ - "async-trait", - "futures", - "hickory-resolver", - "libp2p-core", - "libp2p-identity", - "parking_lot", - "smallvec", - "tracing", -] - -[[package]] -name = "libp2p-gossipsub" -version = "0.46.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d665144a616dadebdc5fff186b1233488cdcd8bfb1223218ff084b6d052c94f7" -dependencies = [ - "asynchronous-codec 0.7.0", - "base64 0.21.7", - "byteorder", - "bytes", - "either", - "fnv", - "futures", - "futures-ticker", - "getrandom", - "hex_fmt", - "instant", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", - "prometheus-client", - "quick-protobuf", - "quick-protobuf-codec", - "rand", - "regex", - "sha2 0.10.8", - "smallvec", - "tracing", - "void", -] - -[[package]] -name = "libp2p-identify" -version = "0.44.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5d635ebea5ca0c3c3e77d414ae9b67eccf2a822be06091b9c1a0d13029a1e2f" -dependencies = [ - "asynchronous-codec 0.7.0", - "either", - "futures", - "futures-bounded", - "futures-timer", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", - "lru", - "quick-protobuf", - "quick-protobuf-codec", - "smallvec", - "thiserror", - "tracing", - "void", -] - -[[package]] -name = "libp2p-identity" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "999ec70441b2fb35355076726a6bc466c932e9bdc66f6a11c6c0aa17c7ab9be0" -dependencies = [ - "asn1_der", - "bs58", - "ed25519-dalek", - "hkdf", - "libsecp256k1", - "multihash", - "quick-protobuf", - "rand", - "sha2 0.10.8", - "thiserror", - "tracing", - "zeroize", -] - -[[package]] -name = "libp2p-kad" -version = "0.45.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc5767727d062c4eac74dd812c998f0e488008e82cce9c33b463d38423f9ad2" -dependencies = [ - "arrayvec", - "asynchronous-codec 0.7.0", - "bytes", - "either", - "fnv", - "futures", - "futures-bounded", - "futures-timer", - "instant", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", - "quick-protobuf", - "quick-protobuf-codec", - "rand", - "sha2 0.10.8", - "smallvec", - "thiserror", - "tracing", - "uint", - "void", -] - -[[package]] -name = "libp2p-mdns" -version = "0.45.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49007d9a339b3e1d7eeebc4d67c05dbf23d300b7d091193ec2d3f26802d7faf2" -dependencies = [ - "data-encoding", - "futures", - "hickory-proto", - "if-watch", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", - "rand", - "smallvec", - "socket2", - "tokio", - "tracing", - "void", -] - -[[package]] -name = "libp2p-metrics" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdac91ae4f291046a3b2660c039a2830c931f84df2ee227989af92f7692d3357" -dependencies = [ - "futures", - "instant", - "libp2p-core", - "libp2p-gossipsub", - "libp2p-identify", - "libp2p-identity", - "libp2p-kad", - "libp2p-swarm", - "pin-project", - "prometheus-client", -] - -[[package]] -name = "libp2p-mplex" -version = "0.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e895765e27e30217b25f7cb7ac4686dad1ff80bf2fdeffd1d898566900a924" -dependencies = [ - "asynchronous-codec 0.6.2", - "bytes", - "futures", - "libp2p-core", - "libp2p-identity", - "nohash-hasher", - "parking_lot", - "rand", - "smallvec", - "tracing", - "unsigned-varint 0.7.2", -] - -[[package]] -name = "libp2p-noise" -version = "0.44.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecd0545ce077f6ea5434bcb76e8d0fe942693b4380aaad0d34a358c2bd05793" -dependencies = [ - "asynchronous-codec 0.7.0", - "bytes", - "curve25519-dalek", - "futures", - "libp2p-core", - "libp2p-identity", - "multiaddr", - "multihash", - "once_cell", - "quick-protobuf", - "rand", - "sha2 0.10.8", - "snow", - "static_assertions", - "thiserror", - "tracing", - "x25519-dalek", - "zeroize", -] - -[[package]] -name = "libp2p-quic" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c67296ad4e092e23f92aea3d2bdb6f24eab79c0929ed816dfb460ea2f4567d2b" -dependencies = [ - "bytes", - "futures", - "futures-timer", - "if-watch", - "libp2p-core", - "libp2p-identity", - "libp2p-tls", - "parking_lot", - "quinn", - "rand", - "ring 0.17.8", - "rustls 0.23.8", - "socket2", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "libp2p-request-response" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6946e5456240b3173187cc37a17cb40c3cd1f7138c76e2c773e0d792a42a8de1" -dependencies = [ - "async-trait", - "futures", - "futures-bounded", - "futures-timer", - "instant", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", - "rand", - "smallvec", - "tracing", - "void", -] - -[[package]] -name = "libp2p-swarm" -version = "0.44.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80cae6cb75f89dbca53862f9ebe0b9f463aa7b302762fcfaafb9e51dcc9b0f7e" -dependencies = [ - "either", - "fnv", - "futures", - "futures-timer", - "instant", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm-derive", - "lru", - "multistream-select", - "once_cell", - "rand", - "smallvec", - "tokio", - "tracing", - "void", -] - -[[package]] -name = "libp2p-swarm-derive" -version = "0.34.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5daceb9dd908417b6dfcfe8e94098bc4aac54500c282e78120b885dadc09b999" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "libp2p-tcp" -version = "0.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2460fc2748919adff99ecbc1aab296e4579e41f374fb164149bd2c9e529d4c" -dependencies = [ - "futures", - "futures-timer", - "if-watch", - "libc", - "libp2p-core", - "libp2p-identity", - "socket2", - "tokio", - "tracing", -] - -[[package]] -name = "libp2p-tls" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "251b17aebdd29df7e8f80e4d94b782fae42e934c49086e1a81ba23b60a8314f2" -dependencies = [ - "futures", - "futures-rustls 0.26.0", - "libp2p-core", - "libp2p-identity", - "rcgen", - "ring 0.17.8", - "rustls 0.23.8", - "rustls-webpki 0.101.7", - "thiserror", - "x509-parser", - "yasna", -] - -[[package]] -name = "libp2p-upnp" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccf04b0e3ff3de52d07d5fd6c3b061d0e7f908ffc683c32d9638caedce86fc8" -dependencies = [ - "futures", - "futures-timer", - "igd-next", - "libp2p-core", - "libp2p-swarm", - "tokio", - "tracing", - "void", -] - -[[package]] -name = "libp2p-websocket" -version = "0.43.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4846d51afd08180e164291c3754ba30dd4fbac6fac65571be56403c16431a5e" -dependencies = [ - "either", - "futures", - "futures-rustls 0.24.0", - "libp2p-core", - "libp2p-identity", - "parking_lot", - "pin-project-lite", - "rw-stream-sink", - "soketto", - "tracing", - "url", - "webpki-roots", -] - -[[package]] -name = "libp2p-yamux" -version = "0.45.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200cbe50349a44760927d50b431d77bed79b9c0a3959de1af8d24a63434b71e5" -dependencies = [ - "either", - "futures", - "libp2p-core", - "thiserror", - "tracing", - "yamux 0.12.1", - "yamux 0.13.2", -] - -[[package]] -name = "libredox" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" -dependencies = [ - "bitflags 2.5.0", - "libc", -] - -[[package]] -name = "librocksdb-sys" -version = "0.11.0+8.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e" -dependencies = [ - "bindgen", - "bzip2-sys", - "cc", - "glob", - "libc", - "libz-sys", - "lz4-sys", -] - -[[package]] -name = "libsecp256k1" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" -dependencies = [ - "arrayref", - "base64 0.13.1", - "digest 0.9.0", - "hmac-drbg", - "libsecp256k1-core", - "libsecp256k1-gen-ecmult", - "libsecp256k1-gen-genmult", - "rand", - "serde", - "sha2 0.9.9", - "typenum", -] - -[[package]] -name = "libsecp256k1-core" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" -dependencies = [ - "crunchy", - "digest 0.9.0", - "subtle", -] - -[[package]] -name = "libsecp256k1-gen-ecmult" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" -dependencies = [ - "libsecp256k1-core", -] - -[[package]] -name = "libsecp256k1-gen-genmult" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" -dependencies = [ - "libsecp256k1-core", -] - -[[package]] -name = "libz-sys" -version = "1.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - -[[package]] -name = "lock_api" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" - -[[package]] -name = "lru" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" -dependencies = [ - "hashbrown 0.14.5", -] - -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "lz4-sys" -version = "1.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "mach" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" -dependencies = [ - "libc", -] - -[[package]] -name = "match_cfg" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - -[[package]] -name = "matchit" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" - -[[package]] -name = "memchr" -version = "2.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" - -[[package]] -name = "memfd" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" -dependencies = [ - "rustix", -] - -[[package]] -name = "memmap2" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" -dependencies = [ - "libc", -] - -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.48.0", -] - -[[package]] -name = "multer" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" -dependencies = [ - "bytes", - "encoding_rs", - "futures-util", - "http", - "httparse", - "log", - "memchr", - "mime", - "spin 0.9.8", - "version_check", -] - -[[package]] -name = "multiaddr" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b852bc02a2da5feed68cd14fa50d0774b92790a5bdbfa932a813926c8472070" -dependencies = [ - "arrayref", - "byteorder", - "data-encoding", - "libp2p-identity", - "multibase", - "multihash", - "percent-encoding", - "serde", - "static_assertions", - "unsigned-varint 0.7.2", - "url", -] - -[[package]] -name = "multibase" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" -dependencies = [ - "base-x", - "data-encoding", - "data-encoding-macro", -] - -[[package]] -name = "multihash" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076d548d76a0e2a0d4ab471d0b1c36c577786dfc4471242035d97a12a735c492" -dependencies = [ - "core2", - "unsigned-varint 0.7.2", -] - -[[package]] -name = "multistream-select" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0df8e5eec2298a62b326ee4f0d7fe1a6b90a09dfcf9df37b38f947a8c42f19" -dependencies = [ - "bytes", - "futures", - "log", - "pin-project", - "smallvec", - "unsigned-varint 0.7.2", -] - -[[package]] -name = "names" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bddcd3bf5144b6392de80e04c347cd7fab2508f6df16a85fc496ecd5cec39bc" -dependencies = [ - "clap 3.2.25", - "rand", -] - -[[package]] -name = "netlink-packet-core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345b8ab5bd4e71a2986663e88c56856699d060e78e152e6e9d7966fcd5491297" -dependencies = [ - "anyhow", - "byteorder", - "libc", - "netlink-packet-utils", -] - -[[package]] -name = "netlink-packet-route" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9ea4302b9759a7a88242299225ea3688e63c85ea136371bb6cf94fd674efaab" -dependencies = [ - "anyhow", - "bitflags 1.3.2", - "byteorder", - "libc", - "netlink-packet-core", - "netlink-packet-utils", -] - -[[package]] -name = "netlink-packet-utils" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ede8a08c71ad5a95cdd0e4e52facd37190977039a4704eb82a283f713747d34" -dependencies = [ - "anyhow", - "byteorder", - "paste", - "thiserror", -] - -[[package]] -name = "netlink-proto" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65b4b14489ab424703c092062176d52ba55485a89c076b4f9db05092b7223aa6" -dependencies = [ - "bytes", - "futures", - "log", - "netlink-packet-core", - "netlink-sys", - "thiserror", - "tokio", -] - -[[package]] -name = "netlink-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416060d346fbaf1f23f9512963e3e878f1a78e707cb699ba9215761754244307" -dependencies = [ - "bytes", - "futures", - "libc", - "log", - "tokio", -] - -[[package]] -name = "nix" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" -dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "libc", -] - -[[package]] -name = "nix" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" -dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "libc", -] - -[[package]] -name = "nkeys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc522a19199a0795776406619aa6aa78e1e55690fbeb3181b8db5265fd0e89ce" -dependencies = [ - "data-encoding", - "ed25519", - "ed25519-dalek", - "getrandom", - "log", - "rand", - "signatory", -] - -[[package]] -name = "nohash-hasher" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - -[[package]] -name = "nuid" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc895af95856f929163a0aa20c26a78d26bfdc839f51b9d5aa7a5b79e52b7e83" -dependencies = [ - "rand", -] - -[[package]] -name = "num-bigint" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.9", - "libc", -] - -[[package]] -name = "num_enum" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" -dependencies = [ - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" -dependencies = [ - "proc-macro-crate 3.1.0", - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "number_prefix" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" - -[[package]] -name = "object" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "crc32fast", - "hashbrown 0.14.5", - "indexmap 2.2.6", - "memchr", -] - -[[package]] -name = "oid-registry" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c958dd45046245b9c3c2547369bb634eb461670b2e7e0de552905801a648d1d" -dependencies = [ - "asn1-rs", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - -[[package]] -name = "open-fastrlp" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" -dependencies = [ - "arrayvec", - "auto_impl", - "bytes", - "ethereum-types", - "open-fastrlp-derive", -] - -[[package]] -name = "open-fastrlp-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" -dependencies = [ - "bytes", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "os_str_bytes" -version = "6.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "p256" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" -dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", - "sha2 0.10.8", -] - -[[package]] -name = "parity-scale-codec" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" -dependencies = [ - "arrayvec", - "bitvec", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive", - "serde", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" -dependencies = [ - "proc-macro-crate 3.1.0", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "parking" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.52.5", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "pbkdf2" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" -dependencies = [ - "digest 0.10.7", - "hmac 0.12.1", -] - -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - -[[package]] -name = "pem" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" -dependencies = [ - "base64 0.13.1", -] - -[[package]] -name = "pem" -version = "3.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" -dependencies = [ - "base64 0.22.1", - "serde", -] - -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pest" -version = "2.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" -dependencies = [ - "memchr", - "thiserror", - "ucd-trie", -] - -[[package]] -name = "pharos" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" -dependencies = [ - "futures", - "rustc_version", -] - -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "pkg-config" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" - -[[package]] -name = "platforms" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" - -[[package]] -name = "polling" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645493cf344456ef24219d02a768cf1fb92ddf8c92161679ae3d91b91a637be3" -dependencies = [ - "cfg-if", - "concurrent-queue", - "hermit-abi 0.3.9", - "pin-project-lite", - "rustix", - "tracing", - "windows-sys 0.52.0", -] - -[[package]] -name = "poly1305" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" -dependencies = [ - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "polyval" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" -dependencies = [ - "cfg-if", - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "portable-atomic" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" - -[[package]] -name = "postcard" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" -dependencies = [ - "cobs", - "embedded-io", - "heapless", - "serde", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "pprof" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978385d59daf9269189d052ca8a84c1acfd0715c0599a5d5188d4acc078ca46a" -dependencies = [ - "backtrace", - "cfg-if", - "findshlibs", - "libc", - "log", - "nix 0.26.4", - "once_cell", - "parking_lot", - "smallvec", - "symbolic-demangle", - "tempfile", - "thiserror", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "prettyplease" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" -dependencies = [ - "proc-macro2", - "syn 2.0.66", -] - -[[package]] -name = "primeorder" -version = "0.13.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" -dependencies = [ - "elliptic-curve", -] - -[[package]] -name = "primitive-types" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" -dependencies = [ - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "scale-info", - "uint", -] - -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - -[[package]] -name = "proc-macro-crate" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" -dependencies = [ - "toml_edit 0.21.1", -] - -[[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 1.0.109", - "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.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prometheus-client" -version = "0.22.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ca959da22a332509f2a73ae9e5f23f9dcfc31fd3a54d71f159495bd5909baa" -dependencies = [ - "dtoa", - "itoa", - "parking_lot", - "prometheus-client-derive-encode", -] - -[[package]] -name = "prometheus-client-derive-encode" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "proptest" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" -dependencies = [ - "bitflags 2.5.0", - "lazy_static", - "num-traits", - "rand", - "rand_chacha", - "rand_xorshift", - "regex-syntax 0.8.3", - "unarray", -] - -[[package]] -name = "prost" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-derive" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" -dependencies = [ - "anyhow", - "itertools 0.10.5", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "psm" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" -dependencies = [ - "cc", -] - -[[package]] -name = "pyroscope" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac8a53ce01af1087eaeee6ce7c4fbf50ea4040ab1825c0115c4bafa039644ba9" -dependencies = [ - "json", - "libc", - "libflate", - "log", - "names", - "prost", - "reqwest", - "thiserror", - "url", - "winapi", -] - -[[package]] -name = "pyroscope_pprofrs" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f010b2a981a7f8449a650f25f309e520b5206ea2d89512dcb146aaa5518ff4" -dependencies = [ - "log", - "pprof", - "pyroscope", - "thiserror", -] - -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - -[[package]] -name = "quick-protobuf" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" -dependencies = [ - "byteorder", -] - -[[package]] -name = "quick-protobuf-codec" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15a0580ab32b169745d7a39db2ba969226ca16738931be152a3209b409de2474" -dependencies = [ - "asynchronous-codec 0.7.0", - "bytes", - "quick-protobuf", - "thiserror", - "unsigned-varint 0.8.0", -] - -[[package]] -name = "quinn" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904e3d3ba178131798c6d9375db2b13b34337d489b089fc5ba0825a2ff1bee73" -dependencies = [ - "bytes", - "futures-io", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash", - "rustls 0.23.8", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "quinn-proto" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e974563a4b1c2206bbc61191ca4da9c22e4308b4c455e8906751cc7828393f08" -dependencies = [ - "bytes", - "rand", - "ring 0.17.8", - "rustc-hash", - "rustls 0.23.8", - "slab", - "thiserror", - "tinyvec", - "tracing", -] - -[[package]] -name = "quinn-udp" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4f0def2590301f4f667db5a77f9694fb004f82796dc1a8b1508fafa3d0e8b72" -dependencies = [ - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.52.0", -] - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_xorshift" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" -dependencies = [ - "rand_core", -] - -[[package]] -name = "rayon" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "rcgen" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52c4f3084aa3bc7dfbba4eff4fab2a54db4324965d8872ab933565e6fbd83bc6" -dependencies = [ - "pem 3.0.4", - "ring 0.16.20", - "time", - "yasna", -] - -[[package]] -name = "redox_syscall" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" -dependencies = [ - "bitflags 2.5.0", -] - -[[package]] -name = "redox_users" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" -dependencies = [ - "getrandom", - "libredox", - "thiserror", -] - -[[package]] -name = "regalloc2" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6" -dependencies = [ - "hashbrown 0.13.2", - "log", - "rustc-hash", - "slice-group-by", - "smallvec", -] - -[[package]] -name = "regex" -version = "1.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata 0.4.6", - "regex-syntax 0.8.3", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-automata" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.8.3", -] - -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" - -[[package]] -name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "base64 0.21.7", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-rustls", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls 0.21.12", - "rustls-pemfile 1.0.4", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "system-configuration", - "tokio", - "tokio-rustls 0.24.1", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots", - "winreg", -] - -[[package]] -name = "resolv-conf" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" -dependencies = [ - "hostname", - "quick-error", -] - -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac 0.12.1", - "subtle", -] - -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin 0.5.2", - "untrusted 0.7.1", - "web-sys", - "winapi", -] - -[[package]] -name = "ring" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" -dependencies = [ - "cc", - "cfg-if", - "getrandom", - "libc", - "spin 0.9.8", - "untrusted 0.9.0", - "windows-sys 0.52.0", -] - -[[package]] -name = "ripemd" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "rle-decode-fast" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" - -[[package]] -name = "rlp" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" -dependencies = [ - "bytes", - "rlp-derive", - "rustc-hex", -] - -[[package]] -name = "rlp-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "rocksdb" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe" -dependencies = [ - "libc", - "librocksdb-sys", -] - -[[package]] -name = "rtnetlink" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322c53fd76a18698f1c27381d58091de3a043d356aa5bd0d510608b565f469a0" -dependencies = [ - "futures", - "log", - "netlink-packet-route", - "netlink-proto", - "nix 0.24.3", - "thiserror", - "tokio", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc-hex" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - -[[package]] -name = "rusticata-macros" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" -dependencies = [ - "nom", -] - -[[package]] -name = "rustix" -version = "0.38.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" -dependencies = [ - "bitflags 2.5.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustls" -version = "0.21.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" -dependencies = [ - "log", - "ring 0.17.8", - "rustls-webpki 0.101.7", - "sct", -] - -[[package]] -name = "rustls" -version = "0.23.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79adb16721f56eb2d843e67676896a61ce7a0fa622dc18d3e372477a029d2740" -dependencies = [ - "once_cell", - "ring 0.17.8", - "rustls-pki-types", - "rustls-webpki 0.102.4", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-native-certs" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" -dependencies = [ - "openssl-probe", - "rustls-pemfile 2.1.2", - "rustls-pki-types", - "schannel", - "security-framework", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.7", -] - -[[package]] -name = "rustls-pemfile" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" -dependencies = [ - "base64 0.22.1", - "rustls-pki-types", -] - -[[package]] -name = "rustls-pki-types" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" - -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", -] - -[[package]] -name = "rustls-webpki" -version = "0.102.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" -dependencies = [ - "ring 0.17.8", - "rustls-pki-types", - "untrusted 0.9.0", -] - -[[package]] -name = "rustversion" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" - -[[package]] -name = "rw-stream-sink" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c9026ff5d2f23da5e45bbc283f156383001bfb09c4e44256d02c1a685fe9a1" -dependencies = [ - "futures", - "pin-project", - "static_assertions", -] - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scale-info" -version = "2.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" -dependencies = [ - "cfg-if", - "derive_more", - "parity-scale-codec", - "scale-info-derive", -] - -[[package]] -name = "scale-info-derive" -version = "2.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" -dependencies = [ - "proc-macro-crate 3.1.0", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "schannel" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", -] - -[[package]] -name = "sec1" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" -dependencies = [ - "base16ct", - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "secp256k1" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4124a35fe33ae14259c490fd70fa199a32b9ce9502f2ee6bc4f81ec06fa65894" -dependencies = [ - "rand", - "secp256k1-sys", -] - -[[package]] -name = "secp256k1-sys" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" -dependencies = [ - "cc", -] - -[[package]] -name = "secrecy" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" -dependencies = [ - "zeroize", -] - -[[package]] -name = "security-framework" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" -dependencies = [ - "bitflags 2.5.0", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" -dependencies = [ - "serde", -] - -[[package]] -name = "send_wrapper" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" - -[[package]] -name = "send_wrapper" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" - -[[package]] -name = "serde" -version = "1.0.203" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.203" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "serde_json" -version = "1.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_nanos" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a93142f0367a4cc53ae0fead1bcda39e85beccfad3dcd717656cacab94b12985" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_repr" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "serde_spanned" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" -dependencies = [ - "serde", -] - -[[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 = "serde_with" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" -dependencies = [ - "base64 0.22.1", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.2.6", - "serde", - "serde_derive", - "serde_json", - "serde_with_macros", - "time", -] - -[[package]] -name = "serde_with_macros" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" -dependencies = [ - "darling 0.20.9", - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "sha-1" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.7", - "keccak", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - -[[package]] -name = "signatory" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e303f8205714074f6068773f0e29527e0453937fe837c9717d066635b65f31" -dependencies = [ - "pkcs8", - "rand_core", - "signature", - "zeroize", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest 0.10.7", - "rand_core", -] - -[[package]] -name = "simple_asn1" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" -dependencies = [ - "num-bigint", - "num-traits", - "thiserror", - "time", -] - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "slice-group-by" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "snow" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "850948bee068e713b8ab860fe1adc4d109676ab4c3b621fd8147f06b261f2f85" -dependencies = [ - "aes-gcm", - "blake2", - "chacha20poly1305", - "curve25519-dalek", - "rand_core", - "ring 0.17.8", - "rustc_version", - "sha2 0.10.8", - "subtle", -] - -[[package]] -name = "socket2" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "soketto" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" -dependencies = [ - "base64 0.13.1", - "bytes", - "futures", - "httparse", - "log", - "rand", - "sha-1", -] - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "sptr" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "strum" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" -dependencies = [ - "strum_macros 0.24.3", -] - -[[package]] -name = "strum" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" -dependencies = [ - "strum_macros 0.25.3", -] - -[[package]] -name = "strum" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" -dependencies = [ - "strum_macros 0.26.2", -] - -[[package]] -name = "strum_macros" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 1.0.109", -] - -[[package]] -name = "strum_macros" -version = "0.25.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.66", -] - -[[package]] -name = "strum_macros" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.66", -] - -[[package]] -name = "subtle" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" - -[[package]] -name = "symbolic-common" -version = "12.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cccfffbc6bb3bb2d3a26cd2077f4d055f6808d266f9d4d158797a4c60510dfe" -dependencies = [ - "debugid", - "memmap2", - "stable_deref_trait", - "uuid", -] - -[[package]] -name = "symbolic-demangle" -version = "12.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a99812da4020a67e76c4eb41f08c87364c14170495ff780f30dd519c221a68" -dependencies = [ - "cpp_demangle", - "rustc-demangle", - "symbolic-common", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "synstructure" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "tai64" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed7401421025f4132e6c1f7af5e7f8287383969f36e6628016cd509b8d3da9dc" -dependencies = [ - "serde", -] - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "target-lexicon" -version = "0.12.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" - -[[package]] -name = "tempfile" -version = "3.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" -dependencies = [ - "cfg-if", - "fastrand", - "rustix", - "windows-sys 0.52.0", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "textwrap" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" - -[[package]] -name = "thiserror" -version = "1.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "thread_local" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "tikv-jemalloc-sys" -version = "0.5.4+5.3.0-patched" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9402443cb8fd499b6f327e40565234ff34dbda27460c5b47db0db77443dd85d1" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "tikv-jemallocator" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "965fe0c26be5c56c94e38ba547249074803efd52adfb66de62107d95aab3eaca" -dependencies = [ - "libc", - "tikv-jemalloc-sys", -] - -[[package]] -name = "time" -version = "0.3.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" -dependencies = [ - "deranged", - "itoa", - "num-conv", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" - -[[package]] -name = "time-macros" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - -[[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.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-macros" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "tokio-rayon" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cf33a76e0b1dd03b778f83244137bd59887abf25c0e87bc3e7071105f457693" -dependencies = [ - "rayon", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls 0.21.12", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" -dependencies = [ - "rustls 0.23.8", - "rustls-pki-types", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", - "tokio-util", -] - -[[package]] -name = "tokio-tungstenite" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" -dependencies = [ - "futures-util", - "log", - "rustls 0.21.12", - "tokio", - "tokio-rustls 0.24.1", - "tungstenite", - "webpki-roots", -] - -[[package]] -name = "tokio-util" -version = "0.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - -[[package]] -name = "toml" -version = "0.8.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.22.13", -] - -[[package]] -name = "toml_datetime" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap 2.2.6", - "toml_datetime", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" -dependencies = [ - "indexmap 2.2.6", - "toml_datetime", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.22.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c" -dependencies = [ - "indexmap 2.2.6", - "serde", - "serde_spanned", - "toml_datetime", - "winnow 0.6.9", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tokio", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-http" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" -dependencies = [ - "bitflags 1.3.2", - "bytes", - "futures-core", - "futures-util", - "http", - "http-body", - "http-range-header", - "pin-project-lite", - "tokio", - "tower", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - -[[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.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "futures", - "futures-task", - "pin-project", - "tracing", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-serde" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" -dependencies = [ - "serde", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "serde", - "serde_json", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", - "tracing-serde", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "tryhard" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9f0a709784e86923586cff0d872dba54cd2d2e116b3bc57587d15737cfce9d" -dependencies = [ - "futures", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tungstenite" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" -dependencies = [ - "byteorder", - "bytes", - "data-encoding", - "http", - "httparse", - "log", - "rand", - "rustls 0.21.12", - "sha1", - "thiserror", - "url", - "utf-8", -] - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" - -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - -[[package]] -name = "unarray" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-width" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" - -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - -[[package]] -name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" -dependencies = [ - "crypto-common", - "subtle", -] - -[[package]] -name = "unsigned-varint" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" -dependencies = [ - "asynchronous-codec 0.6.2", - "bytes", -] - -[[package]] -name = "unsigned-varint" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" -dependencies = [ - "form_urlencoded", - "idna 0.5.0", - "percent-encoding", -] - -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - -[[package]] -name = "uuid" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" -dependencies = [ - "getrandom", -] - -[[package]] -name = "valuable" -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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "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.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.66", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" - -[[package]] -name = "wasm-encoder" -version = "0.41.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "972f97a5d8318f908dded23594188a90bcd09365986b1163e66d70170e5287ae" -dependencies = [ - "leb128", -] - -[[package]] -name = "wasmparser" -version = "0.121.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" -dependencies = [ - "bitflags 2.5.0", - "indexmap 2.2.6", - "semver", -] - -[[package]] -name = "wasmtime" -version = "18.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69472708b96ee90579a482bdbb908ce97e53a9e5ebbcab59cc29c3977bcab512" -dependencies = [ - "anyhow", - "bincode", - "bumpalo", - "cfg-if", - "gimli", - "indexmap 2.2.6", - "libc", - "log", - "object", - "once_cell", - "paste", - "rayon", - "rustix", - "serde", - "serde_derive", - "serde_json", - "target-lexicon", - "wasmparser", - "wasmtime-cache", - "wasmtime-cranelift", - "wasmtime-environ", - "wasmtime-jit-icache-coherence", - "wasmtime-runtime", - "windows-sys 0.52.0", -] - -[[package]] -name = "wasmtime-asm-macros" -version = "18.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86292d6a9bf30c669582a40c4a4b8e0b8640e951f3635ee8e0acf7f87809961e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "wasmtime-cache" -version = "18.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a180017db1233c902b992fea9484640d265f2fedf03db60eed57894cb2effcc" -dependencies = [ - "anyhow", - "base64 0.21.7", - "bincode", - "directories-next", - "log", - "rustix", - "serde", - "serde_derive", - "sha2 0.10.8", - "toml 0.5.11", - "windows-sys 0.52.0", - "zstd", -] - -[[package]] -name = "wasmtime-cranelift" -version = "18.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b57d58e220ae223855c5d030ef20753377bc716d0c81b34c1fe74c9f44268774" -dependencies = [ - "anyhow", - "cfg-if", - "cranelift-codegen", - "cranelift-control", - "cranelift-entity", - "cranelift-frontend", - "cranelift-native", - "cranelift-wasm", - "gimli", - "log", - "object", - "target-lexicon", - "thiserror", - "wasmparser", - "wasmtime-cranelift-shared", - "wasmtime-environ", - "wasmtime-versioned-export-macros", -] - -[[package]] -name = "wasmtime-cranelift-shared" -version = "18.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba2cfdfdbde42f0f3baeddb62f3555524dee9f836c96da8d466e299f75f5eee" -dependencies = [ - "anyhow", - "cranelift-codegen", - "cranelift-control", - "cranelift-native", - "gimli", - "object", - "target-lexicon", - "wasmtime-environ", -] - -[[package]] -name = "wasmtime-environ" -version = "18.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abbf3075d9ee7eb1263dc67949aced64d0f0bf27be8098d34d8e5826cf0ff0f2" -dependencies = [ - "anyhow", - "bincode", - "cranelift-entity", - "gimli", - "indexmap 2.2.6", - "log", - "object", - "serde", - "serde_derive", - "target-lexicon", - "thiserror", - "wasmparser", - "wasmtime-types", -] - -[[package]] -name = "wasmtime-jit-icache-coherence" -version = "18.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dacd2aa30fb20fd8cd0eb4e664024a1ab28a02958529fa05bf52117532a098fc" -dependencies = [ - "cfg-if", - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "wasmtime-runtime" -version = "18.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d14e97c4bb36d91bcdd194745446d595e67ce8b89916806270fdbee640c747fd" -dependencies = [ - "anyhow", - "cc", - "cfg-if", - "indexmap 2.2.6", - "libc", - "log", - "mach", - "memfd", - "memoffset", - "paste", - "psm", - "rustix", - "sptr", - "wasm-encoder", - "wasmtime-asm-macros", - "wasmtime-environ", - "wasmtime-versioned-export-macros", - "wasmtime-wmemcheck", - "windows-sys 0.52.0", -] - -[[package]] -name = "wasmtime-types" -version = "18.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "530b94c627a454d24f520173d3145112d1b807c44c82697a57e1d8e28390cde4" -dependencies = [ - "cranelift-entity", - "serde", - "serde_derive", - "thiserror", - "wasmparser", -] - -[[package]] -name = "wasmtime-versioned-export-macros" -version = "18.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5399c175ddba4a471b9da45105dea3493059d52b2d54860eadb0df04c813948d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "wasmtime-wmemcheck" -version = "18.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1711f429111e782fac0537e0b3eb2ab6f821613cf1ec3013f2a0ff3fde41745" - -[[package]] -name = "web-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - -[[package]] -name = "widestring" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" - -[[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.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" -dependencies = [ - "windows-sys 0.52.0", -] - -[[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" -version = "0.51.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" -dependencies = [ - "windows-core 0.51.1", - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-core" -version = "0.51.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.5", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.5", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" -dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", - "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" - -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "winnow" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86c949fede1d13936a99f14fafd3e76fd642b556dd2ce96287fbe2e0151bfac6" -dependencies = [ - "memchr", -] - -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - -[[package]] -name = "ws_stream_wasm" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" -dependencies = [ - "async_io_stream", - "futures", - "js-sys", - "log", - "pharos", - "rustc_version", - "send_wrapper 0.6.0", - "thiserror", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "x25519-dalek" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" -dependencies = [ - "curve25519-dalek", - "rand_core", - "serde", - "zeroize", -] - -[[package]] -name = "x509-parser" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" -dependencies = [ - "asn1-rs", - "data-encoding", - "der-parser", - "lazy_static", - "nom", - "oid-registry", - "rusticata-macros", - "thiserror", - "time", -] - -[[package]] -name = "xml-rs" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" - -[[package]] -name = "xmltree" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb" -dependencies = [ - "xml-rs", -] - -[[package]] -name = "yamux" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed0164ae619f2dc144909a9f082187ebb5893693d8c0196e8085283ccd4b776" -dependencies = [ - "futures", - "log", - "nohash-hasher", - "parking_lot", - "pin-project", - "rand", - "static_assertions", -] - -[[package]] -name = "yamux" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f97202f6b125031b95d83e01dc57292b529384f80bfae4677e4bbc10178cf72" -dependencies = [ - "futures", - "instant", - "log", - "nohash-hasher", - "parking_lot", - "pin-project", - "rand", - "static_assertions", -] - -[[package]] -name = "yasna" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" -dependencies = [ - "time", -] - -[[package]] -name = "zerocopy" -version = "0.7.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "zstd" -version = "0.11.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "5.0.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.10+zstd.1.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" -dependencies = [ - "cc", - "pkg-config", -] diff --git a/crates/sv-emitter/Cargo.toml b/crates/sv-publisher/Cargo.toml similarity index 97% rename from crates/sv-emitter/Cargo.toml rename to crates/sv-publisher/Cargo.toml index 7433d14e..fdf306e6 100644 --- a/crates/sv-emitter/Cargo.toml +++ b/crates/sv-publisher/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "sv-emitter" +name = "sv-publisher" description = "Service that emitts new blocks using fuel-core block subscription" authors = { workspace = true } keywords = { workspace = true } @@ -12,7 +12,7 @@ rust-version = { workspace = true } publish = false [[bin]] -name = "sv-emitter" +name = "sv-publisher" path = "src/main.rs" [dependencies] diff --git a/crates/sv-emitter/src/cli.rs b/crates/sv-publisher/src/cli.rs similarity index 100% rename from crates/sv-emitter/src/cli.rs rename to crates/sv-publisher/src/cli.rs diff --git a/crates/sv-emitter/src/lib.rs b/crates/sv-publisher/src/lib.rs similarity index 100% rename from crates/sv-emitter/src/lib.rs rename to crates/sv-publisher/src/lib.rs diff --git a/crates/sv-emitter/src/main.rs b/crates/sv-publisher/src/main.rs similarity index 99% rename from crates/sv-emitter/src/main.rs rename to crates/sv-publisher/src/main.rs index 4eeefbb9..38b1d491 100644 --- a/crates/sv-emitter/src/main.rs +++ b/crates/sv-publisher/src/main.rs @@ -10,7 +10,7 @@ use fuel_core_types::blockchain::SealedBlock; use fuel_streams_core::prelude::*; use fuel_streams_executors::*; use futures::StreamExt; -use sv_emitter::{cli::Cli, shutdown::ShutdownController}; +use sv_publisher::{cli::Cli, shutdown::ShutdownController}; use thiserror::Error; use tokio_util::sync::CancellationToken; diff --git a/crates/sv-emitter/src/shutdown.rs b/crates/sv-publisher/src/shutdown.rs similarity index 100% rename from crates/sv-emitter/src/shutdown.rs rename to crates/sv-publisher/src/shutdown.rs diff --git a/crates/fuel-streams-ws/Cargo.toml b/crates/sv-webserver/Cargo.toml similarity index 99% rename from crates/fuel-streams-ws/Cargo.toml rename to crates/sv-webserver/Cargo.toml index 9405795f..fb7b66ff 100644 --- a/crates/fuel-streams-ws/Cargo.toml +++ b/crates/sv-webserver/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "fuel-streams-ws" +name = "sv-webserver" description = "Fuel library for streaming data from nats and storage" authors = { workspace = true } keywords = { workspace = true } diff --git a/crates/fuel-streams-ws/README.md b/crates/sv-webserver/README.md similarity index 97% rename from crates/fuel-streams-ws/README.md rename to crates/sv-webserver/README.md index f8ec1294..cd717d7c 100644 --- a/crates/fuel-streams-ws/README.md +++ b/crates/sv-webserver/README.md @@ -16,7 +16,7 @@

- 📚 Documentation + 📚 Documentation   🐛 Report Bug   diff --git a/crates/fuel-streams-ws/src/cli.rs b/crates/sv-webserver/src/cli.rs similarity index 100% rename from crates/fuel-streams-ws/src/cli.rs rename to crates/sv-webserver/src/cli.rs diff --git a/crates/fuel-streams-ws/src/client/mod.rs b/crates/sv-webserver/src/client/mod.rs similarity index 100% rename from crates/fuel-streams-ws/src/client/mod.rs rename to crates/sv-webserver/src/client/mod.rs diff --git a/crates/fuel-streams-ws/src/config.rs b/crates/sv-webserver/src/config.rs similarity index 100% rename from crates/fuel-streams-ws/src/config.rs rename to crates/sv-webserver/src/config.rs diff --git a/crates/fuel-streams-ws/src/lib.rs b/crates/sv-webserver/src/lib.rs similarity index 100% rename from crates/fuel-streams-ws/src/lib.rs rename to crates/sv-webserver/src/lib.rs diff --git a/crates/fuel-streams-ws/src/main.rs b/crates/sv-webserver/src/main.rs similarity index 98% rename from crates/fuel-streams-ws/src/main.rs rename to crates/sv-webserver/src/main.rs index 5b340d69..253f6fb3 100644 --- a/crates/fuel-streams-ws/src/main.rs +++ b/crates/sv-webserver/src/main.rs @@ -1,4 +1,4 @@ -use fuel_streams_ws::{ +use sv_webserver::{ config::Config, server::{api::create_api, context::Context, state::ServerState}, }; diff --git a/crates/fuel-streams-ws/src/server/api.rs b/crates/sv-webserver/src/server/api.rs similarity index 100% rename from crates/fuel-streams-ws/src/server/api.rs rename to crates/sv-webserver/src/server/api.rs diff --git a/crates/fuel-streams-ws/src/server/auth.rs b/crates/sv-webserver/src/server/auth.rs similarity index 100% rename from crates/fuel-streams-ws/src/server/auth.rs rename to crates/sv-webserver/src/server/auth.rs diff --git a/crates/fuel-streams-ws/src/server/context.rs b/crates/sv-webserver/src/server/context.rs similarity index 100% rename from crates/fuel-streams-ws/src/server/context.rs rename to crates/sv-webserver/src/server/context.rs diff --git a/crates/fuel-streams-ws/src/server/http/handlers.rs b/crates/sv-webserver/src/server/http/handlers.rs similarity index 100% rename from crates/fuel-streams-ws/src/server/http/handlers.rs rename to crates/sv-webserver/src/server/http/handlers.rs diff --git a/crates/fuel-streams-ws/src/server/http/mod.rs b/crates/sv-webserver/src/server/http/mod.rs similarity index 100% rename from crates/fuel-streams-ws/src/server/http/mod.rs rename to crates/sv-webserver/src/server/http/mod.rs diff --git a/crates/fuel-streams-ws/src/server/http/models.rs b/crates/sv-webserver/src/server/http/models.rs similarity index 100% rename from crates/fuel-streams-ws/src/server/http/models.rs rename to crates/sv-webserver/src/server/http/models.rs diff --git a/crates/fuel-streams-ws/src/server/middlewares/auth.rs b/crates/sv-webserver/src/server/middlewares/auth.rs similarity index 100% rename from crates/fuel-streams-ws/src/server/middlewares/auth.rs rename to crates/sv-webserver/src/server/middlewares/auth.rs diff --git a/crates/fuel-streams-ws/src/server/middlewares/mod.rs b/crates/sv-webserver/src/server/middlewares/mod.rs similarity index 100% rename from crates/fuel-streams-ws/src/server/middlewares/mod.rs rename to crates/sv-webserver/src/server/middlewares/mod.rs diff --git a/crates/fuel-streams-ws/src/server/mod.rs b/crates/sv-webserver/src/server/mod.rs similarity index 100% rename from crates/fuel-streams-ws/src/server/mod.rs rename to crates/sv-webserver/src/server/mod.rs diff --git a/crates/fuel-streams-ws/src/server/state.rs b/crates/sv-webserver/src/server/state.rs similarity index 100% rename from crates/fuel-streams-ws/src/server/state.rs rename to crates/sv-webserver/src/server/state.rs diff --git a/crates/fuel-streams-ws/src/server/ws/errors.rs b/crates/sv-webserver/src/server/ws/errors.rs similarity index 100% rename from crates/fuel-streams-ws/src/server/ws/errors.rs rename to crates/sv-webserver/src/server/ws/errors.rs diff --git a/crates/fuel-streams-ws/src/server/ws/mod.rs b/crates/sv-webserver/src/server/ws/mod.rs similarity index 100% rename from crates/fuel-streams-ws/src/server/ws/mod.rs rename to crates/sv-webserver/src/server/ws/mod.rs diff --git a/crates/fuel-streams-ws/src/server/ws/models.rs b/crates/sv-webserver/src/server/ws/models.rs similarity index 100% rename from crates/fuel-streams-ws/src/server/ws/models.rs rename to crates/sv-webserver/src/server/ws/models.rs diff --git a/crates/fuel-streams-ws/src/server/ws/socket.rs b/crates/sv-webserver/src/server/ws/socket.rs similarity index 100% rename from crates/fuel-streams-ws/src/server/ws/socket.rs rename to crates/sv-webserver/src/server/ws/socket.rs diff --git a/crates/fuel-streams-ws/src/server/ws/state.rs b/crates/sv-webserver/src/server/ws/state.rs similarity index 100% rename from crates/fuel-streams-ws/src/server/ws/state.rs rename to crates/sv-webserver/src/server/ws/state.rs diff --git a/crates/fuel-streams-ws/src/telemetry/elastic_search.rs b/crates/sv-webserver/src/telemetry/elastic_search.rs similarity index 100% rename from crates/fuel-streams-ws/src/telemetry/elastic_search.rs rename to crates/sv-webserver/src/telemetry/elastic_search.rs diff --git a/crates/fuel-streams-ws/src/telemetry/metrics.rs b/crates/sv-webserver/src/telemetry/metrics.rs similarity index 100% rename from crates/fuel-streams-ws/src/telemetry/metrics.rs rename to crates/sv-webserver/src/telemetry/metrics.rs diff --git a/crates/fuel-streams-ws/src/telemetry/mod.rs b/crates/sv-webserver/src/telemetry/mod.rs similarity index 100% rename from crates/fuel-streams-ws/src/telemetry/mod.rs rename to crates/sv-webserver/src/telemetry/mod.rs diff --git a/crates/fuel-streams-ws/src/telemetry/runtime.rs b/crates/sv-webserver/src/telemetry/runtime.rs similarity index 100% rename from crates/fuel-streams-ws/src/telemetry/runtime.rs rename to crates/sv-webserver/src/telemetry/runtime.rs diff --git a/crates/fuel-streams-ws/src/telemetry/system.rs b/crates/sv-webserver/src/telemetry/system.rs similarity index 100% rename from crates/fuel-streams-ws/src/telemetry/system.rs rename to crates/sv-webserver/src/telemetry/system.rs diff --git a/examples/Cargo.toml b/examples/Cargo.toml index cad5e612..c9a435e3 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -8,8 +8,8 @@ edition = "2021" anyhow = { workspace = true } fuel-core-types = { workspace = true } fuel-streams = { workspace = true, features = ["test-helpers"] } -fuel-streams-ws = { workspace = true } futures = { workspace = true } +sv-webserver = { workspace = true } tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } [[example]] diff --git a/examples/websockets.rs b/examples/websockets.rs index c05c8206..c8de232a 100755 --- a/examples/websockets.rs +++ b/examples/websockets.rs @@ -18,7 +18,7 @@ use fuel_streams::{ subjects::SubjectBuildable, types::FuelNetwork, }; -use fuel_streams_ws::{ +use sv_webserver::{ client::WebSocketClient, server::ws::models::DeliverPolicy, }; diff --git a/scripts/run_publisher.sh b/scripts/run_publisher.sh index 2cdbcd03..a97cc98c 100755 --- a/scripts/run_publisher.sh +++ b/scripts/run_publisher.sh @@ -33,7 +33,7 @@ NETWORK=${NETWORK:-"testnet"} MODE=${MODE:-"profiling"} PORT=${PORT:-"4004"} TELEMETRY_PORT=${TELEMETRY_PORT:-"8080"} -PACKAGE=${PACKAGE:-"sv-emitter"} +PACKAGE=${PACKAGE:-"sv-publisher"} while [[ "$#" -gt 0 ]]; do case $1 in diff --git a/scripts/run_streamer.sh b/scripts/run_streamer.sh index 0cdf6e01..f80b2a6b 100755 --- a/scripts/run_streamer.sh +++ b/scripts/run_streamer.sh @@ -114,8 +114,8 @@ fi # Execute based on mode if [ "${MODE:-dev}" == "dev" ]; then - cargo run -p fuel-streams-ws -- "${COMMON_ARGS[@]}" ${EXTRA_ARGS} + cargo run -p sv-webserver -- "${COMMON_ARGS[@]}" ${EXTRA_ARGS} else - cargo build --profile profiling --package fuel-streams-ws - samply record ./target/profiling/fuel-streams-ws "${COMMON_ARGS[@]}" ${EXTRA_ARGS} + cargo build --profile profiling --package sv-webserver + samply record ./target/profiling/sv-webserver "${COMMON_ARGS[@]}" ${EXTRA_ARGS} fi From 5319115516536ca7944b3db729407d6fbce387d1 Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 22:38:51 -0300 Subject: [PATCH 25/31] build(repo): bump chart --- .github/workflows/docker_publish.yaml | 4 ++-- cluster/charts/fuel-streams/Chart.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker_publish.yaml b/.github/workflows/docker_publish.yaml index 53a1bc4d..6aff171b 100644 --- a/.github/workflows/docker_publish.yaml +++ b/.github/workflows/docker_publish.yaml @@ -6,13 +6,13 @@ on: package: type: choice description: "Package to build and publish" - default: "sv-publisher" + default: "all" required: true options: + - all - sv-publisher - sv-webserver - sv-consumer - - all push: branches: - main diff --git a/cluster/charts/fuel-streams/Chart.yaml b/cluster/charts/fuel-streams/Chart.yaml index 165f8181..08768282 100755 --- a/cluster/charts/fuel-streams/Chart.yaml +++ b/cluster/charts/fuel-streams/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 appVersion: "1.0" description: A Helm chart for Kubernetes name: fuel-streams -version: 0.7.0 +version: 0.7.1 dependencies: - name: nats version: 1.2.8 From 66c7acdb2143da77038d7236f3d552c8da25bb14 Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 22:51:29 -0300 Subject: [PATCH 26/31] build(repo): some adjusts --- Tiltfile | 6 +++--- .../fuel-streams/tests/publisher/statefulset.yaml | 14 +++++++------- crates/fuel-streams-core/src/fuel_core_like.rs | 2 +- crates/fuel-streams-nats/src/lib.rs | 4 ++-- tarpaulin.toml | 4 ++-- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Tiltfile b/Tiltfile index 7d819a83..f81a64c0 100755 --- a/Tiltfile +++ b/Tiltfile @@ -87,7 +87,7 @@ config_mode = os.getenv('CLUSTER_MODE', 'full') # Resource configurations RESOURCES = { 'publisher': { - 'name': 'fuel-streams-publisher', + 'name': 'fuel-streams-sv-publisher', 'ports': ['8080:8080'], 'labels': 'publisher', 'config_mode': ['minimal', 'full'], @@ -98,10 +98,10 @@ RESOURCES = { 'ports': ['8081:8080'], 'labels': 'consumer', 'config_mode': ['minimal', 'full'], - 'deps': ['fuel-streams-nats-core', 'fuel-streams-nats-publisher', 'fuel-streams-publisher'] + 'deps': ['fuel-streams-nats-core', 'fuel-streams-nats-publisher', 'fuel-streams-sv-publisher'] }, 'sv-webserver': { - 'name': 'sv-webserver', + 'name': 'fuel-streams-sv-webserver', 'ports': ['9003:9003'], 'labels': 'ws', 'config_mode': ['minimal', 'full'], diff --git a/cluster/charts/fuel-streams/tests/publisher/statefulset.yaml b/cluster/charts/fuel-streams/tests/publisher/statefulset.yaml index fd3c3f6b..eaa6af79 100644 --- a/cluster/charts/fuel-streams/tests/publisher/statefulset.yaml +++ b/cluster/charts/fuel-streams/tests/publisher/statefulset.yaml @@ -10,36 +10,36 @@ tests: of: StatefulSet - equal: path: metadata.name - value: RELEASE-NAME-fuel-streams-publisher + value: RELEASE-NAME-sv-publisher - it: should set correct image and tag set: publisher.enabled: true - publisher.image.repository: ghcr.io/fuellabs/fuel-streams-publisher + publisher.image.repository: ghcr.io/fuellabs/sv-publisher publisher.image.tag: latest asserts: - equal: path: spec.template.spec.containers[0].image - value: ghcr.io/fuellabs/fuel-streams-publisher:latest + value: ghcr.io/fuellabs/sv-publisher:latest - it: should use chart version when tag is not specified set: publisher.enabled: true - publisher.image.repository: ghcr.io/fuellabs/fuel-streams-publisher + publisher.image.repository: ghcr.io/fuellabs/sv-publisher publisher.image.tag: null Chart: Version: "1.0" asserts: - equal: path: spec.template.spec.containers[0].image - value: ghcr.io/fuellabs/fuel-streams-publisher:1.0 + value: ghcr.io/fuellabs/sv-publisher:1.0 - it: should merge environment variables correctly set: publisher.enabled: true publisher.env: - CHAIN_CONFIG: "testnet" # Override default - NEW_VAR: "new-value" # Add new var + CHAIN_CONFIG: "testnet" # Override default + NEW_VAR: "new-value" # Add new var publisher.extraEnv: - name: SIMPLE_VAR value: "simple-value" diff --git a/crates/fuel-streams-core/src/fuel_core_like.rs b/crates/fuel-streams-core/src/fuel_core_like.rs index 93a395a7..85d2458f 100644 --- a/crates/fuel-streams-core/src/fuel_core_like.rs +++ b/crates/fuel-streams-core/src/fuel_core_like.rs @@ -17,7 +17,7 @@ use tokio::{sync::broadcast::Receiver, time::sleep}; use crate::types::*; /// Interface for `fuel-core` related logic. -/// This was introduced to simplify mocking and testing the `fuel-streams-publisher` crate. +/// This was introduced to simplify mocking and testing the `sv-publisher` crate. #[async_trait::async_trait] pub trait FuelCoreLike: Sync + Send { async fn start(&self) -> anyhow::Result<()>; diff --git a/crates/fuel-streams-nats/src/lib.rs b/crates/fuel-streams-nats/src/lib.rs index 0b664ba9..762ae550 100644 --- a/crates/fuel-streams-nats/src/lib.rs +++ b/crates/fuel-streams-nats/src/lib.rs @@ -1,6 +1,6 @@ -/// Houses shared APIs for interacting with NATS for fuel-streams-publisher and fuel-streams crates +/// Houses shared APIs for interacting with NATS for sv-publisher and fuel-streams crates /// As much as possible, the public interface/APIS should be agnostic of NATS. These can then be extended -/// in the fuel-streams-publisher and fuel-streams crates to provide a more opinionated API towards +/// in the sv-publisher and fuel-streams crates to provide a more opinionated API towards /// their specific use-cases. pub mod error; pub mod nats_client; diff --git a/tarpaulin.toml b/tarpaulin.toml index 1bc0cf6d..ce0c18cd 100644 --- a/tarpaulin.toml +++ b/tarpaulin.toml @@ -63,10 +63,10 @@ engine = "Llvm" # ========================================== # ignore due to wasm incompatibility -# [cov_fuel_streams_publisher] +# [cov_sv_publisher] # name = "Fuel Streams Publisher Coverage Analysis" # packages = [ -# "fuel-streams-publisher" +# "sv-publisher" # ] # all-features = true # run-types = [ From a4f64e5b4a6444e6ef389483428a9bb9d922e0df Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Fri, 20 Dec 2024 22:56:32 -0300 Subject: [PATCH 27/31] fix(consumer): remove max_messages --- crates/sv-consumer/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/sv-consumer/src/main.rs b/crates/sv-consumer/src/main.rs index d1e85e2d..2dba078d 100644 --- a/crates/sv-consumer/src/main.rs +++ b/crates/sv-consumer/src/main.rs @@ -138,7 +138,7 @@ async fn process_messages( let fuel_streams: Arc = publisher_stream.arc(); while !token.is_cancelled() { - let messages = consumer.fetch().max_messages(100).messages().await?; + let messages = consumer.fetch().messages().await?; tokio::pin!(messages); while let Some(msg) = messages.next().await { let msg = msg?; From e511286af5f837b26814c5234b948e87489d5bc2 Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Sat, 21 Dec 2024 00:01:22 -0300 Subject: [PATCH 28/31] refactor(repo): change s3 path --- Cargo.lock | 1 - Makefile | 35 +++++++++---------- crates/fuel-streams-core/Cargo.toml | 1 - .../src/stream/stream_impl.rs | 31 +++++----------- scripts/run_publisher.sh | 7 ++-- scripts/{run_streamer.sh => run_webserver.sh} | 0 6 files changed, 28 insertions(+), 47 deletions(-) rename scripts/{run_streamer.sh => run_webserver.sh} (100%) diff --git a/Cargo.lock b/Cargo.lock index 2458ca5c..dca7398f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4155,7 +4155,6 @@ dependencies = [ "pretty_assertions", "serde", "serde_json", - "sha2 0.10.8", "thiserror 2.0.8", "tokio", "tracing", diff --git a/Makefile b/Makefile index 5685b246..3a01a4d4 100644 --- a/Makefile +++ b/Makefile @@ -209,7 +209,6 @@ load-test: # ------------------------------------------------------------ run-publisher: NETWORK="testnet" -run-publisher: PACKAGE="sv-publisher" run-publisher: MODE="dev" run-publisher: PORT="4000" run-publisher: TELEMETRY_PORT="8080" @@ -245,15 +244,15 @@ run-consumer: # Streamer Run Commands # ------------------------------------------------------------ -run-streamer: NETWORK="testnet" -run-streamer: MODE="dev" -run-streamer: PORT="9003" -run-streamer: NATS_URL="nats://localhost:4222" -run-streamer: S3_ENABLED="true" -run-streamer: JWT_SECRET="secret" -run-streamer: USE_METRICS="false" -run-streamer: check-network - @./scripts/run_streamer.sh \ +run-webserver: NETWORK="testnet" +run-webserver: MODE="dev" +run-webserver: PORT="9003" +run-webserver: NATS_URL="nats://localhost:4222" +run-webserver: S3_ENABLED="true" +run-webserver: JWT_SECRET="secret" +run-webserver: USE_METRICS="false" +run-webserver: check-network + @./scripts/run_webserver.sh \ --mode $(MODE) \ --port $(PORT) \ --nats-url $(NATS_URL) \ @@ -262,17 +261,17 @@ run-streamer: check-network $(if $(USE_METRICS),--use-metrics,) \ $(if $(extra_args),$(extra_args),) -run-streamer-mainnet-dev: - $(MAKE) run-streamer NETWORK=mainnet MODE=dev +run-webserver-mainnet-dev: + $(MAKE) run-webserver NETWORK=mainnet MODE=dev -run-streamer-mainnet-profiling: - $(MAKE) run-streamer NETWORK=mainnet MODE=profiling +run-webserver-mainnet-profiling: + $(MAKE) run-webserver NETWORK=mainnet MODE=profiling -run-streamer-testnet-dev: - $(MAKE) run-streamer NETWORK=testnet MODE=dev +run-webserver-testnet-dev: + $(MAKE) run-webserver NETWORK=testnet MODE=dev -run-streamer-testnet-profiling: - $(MAKE) run-streamer NETWORK=testnet MODE=profiling +run-webserver-testnet-profiling: + $(MAKE) run-webserver NETWORK=testnet MODE=profiling # ------------------------------------------------------------ # Docker Compose diff --git a/crates/fuel-streams-core/Cargo.toml b/crates/fuel-streams-core/Cargo.toml index 7161a10b..9e6178fc 100644 --- a/crates/fuel-streams-core/Cargo.toml +++ b/crates/fuel-streams-core/Cargo.toml @@ -42,7 +42,6 @@ hex = { workspace = true } pretty_assertions = { workspace = true, optional = true } serde = { workspace = true } serde_json = { workspace = true } -sha2 = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } diff --git a/crates/fuel-streams-core/src/stream/stream_impl.rs b/crates/fuel-streams-core/src/stream/stream_impl.rs index d5476f21..2ed0e843 100644 --- a/crates/fuel-streams-core/src/stream/stream_impl.rs +++ b/crates/fuel-streams-core/src/stream/stream_impl.rs @@ -11,7 +11,6 @@ use async_nats::{ use async_trait::async_trait; use fuel_streams_macros::subject::IntoSubject; use futures::{stream::BoxStream, StreamExt, TryStreamExt}; -use sha2::{Digest, Sha256}; use tokio::sync::OnceCell; use crate::prelude::*; @@ -20,19 +19,20 @@ use crate::prelude::*; pub struct PublishPacket { pub subject: Arc, pub payload: Arc, - pub s3_path: String, } impl PublishPacket { pub fn new(payload: T, subject: Arc) -> Self { - let s3_path = payload.get_s3_path(); - Self { payload: Arc::new(payload), subject, - s3_path, } } + + pub fn get_s3_path(&self) -> String { + let subject = self.subject.parse(); + subject.replace('.', "/").to_string() + } } /// Trait for types that can be streamed. @@ -64,19 +64,6 @@ pub trait Streamable: StreamEncoder + std::marker::Sized { fn to_packet(&self, subject: Arc) -> PublishPacket { PublishPacket::new(self.clone(), subject) } - - fn get_s3_path(&self) -> String { - format!("v1/{}/{}.json", Self::NAME, self.get_consistent_hash()) - } - - fn get_consistent_hash(&self) -> String { - let serialized = self.encode_self(); - - let mut hasher = Sha256::new(); - hasher.update(serialized); - - format!("{:x}", hasher.finalize()) - } } /// Houses nats-agnostic APIs for publishing and consuming a streamable type @@ -174,15 +161,14 @@ impl Stream { packet: &PublishPacket, ) -> Result { let payload = &packet.payload; - let s3_path = &packet.s3_path; + let s3_path = packet.get_s3_path(); let subject_name = &packet.subject.parse(); - // publish payload to S3 self.s3_client - .put_object(s3_path, payload.encode(subject_name)) + .put_object(&s3_path, payload.encode(subject_name)) .await?; - self.publish_s3_path_to_nats(subject_name, s3_path).await + self.publish_s3_path_to_nats(subject_name, &s3_path).await } async fn publish_s3_path_to_nats( @@ -401,7 +387,6 @@ impl Stream { nats_payload: Vec, ) -> Result { let s3_path = String::from_utf8(nats_payload).expect("Must be S3 path"); - let s3_object = self .s3_client .get_object(&s3_path) diff --git a/scripts/run_publisher.sh b/scripts/run_publisher.sh index a97cc98c..3ffa1868 100755 --- a/scripts/run_publisher.sh +++ b/scripts/run_publisher.sh @@ -33,7 +33,6 @@ NETWORK=${NETWORK:-"testnet"} MODE=${MODE:-"profiling"} PORT=${PORT:-"4004"} TELEMETRY_PORT=${TELEMETRY_PORT:-"8080"} -PACKAGE=${PACKAGE:-"sv-publisher"} while [[ "$#" -gt 0 ]]; do case $1 in @@ -128,8 +127,8 @@ COMMON_ARGS=( # Execute based on mode if [ "$MODE" == "dev" ]; then - cargo run -p ${PACKAGE} -- "${COMMON_ARGS[@]}" ${EXTRA_ARGS} + cargo run -p sv-publisher -- "${COMMON_ARGS[@]}" ${EXTRA_ARGS} else - cargo build --profile profiling --package ${PACKAGE} - samply record ./target/profiling/${PACKAGE} "${COMMON_ARGS[@]}" ${EXTRA_ARGS} + cargo build --profile profiling --package sv-publisher + samply record ./target/profiling/sv-publisher "${COMMON_ARGS[@]}" ${EXTRA_ARGS} fi diff --git a/scripts/run_streamer.sh b/scripts/run_webserver.sh similarity index 100% rename from scripts/run_streamer.sh rename to scripts/run_webserver.sh From 7d1c4057a26822ea9eea7d1ca2ddadd75e9da9a4 Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Sat, 21 Dec 2024 00:02:49 -0300 Subject: [PATCH 29/31] build(repo): bump chart --- cluster/charts/fuel-streams/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cluster/charts/fuel-streams/Chart.yaml b/cluster/charts/fuel-streams/Chart.yaml index 08768282..228de229 100755 --- a/cluster/charts/fuel-streams/Chart.yaml +++ b/cluster/charts/fuel-streams/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 appVersion: "1.0" description: A Helm chart for Kubernetes name: fuel-streams -version: 0.7.1 +version: 0.7.2 dependencies: - name: nats version: 1.2.8 From 6f463683cd70fc8867a1c5675afdb92d8cbc6981 Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Sat, 21 Dec 2024 04:02:26 -0300 Subject: [PATCH 30/31] refactor(repo): perf improvements --- Cargo.lock | 2 + .../src/stream/stream_impl.rs | 2 +- crates/fuel-streams-executors/src/blocks.rs | 43 ++++----- crates/fuel-streams-executors/src/lib.rs | 18 ++-- .../src/transactions.rs | 86 +++++++---------- crates/fuel-streams-storage/Cargo.toml | 1 + .../fuel-streams-storage/src/s3/s3_client.rs | 76 ++++++++++++++- crates/sv-consumer/Cargo.toml | 1 + crates/sv-consumer/src/lib.rs | 4 +- crates/sv-consumer/src/main.rs | 92 ++++++++++++++++--- crates/sv-webserver/Cargo.toml | 2 +- 11 files changed, 220 insertions(+), 107 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dca7398f..a8c25d4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4227,6 +4227,7 @@ dependencies = [ "serde_json", "thiserror 2.0.8", "tokio", + "tracing", ] [[package]] @@ -9130,6 +9131,7 @@ dependencies = [ "fuel-streams-core", "fuel-streams-executors", "futures", + "num_cpus", "openssl", "serde_json", "sv-publisher", diff --git a/crates/fuel-streams-core/src/stream/stream_impl.rs b/crates/fuel-streams-core/src/stream/stream_impl.rs index 2ed0e843..fc8d974b 100644 --- a/crates/fuel-streams-core/src/stream/stream_impl.rs +++ b/crates/fuel-streams-core/src/stream/stream_impl.rs @@ -176,7 +176,7 @@ impl Stream { subject_name: &str, s3_path: &str, ) -> Result { - println!("publish_s3_path_to_nats: {:?}", s3_path.to_string()); + tracing::debug!("S3 path published: {:?}", s3_path); let data = s3_path.to_string().into_bytes(); let data_size = data.len(); let result = self.store.create(subject_name, data.into()).await; diff --git a/crates/fuel-streams-executors/src/blocks.rs b/crates/fuel-streams-executors/src/blocks.rs index b24ce9d6..5a145e2d 100644 --- a/crates/fuel-streams-executors/src/blocks.rs +++ b/crates/fuel-streams-executors/src/blocks.rs @@ -1,7 +1,7 @@ -use std::{sync::Arc, time::Instant}; +use std::sync::Arc; use fuel_streams_core::prelude::*; -use futures::{future::try_join_all, stream::FuturesUnordered}; +use futures::stream::FuturesUnordered; use tokio::task::JoinHandle; use crate::*; @@ -23,13 +23,11 @@ impl Executor { self.publish(&packet) } - pub async fn process_all( + pub fn process_all( payload: Arc, fuel_streams: &Arc, - ) -> Result<(), ExecutorError> { - let start_time = Instant::now(); - let metadata = Arc::new(payload.metadata().clone()); - + semaphore: &Arc, + ) -> FuturesUnordered>> { let block_stream = fuel_streams.blocks().arc(); let tx_stream = fuel_streams.transactions().arc(); let input_stream = fuel_streams.inputs().arc(); @@ -38,13 +36,15 @@ impl Executor { let log_stream = fuel_streams.logs().arc(); let utxo_stream = fuel_streams.utxos().arc(); - let block_executor = Executor::new(&payload, &block_stream); - let tx_executor = Executor::new(&payload, &tx_stream); - let input_executor = Executor::new(&payload, &input_stream); - let output_executor = Executor::new(&payload, &output_stream); - let receipt_executor = Executor::new(&payload, &receipt_stream); - let log_executor = Executor::new(&payload, &log_stream); - let utxo_executor = Executor::new(&payload, &utxo_stream); + let block_executor = Executor::new(&payload, &block_stream, semaphore); + let tx_executor = Executor::new(&payload, &tx_stream, semaphore); + let input_executor = Executor::new(&payload, &input_stream, semaphore); + let output_executor = + Executor::new(&payload, &output_stream, semaphore); + let receipt_executor = + Executor::new(&payload, &receipt_stream, semaphore); + let log_executor = Executor::new(&payload, &log_stream, semaphore); + let utxo_executor = Executor::new(&payload, &utxo_stream, semaphore); let transactions = payload.transactions.to_owned(); let tx_tasks = @@ -63,19 +63,8 @@ impl Executor { }); let block_task = block_executor.process(); - let all_tasks = std::iter::once(block_task) + std::iter::once(block_task) .chain(tx_tasks.into_iter().flatten()) - .collect::>(); - - try_join_all(all_tasks).await?; - - let elapsed = start_time.elapsed(); - let height = metadata.block_height.clone(); - tracing::info!( - "Published streams for BlockHeight: {height} in {:?}", - elapsed - ); - - Ok(()) + .collect::>() } } diff --git a/crates/fuel-streams-executors/src/lib.rs b/crates/fuel-streams-executors/src/lib.rs index d5ece798..a227758d 100644 --- a/crates/fuel-streams-executors/src/lib.rs +++ b/crates/fuel-streams-executors/src/lib.rs @@ -20,12 +20,10 @@ use tokio::task::JoinHandle; pub static PUBLISHER_MAX_THREADS: LazyLock = LazyLock::new(|| { let available_cpus = num_cpus::get(); - let default_threads = (available_cpus / 3).max(1); // Use 1/3 of CPUs, minimum 1 - env::var("PUBLISHER_MAX_THREADS") .ok() .and_then(|val| val.parse().ok()) - .unwrap_or(default_threads) + .unwrap_or(available_cpus) }); pub fn sha256(bytes: &[u8]) -> Bytes32 { @@ -194,14 +192,20 @@ impl TryFrom for Publish { pub struct Executor { pub stream: Arc>, payload: Arc, + semaphore: Arc, __marker: PhantomData, } impl Executor { - pub fn new(payload: &Arc, stream: &Arc>) -> Self { + pub fn new( + payload: &Arc, + stream: &Arc>, + semaphore: &Arc, + ) -> Self { Self { payload: payload.to_owned(), stream: stream.to_owned(), + semaphore: semaphore.to_owned(), __marker: PhantomData, } } @@ -212,9 +216,7 @@ impl Executor { ) -> JoinHandle> { let wildcard = packet.subject.parse(); let stream = Arc::clone(&self.stream); - let max_threads = *PUBLISHER_MAX_THREADS; - let semaphore = Arc::new(tokio::sync::Semaphore::new(max_threads)); - let permit = Arc::clone(&semaphore); + let permit = Arc::clone(&self.semaphore); // TODO: add telemetry back again let packet = packet.clone(); @@ -223,7 +225,7 @@ impl Executor { let _permit = permit.acquire().await?; match stream.publish(&packet).await { Ok(_) => { - tracing::info!( + tracing::debug!( "Successfully published for stream: {wildcard}" ); Ok(()) diff --git a/crates/fuel-streams-executors/src/transactions.rs b/crates/fuel-streams-executors/src/transactions.rs index 76c42f28..396364ca 100644 --- a/crates/fuel-streams-executors/src/transactions.rs +++ b/crates/fuel-streams-executors/src/transactions.rs @@ -21,65 +21,47 @@ fn packets_from_tx( (index, tx): (usize, &Transaction), block_height: &BlockHeight, ) -> Vec> { + let estimated_capacity = + 1 + tx.inputs.len() + tx.outputs.len() + tx.receipts.len(); let tx_id = tx.id.clone(); let tx_status = tx.status.clone(); let receipts = tx.receipts.clone(); - let main_subject = TransactionsSubject { - block_height: Some(block_height.to_owned()), - index: Some(index), - tx_id: Some(tx_id.to_owned()), - status: Some(tx_status.to_owned()), - kind: Some(tx.kind.to_owned()), - } - .arc(); - let mut packets = vec![tx.to_packet(main_subject)]; - packets.extend( - identifiers(tx, &tx.kind, &tx_id, index as u8) - .into_par_iter() - .map(|identifier| identifier.into()) - .map(|subject: TransactionsByIdSubject| subject.arc()) - .map(|subject| tx.to_packet(subject)) - .collect::>(), + // Main subject + let mut packets = Vec::with_capacity(estimated_capacity); + packets.push( + tx.to_packet( + TransactionsSubject { + block_height: Some(block_height.to_owned()), + index: Some(index), + tx_id: Some(tx_id.to_owned()), + status: Some(tx_status), + kind: Some(tx.kind.to_owned()), + } + .arc(), + ), ); - let packets_from_inputs: Vec> = tx - .inputs - .par_iter() - .flat_map(|input| { - inputs::identifiers(input, &tx_id, index as u8) - .into_par_iter() - .map(|identifier| identifier.into()) - .map(|subject: TransactionsByIdSubject| subject.arc()) - .map(|subject| tx.to_packet(subject)) - }) - .collect(); - packets.extend(packets_from_inputs); - - let packets_from_outputs: Vec> = tx - .outputs - .par_iter() - .flat_map(|output| { - outputs::identifiers(output, tx, &tx_id, index as u8) - .into_par_iter() - .map(|identifier| identifier.into()) - .map(|subject: TransactionsByIdSubject| subject.arc()) - .map(|subject| tx.to_packet(subject)) - }) - .collect(); - packets.extend(packets_from_outputs); + let index_u8 = index as u8; + let mut additional_packets: Vec> = + rayon::iter::once(&tx.kind) + .flat_map(|kind| identifiers(tx, kind, &tx_id, index_u8)) + .chain( + tx.inputs.par_iter().flat_map(|input| { + inputs::identifiers(input, &tx_id, index_u8) + }), + ) + .chain(tx.outputs.par_iter().flat_map(|output| { + outputs::identifiers(output, tx, &tx_id, index_u8) + })) + .chain(receipts.par_iter().flat_map(|receipt| { + receipts::identifiers(receipt, &tx_id, index_u8) + })) + .map(|identifier| TransactionsByIdSubject::from(identifier).arc()) + .map(|subject| tx.to_packet(subject)) + .collect(); - let packets_from_receipts: Vec> = receipts - .par_iter() - .flat_map(|receipt| { - receipts::identifiers(receipt, &tx_id, index as u8) - .into_par_iter() - .map(|identifier| identifier.into()) - .map(|subject: TransactionsByIdSubject| subject.arc()) - .map(|subject| tx.to_packet(subject)) - }) - .collect(); - packets.extend(packets_from_receipts); + packets.append(&mut additional_packets); packets } diff --git a/crates/fuel-streams-storage/Cargo.toml b/crates/fuel-streams-storage/Cargo.toml index 476e0882..2aefacfb 100644 --- a/crates/fuel-streams-storage/Cargo.toml +++ b/crates/fuel-streams-storage/Cargo.toml @@ -18,6 +18,7 @@ aws-smithy-types = "=1.2.9" dotenvy = { workspace = true } rand = { workspace = true } thiserror = { workspace = true } +tracing = { workspace = true } [dev-dependencies] pretty_assertions = { workspace = true } diff --git a/crates/fuel-streams-storage/src/s3/s3_client.rs b/crates/fuel-streams-storage/src/s3/s3_client.rs index 39a0c140..dad2ec35 100644 --- a/crates/fuel-streams-storage/src/s3/s3_client.rs +++ b/crates/fuel-streams-storage/src/s3/s3_client.rs @@ -54,7 +54,7 @@ pub struct S3Client { impl S3Client { pub async fn new(opts: &S3ClientOpts) -> Result { - let config = aws_config::defaults(BehaviorVersion::v2024_03_28()) + let config = aws_config::defaults(BehaviorVersion::latest()) .endpoint_url(opts.endpoint_url().to_string()) .region(Region::new(opts.region().to_string())) // TODO: Remove this once we have a proper S3 bucket created @@ -66,6 +66,7 @@ impl S3Client { // Create S3 config without signing let s3_config = aws_sdk_s3::config::Builder::from(&config) .force_path_style(true) + .disable_s3_express_session_auth(true) .build(); let client = aws_sdk_s3::Client::from_conf(s3_config); @@ -94,15 +95,80 @@ impl S3Client { key: &str, object: Vec, ) -> Result<(), S3ClientError> { - self.client + match self + .client .put_object() .bucket(&self.bucket) .key(key) .body(object.into()) .send() - .await?; - - Ok(()) + .await + { + Ok(_) => Ok(()), + Err(error) => match error { + SdkError::ServiceError(error) => { + tracing::error!( + "Failed to put object in S3 bucket={} key={}: {}", + self.bucket, + key, + error.err() + ); + Err(S3ClientError::PutObjectError(SdkError::ServiceError( + error, + ))) + } + SdkError::ConstructionFailure(error) => { + tracing::error!( + "Failed to construct S3 request for bucket={} key={}", + self.bucket, + key, + ); + Err(S3ClientError::PutObjectError( + SdkError::ConstructionFailure(error), + )) + } + SdkError::TimeoutError(error) => { + tracing::error!( + "Timeout putting object in S3 bucket={} key={}", + self.bucket, + key, + ); + Err(S3ClientError::PutObjectError(SdkError::TimeoutError( + error, + ))) + } + SdkError::DispatchFailure(error) => { + tracing::error!( + "Failed to dispatch S3 request for bucket={} key={}: {}", + self.bucket, + key, + error.as_connector_error().unwrap() + ); + Err(S3ClientError::PutObjectError( + SdkError::DispatchFailure(error), + )) + } + SdkError::ResponseError(error) => { + tracing::error!( + "Invalid response from S3 for bucket={} key={}", + self.bucket, + key, + ); + Err(S3ClientError::PutObjectError(SdkError::ResponseError( + error, + ))) + } + _ => { + tracing::error!( + "Failed to put object in S3 bucket={} key={}: {:?}", + self.bucket, + key, + error + ); + Err(S3ClientError::PutObjectError(error)) + } + }, + } } pub async fn get_object( diff --git a/crates/sv-consumer/Cargo.toml b/crates/sv-consumer/Cargo.toml index 54234ebc..50d1e17e 100644 --- a/crates/sv-consumer/Cargo.toml +++ b/crates/sv-consumer/Cargo.toml @@ -24,6 +24,7 @@ fuel-core = { workspace = true, default-features = false, features = ["p2p", "re fuel-streams-core = { workspace = true, features = ["test-helpers"] } fuel-streams-executors = { workspace = true, features = ["test-helpers"] } futures = { workspace = true } +num_cpus = { workspace = true } serde_json = { workspace = true } sv-publisher = { workspace = true } thiserror = { workspace = true } diff --git a/crates/sv-consumer/src/lib.rs b/crates/sv-consumer/src/lib.rs index 782b1918..1cddb9ed 100644 --- a/crates/sv-consumer/src/lib.rs +++ b/crates/sv-consumer/src/lib.rs @@ -25,7 +25,9 @@ impl Client { let url = self.url(cli); let opts = NatsClientOpts::admin_opts() .with_url(url) - .with_domain("CORE".to_string()); + .with_domain("CORE".to_string()) + .with_user("admin".to_string()) + .with_password("admin".to_string()); Ok(Arc::new(NatsClient::connect(&opts).await?)) } } diff --git a/crates/sv-consumer/src/main.rs b/crates/sv-consumer/src/main.rs index 2dba078d..3e4fb6b2 100644 --- a/crates/sv-consumer/src/main.rs +++ b/crates/sv-consumer/src/main.rs @@ -1,4 +1,8 @@ -use std::{sync::Arc, time::Duration}; +use std::{ + env, + sync::{Arc, LazyLock}, + time::Duration, +}; use async_nats::jetstream::{ consumer::{ @@ -11,10 +15,11 @@ use async_nats::jetstream::{ use clap::Parser; use fuel_streams_core::prelude::*; use fuel_streams_executors::*; -use futures::StreamExt; +use futures::{future::try_join_all, stream::FuturesUnordered, StreamExt}; use sv_consumer::{cli::Cli, Client}; use sv_publisher::shutdown::ShutdownController; use tokio_util::sync::CancellationToken; +use tracing::level_filters::LevelFilter; use tracing_subscriber::fmt::time; #[derive(thiserror::Error, Debug)] @@ -37,12 +42,18 @@ pub enum ConsumerError { #[error("Failed to deserialize block payload from message: {0}")] Deserialization(#[from] serde_json::Error), - #[error("Failed to publish block to stream: {0}")] - Publish(#[from] ExecutorError), - #[error("Failed to decode UTF-8: {0}")] Utf8(#[from] std::str::Utf8Error), + #[error("Failed to execute executor tasks: {0}")] + Executor(#[from] ExecutorError), + + #[error("Failed to join tasks: {0}")] + JoinTasks(#[from] tokio::task::JoinError), + + #[error("Failed to acquire semaphore: {0}")] + Semaphore(#[from] tokio::sync::AcquireError), + #[error("Failed to setup S3 client: {0}")] S3(#[from] S3ClientError), } @@ -52,7 +63,9 @@ async fn main() -> anyhow::Result<()> { // Initialize tracing subscriber tracing_subscriber::fmt() .with_env_filter( - "sv_consumer=trace,fuel_streams_executors=trace,fuel_streams_core=trace,fuel-streams-nats=trace,fuel-streams-storage=trace", + tracing_subscriber::EnvFilter::builder() + .with_default_directive(LevelFilter::INFO.into()) + .from_env_lossy(), ) .with_timer(time::LocalTime::rfc_3339()) .with_target(false) @@ -126,6 +139,14 @@ async fn setup_nats( Ok((core_client, publisher_client, consumer)) } +pub static CONSUMER_MAX_THREADS: LazyLock = LazyLock::new(|| { + let available_cpus = num_cpus::get(); + env::var("CONSUMER_MAX_THREADS") + .ok() + .and_then(|val| val.parse().ok()) + .unwrap_or(available_cpus) +}); + async fn process_messages( cli: &Cli, token: &CancellationToken, @@ -137,16 +158,63 @@ async fn process_messages( .await; let fuel_streams: Arc = publisher_stream.arc(); + let semaphore = Arc::new(tokio::sync::Semaphore::new(64)); while !token.is_cancelled() { - let messages = consumer.fetch().messages().await?; - tokio::pin!(messages); + let mut messages = + consumer.fetch().max_messages(100).messages().await?.fuse(); + let mut futs = FuturesUnordered::new(); while let Some(msg) = messages.next().await { let msg = msg?; - let msg_str = std::str::from_utf8(&msg.payload)?; - let payload = Arc::new(BlockPayload::decode(msg_str)?); - Executor::::process_all(payload, &fuel_streams).await?; - msg.ack().await?; + let fuel_streams = fuel_streams.clone(); + let semaphore = semaphore.clone(); + let future = async move { + let msg_str = std::str::from_utf8(&msg.payload)?; + let payload = Arc::new(BlockPayload::decode(msg_str)?); + let start_time = std::time::Instant::now(); + let futures = Executor::::process_all( + payload.clone(), + &fuel_streams, + &semaphore, + ); + let results = try_join_all(futures).await?; + let end_time = std::time::Instant::now(); + msg.ack().await?; + Ok::<_, ConsumerError>((results, start_time, end_time, payload)) + }; + futs.push(future); + } + while let Some(result) = futs.next().await { + let (results, start_time, end_time, payload) = result?; + log_task(results, start_time, end_time, payload); } } Ok(()) } + +fn log_task( + res: Vec>, + start_time: std::time::Instant, + end_time: std::time::Instant, + payload: Arc, +) { + let height = payload.metadata().clone().block_height; + let has_error = res.iter().any(|r| r.is_err()); + let errors = res + .iter() + .filter_map(|r| r.as_ref().err()) + .collect::>(); + + let elapsed = end_time.duration_since(start_time); + if has_error { + tracing::error!( + "Block {height} published with errors in {:?}", + elapsed + ); + tracing::debug!("Errors: {:?}", errors); + } else { + tracing::info!( + "Block {height} published successfully in {:?}", + elapsed + ); + } +} diff --git a/crates/sv-webserver/Cargo.toml b/crates/sv-webserver/Cargo.toml index fb7b66ff..e1f77ddd 100644 --- a/crates/sv-webserver/Cargo.toml +++ b/crates/sv-webserver/Cargo.toml @@ -33,7 +33,7 @@ fuel-streams-storage = { workspace = true, features = ["test-helpers"] } futures = { workspace = true } futures-util = { workspace = true } jsonwebtoken = "9.3.0" -num_cpus = "1.16" +num_cpus = { workspace = true } parking_lot = { version = "0.12", features = ["serde"] } prometheus = { version = "0.13", features = ["process"] } rand = { workspace = true } From 64bd803336bb75e1eaf643432ec03a1a8a84490e Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Sun, 22 Dec 2024 13:26:09 -0300 Subject: [PATCH 31/31] refactor(webserver): send decoded payload direct on websocket --- Makefile | 13 +------ crates/sv-webserver/src/server/ws/socket.rs | 43 +++++++-------------- scripts/run_webserver.sh | 34 +--------------- 3 files changed, 18 insertions(+), 72 deletions(-) diff --git a/Makefile b/Makefile index 3a01a4d4..877935b0 100644 --- a/Makefile +++ b/Makefile @@ -248,18 +248,9 @@ run-webserver: NETWORK="testnet" run-webserver: MODE="dev" run-webserver: PORT="9003" run-webserver: NATS_URL="nats://localhost:4222" -run-webserver: S3_ENABLED="true" -run-webserver: JWT_SECRET="secret" -run-webserver: USE_METRICS="false" +run-webserver: EXTRA_ARGS="" run-webserver: check-network - @./scripts/run_webserver.sh \ - --mode $(MODE) \ - --port $(PORT) \ - --nats-url $(NATS_URL) \ - --s3-enabled $(S3_ENABLED) \ - --jwt-secret $(JWT_SECRET) \ - $(if $(USE_METRICS),--use-metrics,) \ - $(if $(extra_args),$(extra_args),) + @./scripts/run_webserver.sh --mode $(MODE) --port $(PORT) --nats-url $(NATS_URL) --extra-args $(EXTRA_ARGS) run-webserver-mainnet-dev: $(MAKE) run-webserver NETWORK=mainnet MODE=dev diff --git a/crates/sv-webserver/src/server/ws/socket.rs b/crates/sv-webserver/src/server/ws/socket.rs index 15e01909..03512ed7 100644 --- a/crates/sv-webserver/src/server/ws/socket.rs +++ b/crates/sv-webserver/src/server/ws/socket.rs @@ -289,14 +289,6 @@ fn parse_client_message( Ok(msg) } -fn stream_to_server_message( - msg: Vec, -) -> Result, WsSubscriptionError> { - let server_message = serde_json::to_vec(&ServerMessage::Update(msg)) - .map_err(WsSubscriptionError::UnserializableMessagePayload)?; - Ok(server_message) -} - pub fn verify_and_extract_subject_name( subject_wildcard: &str, ) -> Result { @@ -347,45 +339,38 @@ async fn decode( match subject.as_str() { Transaction::NAME => { let entity = Transaction::decode_or_panic(s3_payload); - let serialized_data = serde_json::to_vec(&entity) - .map_err(WsSubscriptionError::UnparsablePayload)?; - stream_to_server_message(serialized_data) + serde_json::to_vec(&entity) + .map_err(WsSubscriptionError::UnparsablePayload) } Block::NAME => { let entity = Block::decode_or_panic(s3_payload); - let serialized_data = serde_json::to_vec(&entity) - .map_err(WsSubscriptionError::UnparsablePayload)?; - stream_to_server_message(serialized_data) + serde_json::to_vec(&entity) + .map_err(WsSubscriptionError::UnparsablePayload) } Input::NAME => { let entity = Input::decode_or_panic(s3_payload); - let serialized_data = serde_json::to_vec(&entity) - .map_err(WsSubscriptionError::UnparsablePayload)?; - stream_to_server_message(serialized_data) + serde_json::to_vec(&entity) + .map_err(WsSubscriptionError::UnparsablePayload) } Output::NAME => { let entity = Output::decode_or_panic(s3_payload); - let serialized_data = serde_json::to_vec(&entity) - .map_err(WsSubscriptionError::UnparsablePayload)?; - stream_to_server_message(serialized_data) + serde_json::to_vec(&entity) + .map_err(WsSubscriptionError::UnparsablePayload) } Receipt::NAME => { let entity = Receipt::decode_or_panic(s3_payload); - let serialized_data = serde_json::to_vec(&entity) - .map_err(WsSubscriptionError::UnparsablePayload)?; - stream_to_server_message(serialized_data) + serde_json::to_vec(&entity) + .map_err(WsSubscriptionError::UnparsablePayload) } Utxo::NAME => { let entity = Utxo::decode_or_panic(s3_payload); - let serialized_data = serde_json::to_vec(&entity) - .map_err(WsSubscriptionError::UnparsablePayload)?; - stream_to_server_message(serialized_data) + serde_json::to_vec(&entity) + .map_err(WsSubscriptionError::UnparsablePayload) } Log::NAME => { let entity = Log::decode_or_panic(s3_payload); - let serialized_data = serde_json::to_vec(&entity) - .map_err(WsSubscriptionError::UnparsablePayload)?; - stream_to_server_message(serialized_data) + serde_json::to_vec(&entity) + .map_err(WsSubscriptionError::UnparsablePayload) } _ => Err(WsSubscriptionError::UnknownSubjectName(subject.to_string())), } diff --git a/scripts/run_webserver.sh b/scripts/run_webserver.sh index f80b2a6b..91845a8a 100755 --- a/scripts/run_webserver.sh +++ b/scripts/run_webserver.sh @@ -12,15 +12,12 @@ usage() { echo " --mode : Specify the run mode (dev|profiling)" echo " --port : Port number for the API server (default: 9003)" echo " --nats-url : NATS URL (default: nats://localhost:4222)" - echo " --s3-enabled : Enable S3 integration (default: true)" - echo " --jwt-secret : Secret key for JWT authentication (default: secret)" - echo " --use-metrics : Enable metrics (flag)" echo " --extra-args : Optional additional arguments to append (in quotes)" echo "" echo "Examples:" echo " $0 # Runs with all defaults" echo " $0 --mode dev --port 8080 # Custom port" - echo " $0 --mode dev --use-metrics # Enable metrics" + echo " $0 --mode dev --extra-args '\"--use-metrics\"' # Enable metrics" exit 1 } @@ -38,18 +35,6 @@ while [[ "$#" -gt 0 ]]; do NATS_URL="$2" shift 2 ;; - --s3-enabled) - S3_ENABLED="$2" - shift 2 - ;; - --jwt-secret) - JWT_SECRET="$2" - shift 2 - ;; - --use-metrics) - USE_METRICS="true" - shift - ;; --extra-args) EXTRA_ARGS="$2" shift 2 @@ -67,10 +52,8 @@ done # Load environment variables with defaults PORT=${PORT:-9003} NATS_URL=${NATS_URL:-nats://localhost:4222} -S3_ENABLED=${S3_ENABLED:-true} -JWT_SECRET=${JWT_SECRET:-secret} -USE_METRICS=${USE_METRICS:-false} MODE=${MODE:-dev} +EXTRA_ARGS=${EXTRA_ARGS:-""} # ------------------------------ # Load Environment @@ -87,9 +70,6 @@ echo "Runtime Settings:" echo "→ Mode: ${MODE:-dev}" echo "→ API Port: ${PORT:-9003}" echo "→ NATS URL: ${NATS_URL:-"nats://localhost:4222"}" -echo "→ S3 Enabled: ${S3_ENABLED:-true}" -echo "→ JWT Secret: ${JWT_SECRET:-secret}" -echo "→ Use Metrics: ${USE_METRICS:-false}" if [ -n "$EXTRA_ARGS" ]; then echo "→ Extra Arguments: $EXTRA_ARGS" fi @@ -100,18 +80,8 @@ echo -e "==========================================\n" COMMON_ARGS=( "--port" "${PORT:-9003}" "--nats-url" "${NATS_URL:-"nats://localhost:4222"}" - "--jwt-secret" "${JWT_SECRET:-secret}" ) -# Add boolean flags if enabled -if [ "${S3_ENABLED:-true}" = "true" ]; then - COMMON_ARGS+=("--s3-enabled") -fi - -if [ "${USE_METRICS:-false}" = "true" ]; then - COMMON_ARGS+=("--use-metrics") -fi - # Execute based on mode if [ "${MODE:-dev}" == "dev" ]; then cargo run -p sv-webserver -- "${COMMON_ARGS[@]}" ${EXTRA_ARGS}