diff --git a/.devcontainer/build_golang_server.sh b/.devcontainer/build_golang_server.sh deleted file mode 100755 index 9b3253a..0000000 --- a/.devcontainer/build_golang_server.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -cd server && go build - -cp reconstruction ../ \ No newline at end of file diff --git a/.devcontainer/build_server.sh b/.devcontainer/build_server.sh new file mode 100644 index 0000000..42c1e98 --- /dev/null +++ b/.devcontainer/build_server.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +cd server && cargo build --release +cp target/release/server ../reconstruction diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index dfc53f4..49ec737 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,7 +2,11 @@ "name": "Reconstruction Server Devcontainer", "remoteUser": "reconstruction-server", "build": { - "dockerfile": "../docker/Dockerfile.dev" + "dockerfile": "../docker/Dockerfile", + "context": "../", + "args": { + "IS_DEVELOPMENT": "true" + } }, "workspaceFolder": "/app", "workspaceMount": "source=${localWorkspaceFolder},target=/app,type=bind", @@ -11,7 +15,8 @@ "extensions":[ "golang.Go", "ms-python.python", - "ms-python.debugpy" + "ms-python.debugpy", + "rust-lang.rust-analyzer" ] } }, @@ -32,5 +37,5 @@ // Uncomment if you want display forward // "source=/tmp/.X11-unix,target=/tmp/.X11-unix,type=bind,consistency=cached" ], - "postCreateCommand": "chown -R reconstruction-server:reconstruction-server /app && .devcontainer/build_golang_server.sh" + "postCreateCommand": "sudo .devcontainer/build_server.sh && sudo chown -R reconstruction-server:reconstruction-server /app" } \ No newline at end of file diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..830632b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,9 @@ +target/ +.git/ +.gitignore +.env +*.log +.DS_Store +README.md +Dockerfile +.dockerignore diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 0000000..ca0b020 --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,55 @@ +name: Build Docker Image + +on: + push: + branches: + - feature/sdk-integration + +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }} + cancel-in-progress: true + +jobs: + build: + runs-on: [self-hosted, Linux] + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # - name: Free up space + # run: | + # sudo sudo rm -rf /usr/share/dotnet # ~20GB + # sudo rm -rf /opt/ghc # ~4GB + # sudo rm -rf /usr/local/lib/android # ~10GB + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ secrets.GLOBAL_COMMON_AWS_ACCESS_KEY }} + aws-secret-access-key: ${{ secrets.GLOBAL_COMMON_AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ vars.GLOBAL_COMMON_AWS_REGION }} + + - name: Log in to AWS ECR + id: ecr-login + uses: aws-actions/amazon-ecr-login@v2 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ${{ steps.ecr-login.outputs.registry }}/reconstruction-server + tags: | + type=ref,event=branch + type=sha,prefix=,format=long + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: docker/Dockerfile + push: true + tags: ${{ steps.meta.outputs.tags }} diff --git a/.gitignore b/.gitignore index 0cc84df..752f5ff 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,7 @@ reconstruction .venv /venv /.idea +target +volume /src/cost_functions.cpython-38-x86_64-linux-gnu.so /src/ply_export.cpython-38-x86_64-linux-gnu.so diff --git a/docker/Dockerfile b/docker/Dockerfile index 422440b..24389a5 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,17 +1,23 @@ +ARG IS_DEVELOPMENT="false" + ## -## Go build for server +## Rust build for server ## -FROM --platform=$BUILDPLATFORM golang:1.21 AS go-build -RUN mkdir -p /app -WORKDIR /app -ADD server /app -ARG TARGETOS -ARG TARGETARCH -ARG VERSION -RUN CGO_ENABLED=0 GOOS="${TARGETOS}" GOARCH="${TARGETARCH}" go build +FROM rust:1.84-slim-bullseye AS rust-build +RUN apt-get update && apt-get install -y \ + git \ + && rm -rf /var/lib/apt/lists/* -FROM nvidia/cuda:11.0.3-base-ubuntu20.04 +WORKDIR /app +RUN mkdir -p /app/server +COPY server /app/server +RUN cd server && cargo build --release + +## +## Runtime image +## +FROM nvidia/cuda:11.0.3-base-ubuntu20.04 AS runtime ARG USERNAME=reconstruction-server ARG USER_UID=1000 @@ -159,15 +165,35 @@ RUN echo "/usr/local/lib" > /etc/ld.so.conf.d/local.conf && ldconfig # Run reconstruction server as separate user, not root RUN groupadd --gid $USER_GID $USERNAME \ - && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME + && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \ + && chown -R $USERNAME:$USERNAME /app RUN mkdir -p /app/jobs && chown -R reconstruction-server:reconstruction-server /app/jobs +RUN mkdir -p /app/volume && chown -R reconstruction-server:reconstruction-server /app/volume +# Dev container: Copy rust tools so we can compile inside the dev container +FROM runtime AS reconstruction_dev + +# Sudo enabled in dev container only +RUN apt-get install -y sudo \ + && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \ + && chmod 0440 /etc/sudoers.d/$USERNAME + +COPY --from=rust-build /usr/local/rustup /usr/local/rustup +COPY --from=rust-build /usr/local/cargo /usr/local/cargo +ENV PATH="/usr/local/cargo/bin:$PATH" +ENV RUSTUP_HOME="/usr/local/rustup" +ENV CARGO_HOME="/usr/local/cargo" +# Standalone image: Use the compiled server binary +FROM runtime AS reconstruction +COPY --from=rust-build /app/server/target/release/server /app/reconstruction +RUN chmod +x /app/server + +# Final stage: Select between dev and prod +FROM reconstruction${IS_DEVELOPMENT:+_dev} AS final + +WORKDIR /app USER $USERNAME +ENTRYPOINT ["/app/reconstruction"] -COPY --from=go-build /app/reconstruction ./reconstruction -ENTRYPOINT ["./reconstruction"] -# Overridable using 'docker run ... image_name -api-key ' -# TODO: we probably don't need api key, or make it optional. Just check domain token. -CMD ["-api-key", "kaffekopp123"] diff --git a/docker/Dockerfile.dev b/docker/Dockerfile.dev deleted file mode 100644 index 6f3833f..0000000 --- a/docker/Dockerfile.dev +++ /dev/null @@ -1,148 +0,0 @@ -FROM nvidia/cuda:11.0.3-base-ubuntu20.04 - -ARG USERNAME=reconstruction-server -ARG USER_UID=1000 -ARG USER_GID=$USER_UID -ARG DEBIAN_FRONTEND=noninteractive - -RUN apt-get update && apt-get install -y \ - wget \ - curl \ - vim \ - git \ - nano \ - jq \ - less \ - cmake \ - autoconf \ - automake \ - libtool \ - libffi-dev \ - ninja-build \ - build-essential \ - libboost-program-options-dev \ - libboost-filesystem-dev \ - libboost-graph-dev \ - libboost-system-dev \ - libeigen3-dev \ - libflann-dev \ - libfreeimage-dev \ - libmetis-dev \ - libgtest-dev \ - libsqlite3-dev \ - libglew-dev \ - qtbase5-dev \ - libqt5opengl5-dev \ - libcgal-dev \ - libsuitesparse-dev \ - python3-pip \ - python3-tk - -RUN apt-get install -y --no-install-recommends \ - ssh \ - netcat-openbsd \ - ca-certificates \ - iproute2 \ - iputils-ping \ - bind9-dnsutils - -RUN pip install --upgrade pip setuptools wheel - -RUN wget https://cmake.org/files/v3.27/cmake-3.27.9-linux-x86_64.tar.gz \ - && tar xvf cmake-3.27.9-linux-x86_64.tar.gz \ - && cd cmake-3.27.9-linux-x86_64 \ - && cp -r bin /usr/ \ - && cp -r share /usr/ \ - && cp -r doc /usr/share/ \ - && cp -r man /usr/share/ \ - && cd .. \ - && rm -rf cmake* - -RUN git clone https://github.com/google/glog.git && cd glog && \ - git checkout tags/v0.6.0 && \ - cmake -S . -B build -G "Unix Makefiles" && \ - cmake --build build --target install - -RUN pip install "pybind11[global]==2.12.0" - -RUN pip install psutil gputil - -WORKDIR /src - -RUN git clone https://github.com/NVIDIA/libglvnd && \ - cd libglvnd && \ - ./autogen.sh && \ - ./configure && \ - make -j4 && \ - make install - -# Ceres -RUN git clone --recursive https://ceres-solver.googlesource.com/ceres-solver \ - && cd ceres-solver \ - && git checkout tags/2.2.0 \ - && mkdir build \ - && cd build \ - && cmake .. -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF \ - && make -j4 \ - && make install - -# pyCeres -RUN git clone https://github.com/cvg/pyceres.git \ - && cd pyceres \ - && git checkout tags/v2.3 \ - && python3 -m pip install -e . - -# COLMAP -RUN git clone https://github.com/colmap/colmap.git && \ - cd colmap \ - && git checkout release/3.10 \ - && mkdir build \ - && cd build \ - && cmake -DCUDA_ENABLED=ON -DCMAKE_CUDA_ARCHITECTURES="60;61;70;75;80;86;89" .. \ - && make -j 4 \ - && make install \ - && cd ../pycolmap \ - && python3 -m pip install -e . - -# Hloc -RUN git clone --recursive https://github.com/cvg/Hierarchical-Localization && \ - cd Hierarchical-Localization && \ - git checkout --recurse-submodules abb252080282e31147db6291206ca102c43353f7 && \ - python3 -m pip install -e . --config-settings editable_mode=compat && \ - python3 -m pip install --upgrade plotly - -# Hloc installs latest opencv-python as dependency, -# but the latest opencv 4.11.0.86 introduced a bug -# causing unpacked mp4 frames to be rotated wrong. -# For now we need to downgrade opencv (after hloc). -RUN python3 -m pip install opencv-python==4.10.0.84 - -RUN python3 -m pip install enlighten evo - -RUN python3 -m pip install open3d trimesh alphashape - -RUN git clone https://github.com/google/draco.git && \ - cd draco && \ - mkdir build && \ - cd build && \ - cmake .. && \ - make - -# Server Stuff -COPY --from=golang:1.21 /usr/local/go/ /usr/local/go/ -ENV PATH="$PATH:/usr/local/go/bin" - -# User Stuff -RUN groupadd --gid $USER_GID $USERNAME \ - && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \ - # - # [Optional] Add sudo support. Omit if you don't need to install software after connecting. - && apt-get update \ - && apt-get install -y sudo \ - && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \ - && chmod 0440 /etc/sudoers.d/$USERNAME - -USER $USERNAME - -WORKDIR /app -ENTRYPOINT /bin/bash \ No newline at end of file diff --git a/main.py b/main.py index 5c35a36..53a660a 100644 --- a/main.py +++ b/main.py @@ -1,6 +1,6 @@ from pathlib import Path import argparse - +import sys from local_main import main as local_main from global_main import main as global_main from occlusion_box import main as occlusion_box_main @@ -116,21 +116,6 @@ def local_and_global_main_wrapper(args, logger): #occlusion_box_wrapper(ply_output_path, global_out_folder / "occlusion", logger) -def get_available_scans(datasets_path): - """Get list of available scans in the datasets directory. - - Args: - datasets_path: Path to datasets directory - - Returns: - List of scan names - """ - return [ - scan.name for scan in datasets_path.iterdir() - if scan.is_dir() or scan.suffix == ".zip" - ] - - def process_refinement(args, logger): """Process refinement based on specified mode. @@ -182,15 +167,11 @@ def main(args): level=args.log_level ) - # TODO: ignoring the scans parameter from go for now since it's incorrect (fix after redeploy) - # Get available scans from datasets directory - args.scans = get_available_scans(args.job_root_path / "datasets") - try: process_refinement(args, logger) except Exception as e: handle_refinement_error(e, args, logger) - raise e + raise sys.exit(1) def parse_args(): @@ -204,7 +185,7 @@ def parse_args(): help="Set the logging level (default: INFO)" ) - parser.add_argument("--scans", nargs="+", default=[], help="List of scans to process") + parser.add_argument("--scans", nargs="+", help="List of scans to process") return parser.parse_args() diff --git a/server/Cargo.lock b/server/Cargo.lock new file mode 100644 index 0000000..e915b55 --- /dev/null +++ b/server/Cargo.lock @@ -0,0 +1,5567 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[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 = "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.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +dependencies = [ + "anstyle", + "once_cell", + "windows-sys 0.59.0", +] + +[[package]] +name = "anyhow" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" + +[[package]] +name = "arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "asn1-rs" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" +dependencies = [ + "asn1-rs-derive 0.4.0", + "asn1-rs-impl 0.1.0", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror 1.0.69", + "time", +] + +[[package]] +name = "asn1-rs" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048" +dependencies = [ + "asn1-rs-derive 0.5.1", + "asn1-rs-impl 0.2.0", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror 1.0.69", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure 0.12.6", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", + "synstructure 0.13.2", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[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.101", +] + +[[package]] +name = "async-io" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" +dependencies = [ + "async-lock", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix 0.38.44", + "slab", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-timer" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5fa6ed76cb2aa820707b4eb9ec46f42da9ce70b0eafab5e5e34942b38a44d5" +dependencies = [ + "libc", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "async-trait" +version = "0.1.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[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-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "attohttpc" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9a9bf8b79a749ee0b911b91b671cc2b6c670bdbc7e3dfd537576ddc94bb2a2" +dependencies = [ + "http 0.2.12", + "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 = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + +[[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.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.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + +[[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 = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +dependencies = [ + "serde", +] + +[[package]] +name = "bzip2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" +dependencies = [ + "bzip2-sys", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.13+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" +dependencies = [ + "cc", + "pkg-config", +] + +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + +[[package]] +name = "cbindgen" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadd868a2ce9ca38de7eeafdcec9c7065ef89b42b32f0839278d55f35c54d1ff" +dependencies = [ + "clap 4.5.37", + "heck 0.4.1", + "indexmap", + "log", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn 2.0.101", + "tempfile", + "toml", +] + +[[package]] +name = "cc" +version = "1.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "ccm" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae3c82e4355234767756212c570e29833699ab63e6ffd161887314cc5b43847" +dependencies = [ + "aead", + "cipher", + "ctr", + "subtle", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[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 = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags 1.3.2", + "strsim 0.8.0", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "clap" +version = "4.5.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim 0.11.1", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[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_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[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.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" + +[[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 0.6.4", + "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 0.6.4", + "typenum", +] + +[[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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "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.101", +] + +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + +[[package]] +name = "data-encoding-macro" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47ce6c96ea0102f01122a185683611bd5ac8d99e62bc59dd12e6bda344ee673d" +dependencies = [ + "data-encoding", + "data-encoding-macro-internal", +] + +[[package]] +name = "data-encoding-macro-internal" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" +dependencies = [ + "data-encoding", + "syn 2.0.101", +] + +[[package]] +name = "deflate64" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b" + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "der-parser" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" +dependencies = [ + "asn1-rs 0.5.2", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "der-parser" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" +dependencies = [ + "asn1-rs 0.6.2", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive_arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "downcast" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" + +[[package]] +name = "dtoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "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 0.6.4", + "serde", + "sha2", + "subtle", + "zeroize", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[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", + "ff", + "generic-array", + "group", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "enum-as-inner" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "event-listener" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "flate2" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[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 = "fragile" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619" + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-bounded" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91f328e7fb845fc832912fb6a34f40cf6d1888c92f974d1893a54e97b5ff542e" +dependencies = [ + "futures-timer", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-lite" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[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.26", + "rustls-pki-types", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[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 0.2.6", + "send_wrapper 0.4.0", +] + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[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.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", + "wasm-bindgen", +] + +[[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.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[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 = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +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 0.6.4", + "subtle", +] + +[[package]] +name = "h2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75249d144030531f8dee69fe9cea04d3edf809a017ae445e2abdff6629e86633" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.3.1", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[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 = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92652067c9ce6f66ce53cc38d1169daa36e6e7eb7dd3b63b5103bd9d97117248" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna", + "ipnet", + "once_cell", + "rand 0.8.5", + "socket2", + "thiserror 1.0.69", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "hickory-resolver" +version = "0.24.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbb117a1ca520e111743ab2f6688eddee69db4e0ea242545a604dce8a66fd22e" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-proto", + "ipconfig", + "lru-cache", + "once_cell", + "parking_lot", + "rand 0.8.5", + "resolv-conf", + "smallvec", + "thiserror 1.0.69", + "tokio", + "tracing", +] + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[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" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.3.1", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http 1.3.1", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "humantime" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error", +] + +[[package]] +name = "hyper" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http 1.3.1", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.3.1", + "http-body", + "hyper", + "libc", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdf9d64cfcf380606e64f9a0bcf493616b65331199f984151a6fa11a7b3cde38" +dependencies = [ + "async-io", + "core-foundation", + "fnv", + "futures", + "if-addrs", + "ipnet", + "log", + "netlink-packet-core", + "netlink-packet-route", + "netlink-proto", + "netlink-sys", + "rtnetlink", + "system-configuration", + "tokio", + "windows", +] + +[[package]] +name = "igd-next" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76b0d7d4541def58a37bf8efc559683f21edce7c82f0d866c93ac21f7e098f93" +dependencies = [ + "async-trait", + "attohttpc", + "bytes", + "futures", + "http 1.3.1", + "http-body-util", + "hyper", + "hyper-util", + "log", + "rand 0.8.5", + "tokio", + "url", + "xmltree", +] + +[[package]] +name = "indexmap" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "block-padding", + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "interceptor" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5927883184e6a819b22d5e4f5f7bc7ca134fde9b2026fbddd8d95249746ba21e" +dependencies = [ + "async-trait", + "bytes", + "log", + "rand 0.8.5", + "rtcp", + "rtp 0.9.0", + "thiserror 1.0.69", + "tokio", + "waitgroup", + "webrtc-srtp", + "webrtc-util 0.8.1", +] + +[[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.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jobserver" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +dependencies = [ + "getrandom 0.3.2", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "jsonwebtoken" +version = "9.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" +dependencies = [ + "base64 0.22.1", + "js-sys", + "pem", + "ring 0.17.14", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.172" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" + +[[package]] +name = "libp2p" +version = "0.54.1" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "bytes", + "either", + "futures", + "futures-timer", + "getrandom 0.2.16", + "libp2p-allow-block-list", + "libp2p-autonat", + "libp2p-connection-limits", + "libp2p-core", + "libp2p-dcutr", + "libp2p-dns", + "libp2p-gossipsub", + "libp2p-identify", + "libp2p-identity", + "libp2p-kad", + "libp2p-mdns", + "libp2p-metrics", + "libp2p-noise", + "libp2p-ping", + "libp2p-quic", + "libp2p-relay", + "libp2p-swarm", + "libp2p-tcp", + "libp2p-upnp", + "libp2p-websocket", + "libp2p-yamux", + "multiaddr", + "pin-project", + "rw-stream-sink", + "thiserror 1.0.69", +] + +[[package]] +name = "libp2p-allow-block-list" +version = "0.4.1" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "void", +] + +[[package]] +name = "libp2p-autonat" +version = "0.13.1" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "async-trait", + "asynchronous-codec", + "bytes", + "either", + "futures", + "futures-bounded", + "futures-timer", + "libp2p-core", + "libp2p-identity", + "libp2p-request-response", + "libp2p-swarm", + "quick-protobuf", + "quick-protobuf-codec 0.3.1 (git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm)", + "rand 0.8.5", + "rand_core 0.6.4", + "thiserror 1.0.69", + "tracing", + "void", + "web-time", +] + +[[package]] +name = "libp2p-connection-limits" +version = "0.4.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "void", +] + +[[package]] +name = "libp2p-core" +version = "0.42.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "either", + "fnv", + "futures", + "futures-timer", + "libp2p-identity", + "multiaddr", + "multihash", + "multistream-select", + "once_cell", + "parking_lot", + "pin-project", + "quick-protobuf", + "rand 0.8.5", + "rw-stream-sink", + "serde", + "smallvec", + "thiserror 1.0.69", + "tracing", + "unsigned-varint", + "void", + "web-time", +] + +[[package]] +name = "libp2p-dcutr" +version = "0.12.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "asynchronous-codec", + "either", + "futures", + "futures-bounded", + "futures-timer", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "lru", + "quick-protobuf", + "quick-protobuf-codec 0.3.1 (git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm)", + "thiserror 1.0.69", + "tracing", + "void", + "web-time", +] + +[[package]] +name = "libp2p-dns" +version = "0.42.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "async-trait", + "futures", + "hickory-resolver", + "libp2p-core", + "libp2p-identity", + "parking_lot", + "smallvec", + "tracing", +] + +[[package]] +name = "libp2p-gossipsub" +version = "0.47.2" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "asynchronous-codec", + "base64 0.22.1", + "byteorder", + "bytes", + "either", + "fnv", + "futures", + "futures-ticker", + "getrandom 0.2.16", + "hex_fmt", + "instant", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "prometheus-client", + "quick-protobuf", + "quick-protobuf-codec 0.3.1 (git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm)", + "rand 0.8.5", + "regex", + "serde", + "sha2", + "smallvec", + "tracing", + "void", + "web-time", +] + +[[package]] +name = "libp2p-identify" +version = "0.45.1" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "asynchronous-codec", + "either", + "futures", + "futures-bounded", + "futures-timer", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "lru", + "quick-protobuf", + "quick-protobuf-codec 0.3.1 (git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm)", + "smallvec", + "thiserror 1.0.69", + "tracing", + "void", +] + +[[package]] +name = "libp2p-identity" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbb68ea10844211a59ce46230909fd0ea040e8a192454d4cc2ee0d53e12280eb" +dependencies = [ + "bs58", + "ed25519-dalek", + "hkdf", + "multihash", + "quick-protobuf", + "rand 0.8.5", + "serde", + "sha2", + "thiserror 2.0.12", + "tracing", + "zeroize", +] + +[[package]] +name = "libp2p-kad" +version = "0.47.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "arrayvec", + "asynchronous-codec", + "bytes", + "either", + "fnv", + "futures", + "futures-bounded", + "futures-timer", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "quick-protobuf", + "quick-protobuf-codec 0.3.1 (git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm)", + "rand 0.8.5", + "serde", + "sha2", + "smallvec", + "thiserror 1.0.69", + "tracing", + "uint", + "void", + "web-time", +] + +[[package]] +name = "libp2p-mdns" +version = "0.46.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "data-encoding", + "futures", + "hickory-proto", + "if-watch", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "rand 0.8.5", + "smallvec", + "socket2", + "tokio", + "tracing", + "void", +] + +[[package]] +name = "libp2p-metrics" +version = "0.15.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "futures", + "libp2p-core", + "libp2p-dcutr", + "libp2p-gossipsub", + "libp2p-identify", + "libp2p-identity", + "libp2p-kad", + "libp2p-ping", + "libp2p-relay", + "libp2p-swarm", + "pin-project", + "prometheus-client", + "web-time", +] + +[[package]] +name = "libp2p-noise" +version = "0.45.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "asynchronous-codec", + "bytes", + "curve25519-dalek", + "futures", + "libp2p-core", + "libp2p-identity", + "multiaddr", + "multihash", + "once_cell", + "quick-protobuf", + "rand 0.8.5", + "sha2", + "snow", + "static_assertions", + "thiserror 1.0.69", + "tracing", + "x25519-dalek", + "zeroize", +] + +[[package]] +name = "libp2p-ping" +version = "0.45.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "either", + "futures", + "futures-timer", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "rand 0.8.5", + "tracing", + "void", + "web-time", +] + +[[package]] +name = "libp2p-quic" +version = "0.11.1" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "bytes", + "futures", + "futures-timer", + "if-watch", + "libp2p-core", + "libp2p-identity", + "libp2p-tls", + "parking_lot", + "quinn", + "rand 0.8.5", + "ring 0.17.14", + "rustls 0.23.26", + "socket2", + "thiserror 1.0.69", + "tokio", + "tracing", +] + +[[package]] +name = "libp2p-relay" +version = "0.18.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "asynchronous-codec", + "bytes", + "either", + "futures", + "futures-bounded", + "futures-timer", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "quick-protobuf", + "quick-protobuf-codec 0.3.1 (git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm)", + "rand 0.8.5", + "static_assertions", + "thiserror 1.0.69", + "tracing", + "void", + "web-time", +] + +[[package]] +name = "libp2p-request-response" +version = "0.27.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "async-trait", + "futures", + "futures-bounded", + "futures-timer", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "rand 0.8.5", + "smallvec", + "tracing", + "void", + "web-time", +] + +[[package]] +name = "libp2p-stream" +version = "0.2.0-alpha" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "futures", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "rand 0.8.5", + "tracing", + "void", +] + +[[package]] +name = "libp2p-swarm" +version = "0.45.2" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "either", + "fnv", + "futures", + "futures-timer", + "getrandom 0.2.16", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm-derive", + "lru", + "multistream-select", + "once_cell", + "rand 0.8.5", + "smallvec", + "tokio", + "tracing", + "void", + "wasm-bindgen-futures", + "web-time", +] + +[[package]] +name = "libp2p-swarm-derive" +version = "0.35.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "libp2p-tcp" +version = "0.42.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "futures", + "futures-timer", + "if-watch", + "libc", + "libp2p-core", + "libp2p-identity", + "socket2", + "tokio", + "tracing", +] + +[[package]] +name = "libp2p-tls" +version = "0.5.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "futures", + "futures-rustls", + "libp2p-core", + "libp2p-identity", + "rcgen", + "ring 0.17.14", + "rustls 0.23.26", + "rustls-webpki 0.101.7", + "thiserror 1.0.69", + "x509-parser 0.16.0", + "yasna", +] + +[[package]] +name = "libp2p-upnp" +version = "0.3.1" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "futures", + "futures-timer", + "igd-next", + "libp2p-core", + "libp2p-swarm", + "tokio", + "tracing", + "void", +] + +[[package]] +name = "libp2p-webrtc" +version = "0.8.0-alpha" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "async-trait", + "bytes", + "futures", + "futures-timer", + "hex", + "if-watch", + "libp2p-core", + "libp2p-identity", + "libp2p-noise", + "libp2p-webrtc-utils", + "multihash", + "rand 0.8.5", + "rcgen", + "serde", + "stun 0.6.0", + "thiserror 1.0.69", + "tinytemplate", + "tokio", + "tokio-util", + "tracing", + "webrtc", +] + +[[package]] +name = "libp2p-webrtc-utils" +version = "0.3.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "asynchronous-codec", + "bytes", + "futures", + "hex", + "libp2p-core", + "libp2p-identity", + "libp2p-noise", + "quick-protobuf", + "quick-protobuf-codec 0.3.1 (git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm)", + "rand 0.8.5", + "serde", + "sha2", + "thiserror 1.0.69", + "tinytemplate", + "tracing", +] + +[[package]] +name = "libp2p-webrtc-websys" +version = "0.4.0-alpha.2" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "bytes", + "futures", + "getrandom 0.2.16", + "hex", + "js-sys", + "libp2p-core", + "libp2p-identity", + "libp2p-webrtc-utils", + "send_wrapper 0.6.0", + "thiserror 1.0.69", + "tracing", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "libp2p-websocket" +version = "0.44.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "either", + "futures", + "futures-rustls", + "libp2p-core", + "libp2p-identity", + "parking_lot", + "pin-project-lite", + "rw-stream-sink", + "soketto", + "thiserror 1.0.69", + "tracing", + "url", + "webpki-roots", +] + +[[package]] +name = "libp2p-websocket-websys" +version = "0.4.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "bytes", + "futures", + "js-sys", + "libp2p-core", + "parking_lot", + "send_wrapper 0.6.0", + "thiserror 1.0.69", + "tracing", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "libp2p-yamux" +version = "0.46.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "either", + "futures", + "libp2p-core", + "thiserror 1.0.69", + "tracing", + "yamux 0.12.1", + "yamux 0.13.4", +] + +[[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.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "litemap" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" + +[[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.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown", +] + +[[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 = "lzma-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" +dependencies = [ + "byteorder", + "crc", +] + +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[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 = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[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.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + +[[package]] +name = "mockall" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2" +dependencies = [ + "cfg-if", + "downcast", + "fragile", + "mockall_derive", + "predicates", + "predicates-tree", +] + +[[package]] +name = "mockall_derive" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "multiaddr" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe6351f60b488e04c1d21bc69e56b89cb3f5e8f5d22557d6e8031bdfd79b6961" +dependencies = [ + "arrayref", + "byteorder", + "data-encoding", + "libp2p-identity", + "multibase", + "multihash", + "percent-encoding", + "serde", + "static_assertions", + "unsigned-varint", + "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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b430e7953c29dd6a09afc29ff0bb69c6e306329ee6794700aee27b76a1aea8d" +dependencies = [ + "core2", + "serde", + "unsigned-varint", +] + +[[package]] +name = "multistream-select" +version = "0.13.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "bytes", + "futures", + "pin-project", + "smallvec", + "tracing", + "unsigned-varint", +] + +[[package]] +name = "netlink-packet-core" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72724faf704479d67b388da142b186f916188505e7e0b26719019c525882eda4" +dependencies = [ + "anyhow", + "byteorder", + "netlink-packet-utils", +] + +[[package]] +name = "netlink-packet-route" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053998cea5a306971f88580d0829e90f270f940befd7cf928da179d4187a5a66" +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 1.0.69", +] + +[[package]] +name = "netlink-proto" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72452e012c2f8d612410d89eea01e2d9b56205274abb35d53f60200b2ec41d60" +dependencies = [ + "bytes", + "futures", + "log", + "netlink-packet-core", + "netlink-sys", + "thiserror 2.0.12", +] + +[[package]] +name = "netlink-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16c903aa70590cb93691bf97a767c8d1d6122d2cc9070433deb3bbf36ce8bd23" +dependencies = [ + "bytes", + "futures", + "libc", + "log", + "tokio", +] + +[[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", + "memoffset", + "pin-utils", +] + +[[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 = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +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", +] + +[[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 = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "oid-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +dependencies = [ + "asn1-rs 0.5.2", +] + +[[package]] +name = "oid-registry" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9" +dependencies = [ + "asn1-rs 0.6.2", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[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", +] + +[[package]] +name = "p384" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[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.6", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pb-rs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "354a34df9c65b596152598001c0fe3393379ec2db03ae30b9985659422e2607e" +dependencies = [ + "clap 2.34.0", + "env_logger", + "log", + "nom", +] + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", + "hmac", +] + +[[package]] +name = "pem" +version = "3.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" +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 = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[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.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "polling" +version = "3.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix 0.38.44", + "tracing", + "windows-sys 0.59.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.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" + +[[package]] +name = "posemesh-domain" +version = "0.1.0" +source = "git+https://github.com/aukilabs/posemesh.git?rev=a6acafc44ede38afe07c4887b139186358f6d02c#a6acafc44ede38afe07c4887b139186358f6d02c" +dependencies = [ + "async-timer", + "async-trait", + "base64 0.22.1", + "cbindgen", + "console_error_panic_hook", + "futures", + "hex", + "jsonwebtoken", + "libp2p", + "pb-rs", + "posemesh-networking", + "posemesh-runtime", + "posemesh-utils", + "quick-protobuf", + "quick-protobuf-codec 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.17.14", + "rs_merkle", + "serde", + "serde-wasm-bindgen", + "serde_json", + "sha2", + "thiserror 2.0.12", + "tokio", + "tracing", + "tracing-subscriber", + "tracing-wasm", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", +] + +[[package]] +name = "posemesh-networking" +version = "0.1.0" +source = "git+https://github.com/aukilabs/posemesh.git?rev=a6acafc44ede38afe07c4887b139186358f6d02c#a6acafc44ede38afe07c4887b139186358f6d02c" +dependencies = [ + "async-trait", + "cbindgen", + "console_error_panic_hook", + "futures", + "gloo-timers 0.3.0", + "libp2p", + "libp2p-stream", + "libp2p-webrtc", + "libp2p-webrtc-websys", + "libp2p-websocket", + "libp2p-websocket-websys", + "mockall", + "posemesh-runtime", + "posemesh-utils", + "rand 0.8.5", + "serde", + "serde-wasm-bindgen", + "serde_json", + "thiserror 2.0.12", + "tokio", + "tracing", + "tracing-subscriber", + "tracing-wasm", + "wasm-bindgen", + "wasm-bindgen-futures", +] + +[[package]] +name = "posemesh-runtime" +version = "0.1.0" +source = "git+https://github.com/aukilabs/posemesh.git?rev=a6acafc44ede38afe07c4887b139186358f6d02c#a6acafc44ede38afe07c4887b139186358f6d02c" +dependencies = [ + "once_cell", + "tokio", +] + +[[package]] +name = "posemesh-utils" +version = "0.1.0" +source = "git+https://github.com/aukilabs/posemesh.git?rev=a6acafc44ede38afe07c4887b139186358f6d02c#a6acafc44ede38afe07c4887b139186358f6d02c" +dependencies = [ + "futures", + "gloo-timers 0.3.0", + "js-sys", + "tokio", + "tracing", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "predicates" +version = "3.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573" +dependencies = [ + "anstyle", + "predicates-core", +] + +[[package]] +name = "predicates-core" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" + +[[package]] +name = "predicates-tree" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" +dependencies = [ + "predicates-core", + "termtree", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prometheus-client" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "504ee9ff529add891127c4827eb481bd69dc0ebc72e9a682e187db4caa60c3ca" +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.101", +] + +[[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", + "bytes", + "quick-protobuf", + "thiserror 1.0.69", + "unsigned-varint", +] + +[[package]] +name = "quick-protobuf-codec" +version = "0.3.1" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "asynchronous-codec", + "bytes", + "quick-protobuf", + "thiserror 1.0.69", + "unsigned-varint", +] + +[[package]] +name = "quinn" +version = "0.11.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012" +dependencies = [ + "bytes", + "cfg_aliases", + "futures-io", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls 0.23.26", + "socket2", + "thiserror 2.0.12", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcbafbbdbb0f638fe3f35f3c56739f77a8a1d070cb25603226c83339b391472b" +dependencies = [ + "bytes", + "getrandom 0.3.2", + "rand 0.9.1", + "ring 0.17.14", + "rustc-hash", + "rustls 0.23.26", + "rustls-pki-types", + "slab", + "thiserror 2.0.12", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee4e529991f949c5e25755532370b8af5d114acae52326361d68d47af64aa842" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + +[[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 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.2", +] + +[[package]] +name = "rcgen" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52c4f3084aa3bc7dfbba4eff4fab2a54db4324965d8872ab933565e6fbd83bc6" +dependencies = [ + "pem", + "ring 0.16.20", + "time", + "x509-parser 0.15.1", + "yasna", +] + +[[package]] +name = "redox_syscall" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +dependencies = [ + "bitflags 2.9.0", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "resolv-conf" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7c8f7f733062b66dc1c63f9db168ac0b97a9210e247fa90fdc9ad08f51b302" + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "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", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "rs_merkle" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb09b49230ba22e8c676e7b75dfe2887dea8121f18b530ae0ba519ce442d2b21" +dependencies = [ + "sha2", +] + +[[package]] +name = "rtcp" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33648a781874466a62d89e265fee9f17e32bc7d05a256e6cca41bf97eadcd8aa" +dependencies = [ + "bytes", + "thiserror 1.0.69", + "webrtc-util 0.8.1", +] + +[[package]] +name = "rtnetlink" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a552eb82d19f38c3beed3f786bd23aa434ceb9ac43ab44419ca6d67a7e186c0" +dependencies = [ + "futures", + "log", + "netlink-packet-core", + "netlink-packet-route", + "netlink-packet-utils", + "netlink-proto", + "netlink-sys", + "nix", + "thiserror 1.0.69", + "tokio", +] + +[[package]] +name = "rtp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e60482acbe8afb31edf6b1413103b7bca7a65004c423b3c3993749a083994fbe" +dependencies = [ + "bytes", + "rand 0.8.5", + "serde", + "thiserror 1.0.69", + "webrtc-util 0.8.1", +] + +[[package]] +name = "rtp" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47fca9bd66ae0b1f3f649b8f5003d6176433d7293b78b0fce7e1031816bdd99d" +dependencies = [ + "bytes", + "rand 0.8.5", + "serde", + "thiserror 1.0.69", + "webrtc-util 0.8.1", +] + +[[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 = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +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.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.9.0", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +dependencies = [ + "bitflags 2.9.0", + "errno", + "libc", + "linux-raw-sys 0.9.4", + "windows-sys 0.59.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.14", + "rustls-webpki 0.101.7", + "sct", +] + +[[package]] +name = "rustls" +version = "0.23.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0" +dependencies = [ + "once_cell", + "ring 0.17.14", + "rustls-pki-types", + "rustls-webpki 0.103.1", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" +dependencies = [ + "web-time", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.14", + "untrusted 0.9.0", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" +dependencies = [ + "ring 0.17.14", + "rustls-pki-types", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + +[[package]] +name = "rw-stream-sink" +version = "0.4.0" +source = "git+https://github.com/aukilabs/rust-libp2p.git?branch=fix%2Fgossipsub-wasm#9b97c007650c3a3e29cf90b896a159fc3e0e0b5b" +dependencies = [ + "futures", + "pin-project", + "static_assertions", +] + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[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.14", + "untrusted 0.9.0", +] + +[[package]] +name = "sdp" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13254db766b17451aced321e7397ebf0a446ef0c8d2942b6e67a95815421093f" +dependencies = [ + "rand 0.8.5", + "substring", + "thiserror 1.0.69", + "url", +] + +[[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 = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + +[[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" +dependencies = [ + "futures-core", +] + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "serde_json" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "server" +version = "0.1.0" +dependencies = [ + "async-trait", + "futures", + "posemesh-domain", + "posemesh-networking", + "quick-protobuf", + "regex", + "scopeguard", + "serde", + "serde_json", + "tokio", + "tracing", + "tracing-subscriber", + "zip", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simple_asn1" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror 2.0.12", + "time", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" + +[[package]] +name = "smol_str" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +dependencies = [ + "serde", +] + +[[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 0.6.4", + "ring 0.17.14", + "rustc_version", + "sha2", + "subtle", +] + +[[package]] +name = "socket2" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "soketto" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e859df029d160cb88608f5d7df7fb4753fd20fdfb4de5644f3d8b8440841721" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures", + "httparse", + "log", + "rand 0.8.5", + "sha1", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[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.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "stun" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3f371788132e9d623e6eab4ba28aac083763a4133f045e6ebaee5ceb869803d" +dependencies = [ + "base64 0.21.7", + "crc", + "lazy_static", + "md-5", + "rand 0.8.5", + "ring 0.17.14", + "subtle", + "thiserror 1.0.69", + "tokio", + "url", + "webrtc-util 0.8.1", +] + +[[package]] +name = "stun" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28fad383a1cc63ae141e84e48eaef44a1063e9d9e55bcb8f51a99b886486e01b" +dependencies = [ + "base64 0.21.7", + "crc", + "lazy_static", + "md-5", + "rand 0.8.5", + "ring 0.17.14", + "subtle", + "thiserror 1.0.69", + "tokio", + "url", + "webrtc-util 0.9.0", +] + +[[package]] +name = "substring" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86" +dependencies = [ + "autocfg", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[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.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.9.0", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +dependencies = [ + "fastrand", + "getrandom 0.3.2", + "once_cell", + "rustix 1.0.7", + "windows-sys 0.59.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 = "termtree" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[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 = "time" +version = "0.3.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + +[[package]] +name = "time-macros" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "tinyvec" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" +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.44.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "tokio-util" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" +dependencies = [ + "bytes", + "futures-core", + "futures-io", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", + "valuable", +] + +[[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-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "tracing-wasm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4575c663a174420fa2d78f4108ff68f65bf2fbb7dd89f33749b6e826b3626e07" +dependencies = [ + "tracing", + "tracing-subscriber", + "wasm-bindgen", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "turn" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb2ac4f331064513ad510b7a36edc0df555bd61672986607f7c9ff46f98f415" +dependencies = [ + "async-trait", + "base64 0.21.7", + "futures", + "log", + "md-5", + "rand 0.8.5", + "ring 0.17.14", + "stun 0.5.1", + "thiserror 1.0.69", + "tokio", + "tokio-util", + "webrtc-util 0.8.1", +] + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[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 = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[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.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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" +dependencies = [ + "getrandom 0.3.2", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "waitgroup" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1f50000a783467e6c0200f9d10642f4bc424e39efc1b770203e88b488f79292" +dependencies = [ + "atomic-waker", +] + +[[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 = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.101", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +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 = "webrtc" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91e7cf018f7185552bf6a5dd839f4ed9827aea33b746763c9a215f84a0d0b34" +dependencies = [ + "arc-swap", + "async-trait", + "bytes", + "cfg-if", + "hex", + "interceptor", + "lazy_static", + "log", + "rand 0.8.5", + "rcgen", + "regex", + "ring 0.16.20", + "rtcp", + "rtp 0.9.0", + "rustls 0.21.12", + "sdp", + "serde", + "serde_json", + "sha2", + "smol_str", + "stun 0.5.1", + "thiserror 1.0.69", + "time", + "tokio", + "turn", + "url", + "waitgroup", + "webrtc-data", + "webrtc-dtls", + "webrtc-ice", + "webrtc-mdns", + "webrtc-media", + "webrtc-sctp", + "webrtc-srtp", + "webrtc-util 0.8.1", +] + +[[package]] +name = "webrtc-data" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c08e648e10572b9edbe741074e0f4d3cb221aa7cdf9a814ee71606de312f33" +dependencies = [ + "bytes", + "log", + "thiserror 1.0.69", + "tokio", + "webrtc-sctp", + "webrtc-util 0.8.1", +] + +[[package]] +name = "webrtc-dtls" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b140b953f986e97828aa33ec6318186b05d862bee689efbc57af04a243e832" +dependencies = [ + "aes", + "aes-gcm", + "async-trait", + "bincode", + "byteorder", + "cbc", + "ccm", + "der-parser 8.2.0", + "hkdf", + "hmac", + "log", + "p256", + "p384", + "rand 0.8.5", + "rand_core 0.6.4", + "rcgen", + "ring 0.16.20", + "rustls 0.21.12", + "sec1", + "serde", + "sha1", + "sha2", + "subtle", + "thiserror 1.0.69", + "tokio", + "webrtc-util 0.8.1", + "x25519-dalek", + "x509-parser 0.15.1", +] + +[[package]] +name = "webrtc-ice" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1bbd6b3dea22cc6e961e22b012e843d8869e2ac8e76b96e54d4a25e311857ad" +dependencies = [ + "arc-swap", + "async-trait", + "crc", + "log", + "rand 0.8.5", + "serde", + "serde_json", + "stun 0.5.1", + "thiserror 1.0.69", + "tokio", + "turn", + "url", + "uuid", + "waitgroup", + "webrtc-mdns", + "webrtc-util 0.8.1", +] + +[[package]] +name = "webrtc-mdns" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce981f93104a8debb3563bb0cedfe4aa2f351fdf6b53f346ab50009424125c08" +dependencies = [ + "log", + "socket2", + "thiserror 1.0.69", + "tokio", + "webrtc-util 0.8.1", +] + +[[package]] +name = "webrtc-media" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "280017b6b9625ef7329146332518b339c3cceff231cc6f6a9e0e6acab25ca4af" +dependencies = [ + "byteorder", + "bytes", + "rand 0.8.5", + "rtp 0.10.0", + "thiserror 1.0.69", +] + +[[package]] +name = "webrtc-sctp" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df75ec042002fe995194712cbeb2029107a60a7eab646f1b789eb1be94d0e367" +dependencies = [ + "arc-swap", + "async-trait", + "bytes", + "crc", + "log", + "rand 0.8.5", + "thiserror 1.0.69", + "tokio", + "webrtc-util 0.8.1", +] + +[[package]] +name = "webrtc-srtp" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1db1f36c1c81e4b1e531c0b9678ba0c93809e196ce62122d87259bb71c03b9f" +dependencies = [ + "aead", + "aes", + "aes-gcm", + "byteorder", + "bytes", + "ctr", + "hmac", + "log", + "rtcp", + "rtp 0.9.0", + "sha1", + "subtle", + "thiserror 1.0.69", + "tokio", + "webrtc-util 0.8.1", +] + +[[package]] +name = "webrtc-util" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e85154ef743d9a2a116d104faaaa82740a281b8b4bed5ee691a2df6c133d873" +dependencies = [ + "async-trait", + "bitflags 1.3.2", + "bytes", + "ipnet", + "lazy_static", + "libc", + "log", + "nix", + "rand 0.8.5", + "thiserror 1.0.69", + "tokio", + "winapi", +] + +[[package]] +name = "webrtc-util" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc8d9bc631768958ed97b8d68b5d301e63054ae90b09083d43e2fefb939fd77e" +dependencies = [ + "async-trait", + "bitflags 1.3.2", + "bytes", + "ipnet", + "lazy_static", + "libc", + "log", + "nix", + "portable-atomic", + "rand 0.8.5", + "thiserror 1.0.69", + "tokio", + "winapi", +] + +[[package]] +name = "widestring" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" + +[[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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.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.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efc5cf48f83140dcaab716eeaea345f9e93d0018fb81162753a3f76c3397b538" +dependencies = [ + "windows-core", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dcc5b895a6377f1ab9fa55acedab1fd5ac0db66ad1e6c7f47e28a22e446a5dd" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.6", +] + +[[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.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e27d6ad3dac991091e4d35de9ba2d2d00647c5d0fc26c5496dee55984ae111b" +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 = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.9.0", +] + +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[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 0.6.4", + "serde", + "zeroize", +] + +[[package]] +name = "x509-parser" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7069fba5b66b9193bd2c5d3d4ff12b839118f6bcbef5328efafafb5395cf63da" +dependencies = [ + "asn1-rs 0.5.2", + "data-encoding", + "der-parser 8.2.0", + "lazy_static", + "nom", + "oid-registry 0.6.1", + "ring 0.16.20", + "rusticata-macros", + "thiserror 1.0.69", + "time", +] + +[[package]] +name = "x509-parser" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" +dependencies = [ + "asn1-rs 0.6.2", + "data-encoding", + "der-parser 9.0.0", + "lazy_static", + "nom", + "oid-registry 0.7.1", + "rusticata-macros", + "thiserror 1.0.69", + "time", +] + +[[package]] +name = "xml-rs" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62ce76d9b56901b19a74f19431b0d8b3bc7ca4ad685a746dfd78ca8f4fc6bda" + +[[package]] +name = "xmltree" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb" +dependencies = [ + "xml-rs", +] + +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + +[[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 0.8.5", + "static_assertions", +] + +[[package]] +name = "yamux" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17610762a1207ee816c6fadc29220904753648aba0a9ed61c7b8336e80a559c4" +dependencies = [ + "futures", + "log", + "nohash-hasher", + "parking_lot", + "pin-project", + "rand 0.8.5", + "static_assertions", + "web-time", +] + +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", +] + +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", + "synstructure 0.13.2", +] + +[[package]] +name = "zerocopy" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", + "synstructure 0.13.2", +] + +[[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.101", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "zip" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dcb24d0152526ae49b9b96c1dcf71850ca1e0b882e4e28ed898a93c41334744" +dependencies = [ + "aes", + "arbitrary", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils", + "deflate64", + "flate2", + "getrandom 0.3.2", + "hmac", + "indexmap", + "lzma-rs", + "memchr", + "pbkdf2", + "sha1", + "time", + "xz2", + "zeroize", + "zopfli", + "zstd", +] + +[[package]] +name = "zopfli" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edfc5ee405f504cd4984ecc6f14d02d55cfda60fa4b689434ef4102aae150cd7" +dependencies = [ + "bumpalo", + "crc32fast", + "log", + "simd-adler32", +] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.15+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/server/Cargo.toml b/server/Cargo.toml new file mode 100644 index 0000000..2c8f294 --- /dev/null +++ b/server/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "server" +version = "0.1.0" +edition = "2021" + +[dependencies] +posemesh-networking = { git = "https://github.com/aukilabs/posemesh.git", rev = "a6acafc44ede38afe07c4887b139186358f6d02c" } +futures = "0.3.30" +posemesh-domain = { git = "https://github.com/aukilabs/posemesh.git", rev = "a6acafc44ede38afe07c4887b139186358f6d02c" } +tracing = "0.1.40" +tracing-subscriber = "0.3.18" +tokio = "1.44.0" +quick-protobuf = "0.8.1" +serde = "1.0.210" +serde_json = "1.0.128" +zip = "2.2.3" +regex = "1.10.3" +scopeguard = "1.2.0" +async-trait = "0.1.88" diff --git a/server/go.mod b/server/go.mod deleted file mode 100644 index 6899a38..0000000 --- a/server/go.mod +++ /dev/null @@ -1,27 +0,0 @@ -module github.com/aukilabs/reconstruction - -go 1.21.5 - -require ( - github.com/go-chi/chi v1.5.5 - github.com/google/uuid v1.6.0 - github.com/lestrrat-go/jwx v1.2.29 -) - -require ( - go.opentelemetry.io/otel v1.28.0 // indirect - go.opentelemetry.io/otel/trace v1.28.0 // indirect -) - -require ( - github.com/aukilabs/go-tooling v0.15.8 - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect - github.com/goccy/go-json v0.10.2 // indirect - github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect - github.com/lestrrat-go/blackmagic v1.0.2 // indirect - github.com/lestrrat-go/httpcc v1.0.1 // indirect - github.com/lestrrat-go/iter v1.0.2 // indirect - github.com/lestrrat-go/option v1.0.1 // indirect - github.com/pkg/errors v0.9.1 // indirect - golang.org/x/crypto v0.31.0 // indirect -) diff --git a/server/go.sum b/server/go.sum deleted file mode 100644 index 024000b..0000000 --- a/server/go.sum +++ /dev/null @@ -1,95 +0,0 @@ -github.com/aukilabs/go-tooling v0.15.8 h1:BLrdW3KGrkLQAkxjuZbqPzC1p+LJfbOGLlXsC52FCyo= -github.com/aukilabs/go-tooling v0.15.8/go.mod h1:Cs1/wCUK1l1kBtvIY7fASXGGkyF6DX0IKIdh8TjcQFY= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= -github.com/go-chi/chi v1.5.5 h1:vOB/HbEMt9QqBqErz07QehcOKHaWFtuj87tTDVz2qXE= -github.com/go-chi/chi v1.5.5/go.mod h1:C9JqLr3tIYjDOZpzn+BCuxY8z8vmca43EeMgyZt7irw= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= -github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= -github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= -github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= -github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= -github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= -github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= -github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx v1.2.29 h1:QT0utmUJ4/12rmsVQrJ3u55bycPkKqGYuGT4tyRhxSQ= -github.com/lestrrat-go/jwx v1.2.29/go.mod h1:hU8k2l6WF0ncx20uQdOmik/Gjg6E3/wIRtXSNFeZuB8= -github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= -github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/server/helper.go b/server/helper.go deleted file mode 100644 index 985dee2..0000000 --- a/server/helper.go +++ /dev/null @@ -1,976 +0,0 @@ -package main - -import ( - "bytes" - "context" - "encoding/json" - "slices" - "sort" - - "fmt" - "io" - - "mime" - "mime/multipart" - "net/http" - "net/textproto" - "os" - "os/exec" - "path" - "regexp" - "strconv" - "strings" - "sync" - "time" - - "github.com/aukilabs/go-tooling/pkg/errors" - "github.com/aukilabs/go-tooling/pkg/logs" - "github.com/google/uuid" - "github.com/lestrrat-go/jwx/jwt" -) - -type ExpectedOutput struct { - FilePath string // relative to job folder - Name string - DataType string - Optional bool -} - -type jobList struct { - lock sync.RWMutex - list map[string]job -} - -func (js *jobList) AddJob(j *job) { - js.lock.Lock() - defer js.lock.Unlock() - - js.list[j.ID] = *j -} - -func ParseStatusFromManifest(manifestPath string) (string, error) { - content, err := os.ReadFile(manifestPath) - if err != nil { - return "", err - } - - var parsedManifest map[string]interface{} - if err := json.Unmarshal(content, &parsedManifest); err != nil { - return "", err - } - - status, ok := parsedManifest["jobStatus"].(string) - if !ok { - return "", fmt.Errorf("cannot parse jobStatus in existing manifest json file: %s", manifestPath) - } - return status, nil -} - -func WriteJobManifestFile(j *job, status string) { - if status == "failed" { - // If python script has already written a manifest with status "failed", don't overwrite it - statusFromManifest, err := ParseStatusFromManifest(path.Join(j.JobPath, "job_manifest.json")) - - if err == nil && statusFromManifest == "failed" { - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("job %s python script has already written a failed manifest, won't overwrite.", j.ID) - } else { - WriteFailedJobManifestFile(j, "Reconstruction job script failed") - } - - } else if status == "processing" { - progress := 0 - WriteJobManifestFileHelper(j, status, progress, "Request received by reconstruction server") - } else { - return - } - - err := UploadJobManifestToDomain(j) - if err != nil { - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Error(errors.New("failed to upload job manifest to domain").Wrap(err)) - } -} - -func (js *jobList) UpdateJob(id string, status string) { - js.lock.Lock() - j, ok := js.list[id] - if ok { - j.Status = status - js.list[id] = j - } - js.lock.Unlock() - - if ok { - WriteJobManifestFile(&j, status) - } -} - -func (js *jobList) List() []job { - js.lock.RLock() - defer js.lock.RUnlock() - - logs.Info("job list count: ", len(js.list)) - logs.Info("job list null? ", js.list == nil) - // log.Println("job list count: ", len(js.list)) - // log.Println("job list null? ", js.list == nil) - - var jobs []job - for _, j := range js.list { - jobs = append(jobs, j) - logs.Info("APPEND! new job list count: ", len(jobs)) - // log.Println("APPEND! new job list count: ", len(jobs)) - } - logs.Info("job list null? ", js.list == nil) - // log.Println("job list null? ", js.list == nil) - return jobs -} - -var jobs = jobList{ - lock: sync.RWMutex{}, - list: map[string]job{}, -} - -type JobMetadata struct { - ID string `json:"id"` - Name string `json:"name"` - DomainID string `json:"domain_id"` - ProcessingType string `json:"processing_type"` - CreatedAt time.Time `json:"created_at"` - DomainServerURL string `json:"domain_server_url"` - ReconstructionServerURL string `json:"reconstruction_server_url"` - AccessToken string `json:"-"` - DataIDs []string `json:"data_ids"` -} - -type job struct { - JobMetadata - JobPath string `json:"job_path"` - Status string `json:"status"` - UploadedDataIDs map[string]string `json:"-"` -} - -type JobRequestData struct { - DataIDs []string `json:"data_ids"` - DomainID string `json:"domain_id"` - AccessToken string `json:"access_token"` - ProcessingType string `json:"processing_type"` - DomainServerURL string `json:"domain_server_url"` // Optional. Default: "issuer" of the incoming request, since jobs are triggered via the domain server. -} - -type DomainDataMetadata struct { - ID string `json:"id"` - DomainID string `json:"domain_id"` - EditableDomainDataMetadata -} - -type EditableDomainDataMetadata struct { - Name string `json:"name"` - DataType string `json:"data_type"` -} - -type DomainData struct { - DomainDataMetadata `` - Data io.ReadCloser `json:"-"` -} - -type PostDomainDataResponse struct { - Data []DomainDataMetadata `json:"data"` -} - -var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"") - -var MaxBytesError = &http.MaxBytesError{} - -func escapeQuotes(s string) string { - return quoteEscaper.Replace(s) -} - -func WriteScanDataSummary(datasetsRootPath string, allScanFolders []os.DirEntry, summaryJsonPath string) error { - scanCount := 0 - totalFrameCount := 0 - totalScanDuration := 0.0 - scanDurations := []float64{} - uniquePortalIDs := []string{} - portalSizes := []float64{} // Size list is used when saving manifest, to output same physical size, without asking domain server - devicesUsed := []string{} - appVersionsUsed := []string{} - - for _, scanFolder := range allScanFolders { - if !scanFolder.IsDir() { - continue - } - - manifestPath := path.Join(datasetsRootPath, scanFolder.Name(), "Manifest.json") - if _, err := os.Stat(manifestPath); os.IsNotExist(err) { - continue - } - - manifestData, err := os.ReadFile(manifestPath) - if err != nil { - return err - } - - var manifest map[string]interface{} - if err := json.Unmarshal(manifestData, &manifest); err != nil { - return err - } - - scanCount++ - - frameCount := int(manifest["frameCount"].(float64)) - duration := manifest["duration"].(float64) - totalFrameCount += frameCount - totalScanDuration += duration - scanDurations = append(scanDurations, duration) - - if portals, ok := manifest["portals"].([]interface{}); ok { - for _, portal := range portals { - if portalMap, ok := portal.(map[string]interface{}); ok { - if portalID, ok := portalMap["shortId"].(string); ok { - if !slices.Contains(uniquePortalIDs, portalID) { - uniquePortalIDs = append(uniquePortalIDs, portalID) - portalSizes = append(portalSizes, portalMap["physicalSize"].(float64)) - } - } - } - } - } - - device := "unknown" - if manifest["brand"] != nil && manifest["model"] != nil && manifest["systemName"] != nil && manifest["systemVersion"] != nil { - device = manifest["brand"].(string) + " " + manifest["model"].(string) + " " + manifest["systemName"].(string) + " " + manifest["systemVersion"].(string) - device = strings.TrimSpace(device) - } - if !slices.Contains(devicesUsed, device) { - devicesUsed = append(devicesUsed, device) - } - - appVersion := "unknown" - if manifest["appVersion"] != nil && manifest["buildId"] != nil { - appVersion = manifest["appVersion"].(string) + " (build " + manifest["buildId"].(string) + ")" - } - if !slices.Contains(appVersionsUsed, appVersion) { - appVersionsUsed = append(appVersionsUsed, appVersion) - } - } - - sort.Float64s(scanDurations) - shortestScanDuration := scanDurations[0] - longestScanDuration := scanDurations[len(scanDurations)-1] - medianScanDuration := scanDurations[len(scanDurations)/2] - - averageScanDuration := totalScanDuration / float64(len(allScanFolders)) - averageScanFrameCount := float64(totalFrameCount) / float64(len(allScanFolders)) - averageScanFrameRate := float64(totalFrameCount) / totalScanDuration - - summary := map[string]interface{}{ - "scanCount": scanCount, - "totalFrameCount": totalFrameCount, - "totalScanDuration": totalScanDuration, - "averageScanDuration": averageScanDuration, - "averageScanFrameCount": averageScanFrameCount, - "averageFrameRate": averageScanFrameRate, - "shortestScanDuration": shortestScanDuration, - "longestScanDuration": longestScanDuration, - "medianScanDuration": medianScanDuration, - "portalCount": len(uniquePortalIDs), - "portalIDs": uniquePortalIDs, - "portalSizes": portalSizes, - "deviceVersionsUsed": devicesUsed, - "appVersionsUsed": appVersionsUsed, - } - - summaryJson, err := json.MarshalIndent(summary, "", " ") - if err != nil { - return err - } - - return os.WriteFile(summaryJsonPath, summaryJson, 0644) -} - -func WriteDomainData(mw *multipart.Writer, data *DomainData) error { - h := make(textproto.MIMEHeader) - h.Set("Content-Type", "application/octet-stream") - h.Set("Content-Disposition", - fmt.Sprintf( - `form-data; name="%s"; data-type="%s"; id="%s"; domain-id="%s"`, - escapeQuotes(data.Name), - escapeQuotes(data.DataType), - escapeQuotes(data.ID), - escapeQuotes(data.DomainID), - ), - ) - fw, err := mw.CreatePart(h) - if err != nil { - return err - } - _, err = io.Copy(fw, data.Data) - return err -} - -func WriteFailedJobManifestFile(j *job, errorMessage string) error { - pythonSnippet := ` -from utils.data_utils import save_failed_manifest_json; -save_failed_manifest_json('` + j.JobPath + `/job_manifest.json', '` + j.JobPath + `', '` + errorMessage + `') -` - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("writing failed manifest, error message: %s", errorMessage) - - cmd := exec.Command("python3", "-c", pythonSnippet) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - - return cmd.Run() -} - -func WriteJobManifestFileHelper(j *job, status string, progress int, statusDetails string) error { - pythonSnippet := ` -from utils.data_utils import save_manifest_json; -save_manifest_json({}, - '` + j.JobPath + `/job_manifest.json', - '` + j.JobPath + `', - job_status='` + status + `', - job_progress=` + strconv.Itoa(progress) + `, - job_status_details='` + statusDetails + `' -)` - - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Info("Writing manifest with status: ", status, ", progress: ", progress, ", status details: ", statusDetails) - - cmd := exec.Command("python3", "-c", pythonSnippet) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - - return cmd.Run() -} - -func UploadJobManifestToDomain(j *job) error { - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("Upload job manifest to domain, for job") - - output := ExpectedOutput{ - FilePath: "job_manifest.json", - Name: "refined_manifest", - DataType: "refined_manifest_json", - Optional: false, - } - - return UploadOutputToDomain(j, output) -} - -func UploadRefinedOutputsToDomain(j *job) (int, error) { - refinedOutput := path.Join("refined", "global") - expectedOutputs := []ExpectedOutput{ - { - FilePath: path.Join(refinedOutput, "refined_manifest.json"), - Name: "refined_manifest", - DataType: "refined_manifest_json", - Optional: false, - }, - { - FilePath: path.Join(refinedOutput, "RefinedPointCloudReduced.ply"), - Name: "refined_pointcloud", - DataType: "refined_pointcloud_ply", - Optional: false, - }, - { - FilePath: path.Join(refinedOutput, "RefinedPointCloud.ply.drc"), - Name: "refined_pointcloud_full_draco", - DataType: "refined_pointcloud_ply_draco", - Optional: true, - }, - /*{ - FilePath: path.Join(refinedOutput, "occlusion", "meshes.obj"), - Name: "occlusionmesh_v1", - DataType: "obj", - },*/ - } - - outputCount := 0 - for _, output := range expectedOutputs { - if _, err := os.Stat(path.Join(j.JobPath, output.FilePath)); !os.IsNotExist(err) { - outputCount++ - } - } - - // Upload manifest using PUT since it already exists from start of the job - if err := UploadOutputToDomain(j, expectedOutputs[0]); err != nil { - return outputCount, errors.New("failed to upload refined manifest to domain").Wrap(err) - } - - if err := UploadOutputsToDomain(j, expectedOutputs[1:]); err != nil { - return outputCount, errors.New("failed to upload refined outputs to domain").Wrap(err) - } - - return outputCount, nil -} - -func UploadOutputsToDomain(j *job, expectedOutputs []ExpectedOutput) error { - firstErr := error(nil) - for _, output := range expectedOutputs { - if err := UploadOutputToDomain(j, output); err != nil { - if firstErr == nil { - firstErr = err - } - } - } - return firstErr -} - -func UploadOutputToDomain(j *job, output ExpectedOutput) error { - if err := UploadOutputToDomainHelper(j, output); err != nil { - if output.Optional { - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("Uploading output %s failed (but won't fail the job): %s", output.Name, err.Error()) - return nil - } - return err - } - return nil -} - -func UploadOutputToDomainHelper(j *job, output ExpectedOutput) error { - outputPath := j.JobPath - if _, err := os.Stat(outputPath); os.IsNotExist(err) { - return err - } - - f, err := os.Open(path.Join(outputPath, output.FilePath)) - if err != nil { - return fmt.Errorf("failed to open output file %s: %s", output.FilePath, err.Error()) - } - defer f.Close() - - nameSuffix := j.CreatedAt.Format("2006-01-02_15-04-05") - domainData := DomainData{ - DomainDataMetadata: DomainDataMetadata{ - EditableDomainDataMetadata: EditableDomainDataMetadata{ - Name: output.Name + "_" + nameSuffix, - DataType: output.DataType, - }, - DomainID: j.DomainID, - }, - Data: f, - } - - httpMethod := http.MethodPost - alreadyUploadedID := j.UploadedDataIDs[output.Name+"."+output.DataType] - if alreadyUploadedID != "" { - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("%s.%s already uploaded. Updating it instead.", output.Name, output.DataType) - domainData.ID = alreadyUploadedID - httpMethod = http.MethodPut - } - - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - - if err := WriteDomainData(writer, &domainData); err != nil { - return fmt.Errorf("failed to write domain data to message body: %s", err.Error()) - } - - if err := writer.Close(); err != nil { - return err - } - - reqUrl := j.DomainServerURL + "/api/v1/domains/" + j.DomainID + "/data" - req, err := http.NewRequest(httpMethod, reqUrl, body) - if err != nil { - return err - } - req.Header.Set("Content-Type", writer.FormDataContentType()) - req.Header.Set("Authorization", "Bearer "+j.AccessToken) - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return fmt.Errorf("domain server returned status %d", resp.StatusCode) - } - - responseBody, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("Uploaded domain data! response: %s", string(responseBody)) - var parsedResp PostDomainDataResponse - if err := json.Unmarshal(responseBody, &parsedResp); err != nil { - return err - } - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("Uploaded domain data! parsed response: %+v", parsedResp) - j.UploadedDataIDs[output.Name+"."+output.DataType] = parsedResp.Data[0].ID - return nil -} - -func DownloadDomainDataFromDomain(ctx context.Context, j *job, ids ...string) error { - - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("downloading %d data from domain", len(ids)) - if len(ids) == 0 { - return errors.New("no data ids provided") - } - - scan_data_ids := strings.Join(ids, ",") - - req, err := http.NewRequestWithContext(ctx, http.MethodGet, j.DomainServerURL+"/api/v1/domains/"+j.DomainID+"/data?ids="+scan_data_ids, nil) - if err != nil { - return err - } - req.Header.Add("Authorization", "Bearer "+j.AccessToken) - req.Header.Add("Accept", "multipart/form-data") - - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Info("Downloading data from domain, request:\n", req) - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return fmt.Errorf("domain server returned status %d", resp.StatusCode) - } - - _, params, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) - if err != nil { - return err - } - var i int - mr := multipart.NewReader(resp.Body, params["boundary"]) - for { - part, err := mr.NextPart() - if err != nil { - if err == io.EOF { - break - } - return err - } - - meta, err := ReadDomainDataMetadata(part) - if err != nil { - return err - } - - // For now match multiple data objects from same scan by the timestamp in the name: - // dmt_manifest_2024-09-27_01-13-50 - // dmt_pointcloud_2024-09-27_01-13-50 - // dmt_arposes_2024-09-27_01-13-50 - // dmt_portal_detections_2024-09-27_01-13-50 - // dmt_intrinsics_2024-09-27_01-13-50 - // dmt_frames_2024-09-27_01-13-50 - - dateTimeRegex := regexp.MustCompile(`\d{4}-\d{2}-\d{2}[_-]\d{2}-\d{2}-\d{2}`) - scanFolderName := "" - if match := dateTimeRegex.FindString(meta.Name); match != "" { - scanFolderName = match - } - - var fileName string - switch meta.DataType { - case "dmt_manifest_json": - fileName = "Manifest.json" - case "dmt_featurepoints_ply", "dmt_pointcloud_ply": - fileName = "FeaturePoints.ply" - case "dmt_arposes_csv": - fileName = "ARposes.csv" - case "dmt_portal_detections_csv", "dmt_observations_csv": - fileName = "PortalDetections.csv" - case "dmt_intrinsics_csv", "dmt_cameraintrinsics_csv": - fileName = "CameraIntrinsics.csv" - case "dmt_frames_csv": - fileName = "Frames.csv" - case "dmt_gyro_csv": - fileName = "Gyro.csv" - case "dmt_accel_csv": - fileName = "Accel.csv" - case "dmt_gyroaccel_csv": - fileName = "gyro_accel.csv" - case "dmt_recording_mp4": - fileName = "Frames.mp4" - default: - logs.Infof("unknown domain data type: %s", meta.DataType) - fileName = meta.Name + "." + meta.DataType - } - - scanFolder := path.Join(j.JobPath, "datasets", scanFolderName) - if err := os.MkdirAll(scanFolder, 0755); err != nil { - return err - } - - f, err := os.Create(path.Join(scanFolder, fileName)) - if err != nil { - return err - } - defer f.Close() - - if _, err := io.Copy(f, part); err != nil { - return err - } - - i++ - } - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("downloaded %d data objects from domain", i) - return nil -} - -func ReadDispositionParams(part *multipart.Part) (map[string]string, error) { - d := part.Header.Get("Content-Disposition") - var err error - _, dispositionParams, err := mime.ParseMediaType(d) - if err != nil { - return nil, err - } - return dispositionParams, nil -} - -func ReadDomainDataMetadata(part *multipart.Part) (*DomainDataMetadata, error) { - dispositionParams, err := ReadDispositionParams(part) - if err != nil { - return nil, err - } - return &DomainDataMetadata{ - EditableDomainDataMetadata: EditableDomainDataMetadata{ - Name: dispositionParams["name"], - DataType: dispositionParams["data-type"], - }, - DomainID: dispositionParams["domain-id"], - }, nil -} - -func ReadJobRequestFromJson(requestJson string) (*JobRequestData, error) { - - var jobRequest JobRequestData - if err := json.Unmarshal([]byte(requestJson), &jobRequest); err != nil { - return nil, err - } - - // Debug printing the extracted metadata - logs.Debug("Parsed Metadata:\n") - logs.Debug("Data IDs: %s\n", jobRequest.DataIDs) - logs.Debug("DomainID: %s\n", jobRequest.DomainID) - logs.Debug("Processing Type: %s\n", jobRequest.ProcessingType) - logs.Debug("Access Token: %s\n", jobRequest.AccessToken) - logs.Debug("Domain Server URL: %s\n", jobRequest.DomainServerURL) - - return &jobRequest, nil -} - -func CreateJobMetadata(dirPath string, requestJson string, reconstructionServerURL string) (*job, error) { - - logs.Info("Will mkdir path ", dirPath) - if err := os.MkdirAll(dirPath, 0750); err != nil { - return nil, err - } - - logs.Info("Refinement job requested") - jobRequest, err := ReadJobRequestFromJson(requestJson) - - if err != nil { - return nil, err - } - - logs.WithTag("domain_id", jobRequest.DomainID). - Info("Parsing domain access token: ", jobRequest.AccessToken) - t, err := jwt.ParseString(jobRequest.AccessToken, jwt.WithValidate(false)) - if err != nil { - return nil, errors.New("Error parsing domain access token from job request"). - WithTag("domain_id", jobRequest.DomainID).Wrap(err) - } - - domainServerURL := jobRequest.DomainServerURL - if domainServerURL == "" { - domainServerURL = t.Issuer() - if domainServerURL == "" { - return nil, errors.New("domain server URL is not set in job request or domain access token") - } - logs.WithTag("domain_id", jobRequest.DomainID). - Info("Using domain server URL from domain access token: ", domainServerURL) - - } else { - logs.WithTag("domain_id", jobRequest.DomainID). - Info("Using domain server URL from job request: ", domainServerURL) - } - - startTime := time.Now() - jobID := uuid.NewString() - jobName := "job_" + jobID - - j := job{ - JobMetadata: JobMetadata{ - CreatedAt: startTime, - ID: jobID, - Name: jobName, - DomainID: jobRequest.DomainID, - DataIDs: jobRequest.DataIDs, - ProcessingType: jobRequest.ProcessingType, - DomainServerURL: domainServerURL, - ReconstructionServerURL: reconstructionServerURL, - AccessToken: jobRequest.AccessToken, - }, - Status: "started", - UploadedDataIDs: map[string]string{}, - JobPath: path.Join(dirPath, jobRequest.DomainID, jobName), - } - - if err := os.MkdirAll(j.JobPath, 0755); err != nil { - return nil, errors.New("failed to create job directory").Wrap(err). - WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID) - } - - // write the requestJson to file, for debugging purposes - requestFile := path.Join(j.JobPath, "job_request.json") - if err := os.WriteFile(requestFile, []byte(requestJson), 0644); err != nil { - return nil, errors.New("failed to write jobrequest json file to disk").Wrap(err). - WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID) - } - - // write job metadata to file, gets added into refined manifest file - metadataFile := path.Join(j.JobPath, "job_metadata.json") - jobMetadataJson, err := json.Marshal(j.JobMetadata) - if err != nil { - return nil, errors.New("failed to marshal job metadata to json").Wrap(err). - WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID) - } - if err := os.WriteFile(metadataFile, jobMetadataJson, 0644); err != nil { - return nil, errors.New("failed to write job metadata json file to disk").Wrap(err). - WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID) - } - - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("Job Request File: %s", requestFile) - - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("Job Metadata File: %s", metadataFile) - - jobs.AddJob(&j) - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("Job added to job list: %s", j.ID) - - return &j, nil -} - -func executeJob(j *job) { - - // Write in-progress manifest as soon as job starts. - // DMT uses this to show job status to the user. - WriteJobManifestFile(j, "processing") - - // Download domain data in batches of 20 ids - batchSize := 20 - for i := 0; i < len(j.DataIDs); i += batchSize { - end := i + batchSize - if end > len(j.DataIDs) { - end = len(j.DataIDs) - } - batch := j.DataIDs[i:end] - - if err := DownloadDomainDataFromDomain(context.Background(), j, batch...); err != nil { - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Error(errors.Newf("failed to download data batch %d-%d", i, end).Wrap(err)) - jobs.UpdateJob(j.ID, "failed") - return - } - } - - refinementPython := "main.py" - - outputPath := path.Join(j.JobPath, "refined") - logFilePath := path.Join(j.JobPath, "log.txt") - - params := []string{ - refinementPython, - "--mode", j.ProcessingType, - "--job_root_path", j.JobPath, - "--output", outputPath, - "--domain_id", j.DomainID, - "--job_id", j.Name, - "--scans"} - - datasetsRootPath := path.Join(j.JobPath, "datasets") - if allScanFolders, err := os.ReadDir(datasetsRootPath); err != nil { - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Error(errors.Newf("failed to to read input directory").Wrap(err)) - jobs.UpdateJob(j.ID, "failed") - return - } else { - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("read %d scan folders", len(allScanFolders)) - - scanDataSummaryPath := path.Join(j.JobPath, "scan_data_summary.json") - WriteScanDataSummary(datasetsRootPath, allScanFolders, scanDataSummaryPath) - - for _, folder := range allScanFolders { - params = append(params, folder.Name()) - } - } - - startTime := time.Now() - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Debugf("executing main.py with params: %s", params) - cmd := exec.Command("python3", params...) - - // Create log file - logFile, err := os.Create(logFilePath) - if err != nil { - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Error(errors.Newf("failed to create log file").Wrap(err)) - jobs.UpdateJob(j.ID, "failed") - return - } - defer logFile.Close() - - // Write to both log file and stdout/stderr - stdoutWriter := io.MultiWriter(logFile, os.Stdout) - stderrWriter := io.MultiWriter(logFile, os.Stderr) - cmd.Stdout = stdoutWriter - cmd.Stderr = stderrWriter - - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("started, logging to %s", logFilePath) - - // Run the refinement python - if err := cmd.Start(); err != nil { - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Error(errors.Newf("job failed to start").Wrap(err)) - jobs.UpdateJob(j.ID, "failed") - return - } - - // Monitor progress in a separate goroutine - progressDone := make(chan bool) - go func() { - refinedPath := path.Join(outputPath, "local") - - for { - select { - case <-progressDone: - return - default: - // Get total number of datasets - datasetFolders, err := os.ReadDir(datasetsRootPath) - if err != nil { - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Error(errors.Newf("Error reading datasets directory").Wrap(err)) - return - } - totalCount := len(datasetFolders) - - // Check number of completed datasets by matching dataset names - refinedCount := 0 - for _, dataset := range datasetFolders { - if _, err := os.Stat(path.Join(refinedPath, dataset.Name())); err == nil { - refinedCount++ - } - } - refinedCount-- // Last folder created is still refining, remove it - if refinedCount < 0 { - refinedCount = 0 // Just in case - } - progress := int((float64(refinedCount) / float64(totalCount)) * 100) - if progress > 100 { - progress = 100 - } - - // Update manifest with current progress - statusText := fmt.Sprintf("Processed %d of %d scans", refinedCount, totalCount) - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("progress: %d%% - %s", progress, statusText) - - err = WriteJobManifestFileHelper(j, "processing", progress, statusText) - if err != nil { - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Error(errors.Newf("failed to write job manifest").Wrap(err)) - } - - err = UploadJobManifestToDomain(j) - if err != nil { - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Error(errors.Newf("failed to upload job manifest").Wrap(err)) - } - - time.Sleep(30 * time.Second) - } - } - }() - - if err := cmd.Wait(); err != nil { - progressDone <- true - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Error(errors.Newf("job failed").Wrap(err)) - jobs.UpdateJob(j.ID, "failed") - return - } - progressDone <- true - - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("Refinement python script finished.") - - timeTaken := time.Since(startTime) - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("Refinement algorithm took %s", timeTaken) - - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("Going to upload results to domain %s", j.DomainID) - - if _, err := UploadRefinedOutputsToDomain(j); err != nil { - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Error(errors.New("failed to upload refined outputs to domain").Wrap(err)) - jobs.UpdateJob(j.ID, "failed") - return - } - - // remove the job directory (disable for now) - // TODO: keep scan inputs downloaded in some local cache while still setting up the domain. - /*if err := os.RemoveAll(j.JobPath); err != nil { - log.Printf("job %s failed to remove output directory: %s", j.ID, err) - } - */ - - logs.WithTag("job_id", j.ID). - WithTag("domain_id", j.DomainID). - Infof("job succeeded!") - jobs.UpdateJob(j.ID, "succeeded") -} diff --git a/server/main.go b/server/main.go deleted file mode 100644 index 4e65e1e..0000000 --- a/server/main.go +++ /dev/null @@ -1,130 +0,0 @@ -package main - -import ( - "encoding/json" - "flag" - "io" - - "net/http" - "net/http/httputil" - "reflect" - "sync" - - "github.com/aukilabs/go-tooling/pkg/errors" - "github.com/aukilabs/go-tooling/pkg/logs" - "github.com/go-chi/chi" -) - -// Add a global variable to track if a job is in progress -var ( - jobInProgress bool - jobMutex sync.Mutex -) - -func main() { - - apiKey := flag.String("api-key", "", "API key for the server") - port := flag.String("port", ":8080", "Port to run the server on") - loglevel := flag.String("log-level", "info", "Log Level") - flag.Parse() - - // Configure logging to include file name, line number, and timestamp - logs.SetLevel(logs.ParseLevel(*loglevel)) - logs.Encoder = json.Marshal - - if apiKey == nil || *apiKey == "" { - logs.Fatal(errors.New("API key is required")) - } - // create a new router - r := chi.NewRouter() - - // Endpoint for triggering refinement jobs (from DMT) - r.Post("/jobs", func(w http.ResponseWriter, r *http.Request) { - logs.Info("[POST] /jobs endpoint called") - - debug, _ := httputil.DumpRequest(r, true) - logs.Debug(debug) - - if apiKey != nil && *apiKey != "" { - inApiKey := r.Header.Get("X-API-Key") - if inApiKey != *apiKey { - http.Error(w, "Unauthorized", http.StatusUnauthorized) - return - } - } - - // Check if a job is already in progress - jobMutex.Lock() - if jobInProgress { - jobMutex.Unlock() - logs.Info("Job already in progress, rejecting incoming job request.") - http.Error(w, "Reconstruction server is busy processing another job", http.StatusServiceUnavailable) - return - } - jobInProgress = true - jobMutex.Unlock() - - // Read request body - reqBodyBytes, err := io.ReadAll(r.Body) - if err != nil { - logs.Error(errors.New("Failed to read request body for job request: " + err.Error())) - http.Error(w, err.Error(), http.StatusInternalServerError) - jobMutex.Lock() - jobInProgress = false - jobMutex.Unlock() - return - } - reqBodyString := string(reqBodyBytes) - logs.Infof("Request body: %s", reqBodyString) - - reconstructionServerURL := r.Host - - // Create job metadata - j, err := CreateJobMetadata("jobs", reqBodyString, reconstructionServerURL) - if err != nil { - logs.Error(errors.New("Job creation failed with error: " + err.Error())) - http.Error(w, err.Error(), http.StatusInternalServerError) - jobMutex.Lock() - jobInProgress = false - jobMutex.Unlock() - return - } - - // Execute Job - go func(j job) { - defer func() { - jobMutex.Lock() - jobInProgress = false - jobMutex.Unlock() - }() - executeJob(&j) - }(*j) - - w.WriteHeader(http.StatusOK) - }) - - // Endpoint for fetching current job list - r.Get("/jobs", func(w http.ResponseWriter, r *http.Request) { - logs.Info("[GET] /jobs endpoint called") - - debug, _ := httputil.DumpRequest(r, true) - logs.Debug(debug) - - jobList := jobs.List() - logs.Info("Number of jobs to list: ", len(jobList), " type: ", reflect.TypeOf(jobList)) - - encoder := json.NewEncoder(w) - encoder.SetIndent("", " ") - - err := encoder.Encode(jobList) - if err != nil { - logs.Error(errors.Newf("Error encoding jobs list: %v", err)) - http.Error(w, "Internal Server Error", http.StatusInternalServerError) - return - } - logs.Info("Jobs list returned successfully") - }) - // start the server - logs.Info("Server running on ", *port) - logs.Fatal(http.ListenAndServe(*port, r)) -} diff --git a/server/src/global_refinement.rs b/server/src/global_refinement.rs new file mode 100644 index 0000000..1a6867e --- /dev/null +++ b/server/src/global_refinement.rs @@ -0,0 +1,311 @@ +use std::{collections::HashMap, fs::{self, File}, io::{self, Cursor, Error, ErrorKind}, path::{Path, PathBuf}, pin::Pin, sync::{Arc, Mutex}, task::{Context, Poll}}; +use posemesh_domain::{auth::{handshake, TaskTokenClaim}, capabilities::public_key::PublicKeyStorage, datastore::{common::{data_id_generator, Datastore}, remote::RemoteDatastore}, message::read_prefix_size_message, protobuf::{domain_data::{self, Metadata, Query, UpsertMetadata}, task}}; +use posemesh_networking::{client::{Client, TClient}, AsyncStream}; +use quick_protobuf::{deserialize_from_slice, serialize_into_vec}; +use regex::Regex; +use tokio::{self, sync::watch, time::{sleep, Duration}}; +use futures::AsyncWrite; +use zip::ZipArchive; + +use crate::utils::{execute_python, health}; + +fn add_suffix(name: &str, suffix: &str) -> String { + format!("{name}_{suffix}") +} + +async fn upload_results(domain_id: &str, job_id: &str, output_path: PathBuf, datastore: &mut RemoteDatastore) -> Result<(), Box> { + let mut uploader = datastore.upsert(domain_id.to_string()).await?; + // open output_path and upload to datastore + let files = fs::read_dir(output_path)?; + for file in files { + let file = file?; + let path = file.path(); + let metadata: UpsertMetadata = match file.file_name().to_str().unwrap() { + "refined_manifest.json" => UpsertMetadata { + name: add_suffix("refined_manifest", job_id), + data_type: "refined_manifest_json".to_string(), + size: file.metadata()?.len() as u32, + id: data_id_generator(), + properties: HashMap::new(), + is_new: true, + }, + "RefinedPointCloud.ply" => UpsertMetadata { + name: add_suffix("refined_pointcloud", job_id), + data_type: "refined_pointcloud_ply".to_string(), + size: file.metadata()?.len() as u32, + id: data_id_generator(), + properties: HashMap::new(), + is_new: true + }, + "BasicStitchPointCloud.ply" => UpsertMetadata { + name: add_suffix("unrefined_pointcloud", job_id), + data_type: "unrefined_pointcloud_ply".to_string(), + size: file.metadata()?.len() as u32, + id: data_id_generator(), + properties: HashMap::new(), + is_new: true + }, + _ => continue + }; + let content = fs::read(path)?; + let mut producer = uploader.push(&metadata).await?; + producer.next_chunk(&content, false).await?; + } + + while !uploader.is_completed().await { + sleep(Duration::from_secs(3)).await; + } + uploader.close().await; + Ok(()) +} + +fn unzip_bytes(path: PathBuf, zip_bytes: &[u8]) -> io::Result<()> { + let cursor = Cursor::new(zip_bytes); + let mut archive = ZipArchive::new(cursor)?; + tracing::info!("Zip archive opened, contains {} files", archive.len()); + + for i in 0..archive.len() { + let mut input_file = archive.by_index(i)?; + let file_name = input_file.enclosed_name().unwrap(); + let file_name = file_name.file_name().unwrap().to_str().unwrap(); + + let file_path = path.join(file_name); + + // Create parent directory if it doesn't exist + if let Some(parent) = file_path.parent() { + fs::create_dir_all(parent)?; + } + + let mut output_file: File = File::create(&file_path)?; + let _ = std::io::copy(&mut input_file, &mut output_file)?; + } + Ok(()) +} + +async fn initialize_task( + base_path: &str, + stream: &mut S, + c: &mut C, + key_loader: P, +) -> Result<(task::Task, String, TaskTokenClaim, PathBuf, PathBuf, PathBuf, PathBuf), Box> { + let claim = handshake(stream, key_loader).await.expect("Failed to handshake"); + let job_id = claim.job_id.clone(); + c.subscribe(job_id.clone()).await.expect("Failed to subscribe to job"); + let task = task::Task { + name: claim.task_name.clone(), + receiver: Some(claim.receiver.clone()), + sender: claim.sender.clone(), + endpoint: "/global-refinement/v1".to_string(), + status: task::Status::STARTED, + access_token: None, + job_id: job_id.clone(), + output: None, + }; + + let task_path = Path::new(base_path).join(&job_id); + let dataset_path = task_path.join("datasets"); + let input_path = task_path.join("refined").join("local"); + let output_path = task_path.join("refined").join("global"); + + /* + | volumn/node_name + | | job_id + | | | datasets/suffix + | | | refined/local/suffix/sfm => input for global refinement + | | | refined/global => output for global refinement + */ + + fs::create_dir_all(&input_path)?; + fs::create_dir_all(&dataset_path)?; + fs::create_dir_all(&output_path)?; + + Ok((task, job_id, claim, task_path, dataset_path, input_path, output_path)) +} + +fn download_local_refinement_result(dataset_path: &Path, input_path: &Path, name: &str, data: &[u8]) -> io::Result { + let suffix = extract_suffix(name).map_err(|_| Error::new(ErrorKind::Other, "Failed to extract suffix"))?; + + fs::create_dir_all(dataset_path.join(&suffix))?; // This is because python may expect there is dataset folder even it is empty + let path = input_path.join(&suffix).join("sfm"); + fs::create_dir_all(&path)?; + unzip_bytes(path, data)?; + Ok(suffix) +} + +#[derive(Clone)] +struct ToZipArchive { + dataset_path: PathBuf, + input_path: PathBuf, + size: u32, + name: String, + content: Vec, + scan_ids: Arc>>, +} +impl ToZipArchive { + fn new(dataset_path: PathBuf, input_path: PathBuf) -> Self { + Self { + dataset_path, + input_path, + size: 0, + name: "".to_string(), + content: vec![], + scan_ids: Arc::new(Mutex::new(vec![])), + } + } + + pub fn scan_ids(&self) -> Vec { + self.scan_ids.lock().unwrap().clone() + } +} + +impl AsyncWrite for ToZipArchive { + fn poll_write(mut self: Pin<&mut Self>, _: &mut Context<'_>, content: &[u8]) -> Poll> { + if self.size == 0 { + if content.len() < 4 { + return Poll::Ready(Err(Error::new(ErrorKind::Other, "Content is too short"))); + } + let metadata = deserialize_from_slice::(&content[4..]).map_err(|_| Error::new(ErrorKind::Other, "Failed to deserialize metadata"))?; + self.size = metadata.size; + self.name = metadata.name; + self.content = vec![]; + return Poll::Ready(Ok(content.len())); + } else { + self.content.extend_from_slice(content); + return Poll::Ready(Ok(content.len())); + } + } + + fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + if self.size == 0 { + return Poll::Ready(Ok(())); + } + if self.size > self.content.len() as u32 { + return Poll::Ready(Ok(())); + } + let suffix = download_local_refinement_result(&self.dataset_path, &self.input_path, &self.name, &self.content)?; + self.scan_ids.lock().unwrap().push(suffix); + self.content = vec![]; + self.size = 0; + self.name = "".to_string(); + + Poll::Ready(Ok(())) + } + + fn poll_close(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + self.content = vec![]; + self.size = 0; + self.name = "".to_string(); + Poll::Ready(Ok(())) + } +} + +async fn download_data( + datastore: &mut RemoteDatastore, + domain_id: &str, + query: Query, + dataset_path: &Path, + input_path: &Path, +) -> Result, Box> { + let to_file_system = ToZipArchive::new(dataset_path.to_path_buf(), input_path.to_path_buf()); + let mut downloader = datastore.load(domain_id.to_string(), query, false, to_file_system.clone()).await?; + downloader.wait_for_done().await?; + + if to_file_system.scan_ids().is_empty() { + return Err("No scans to refine".into()); + } + + Ok(to_file_system.scan_ids()) +} + +fn extract_suffix(name: &str) -> Result> { + let date_time_regex = Regex::new(r"\d{4}-\d{2}-\d{2}[_-]\d{2}-\d{2}-\d{2}")?; + date_time_regex + .find(name) + .map(|m| m.as_str().to_string()) + .ok_or_else(|| "Failed to parse suffix from data.metadata.name".into()) +} + +pub(crate) async fn v1( + base_path: String, + mut stream: S, + datastore: RemoteDatastore, + mut c: Client, + key_loader: P, +) -> Result<(), Box> { + let (mut t, job_id, claim, task_path, dataset_path, input_path, output_path) = + initialize_task(&base_path, &mut stream, &mut c, key_loader).await?; + + let input = read_prefix_size_message::(&mut stream).await?; + tracing::info!("Received global refinement input: {:?}", input); + + let mut query = Query::default(); + for result in input.local_refinement_results { + query.ids.extend(result.result_ids); + } + + c.publish(job_id.clone(), serialize_into_vec(&t).expect("failed to serialize task update")).await?; + + let (tx, rx) = watch::channel(false); + + let heartbeat_handle = health(t.clone(), c.clone(), &job_id, rx).await; + + let _cleanup = scopeguard::guard(tx.clone(), |tx| { + let _ = tx.send(true); // Signal heartbeat task to stop + }); + + let domain_id = claim.domain_id.clone(); + let res = run(&domain_id, &task_path, &dataset_path, &input_path, &output_path, datastore, query, &job_id).await; + + tx.send(true).unwrap(); + if let Err(e) = res { + t.status = task::Status::FAILED; + t.output = Some(task::Any { + type_url: "Error".to_string(), + value: serialize_into_vec(&task::Error { + message: e.to_string(), + }).expect("failed to serialize local refinement output"), + }); + tracing::error!("Error: {}", e); + } else { + t.status = task::Status::DONE; + } + + let _ = heartbeat_handle.await; + + let buf = serialize_into_vec(&t)?; + c.publish(job_id.to_string(), buf).await?; + + tracing::info!("Finished executing {}", claim.task_name); + + Ok(()) +} + +async fn run( + domain_id: &str, + task_path: &Path, + dataset_path: &Path, + input_path: &Path, + output_path: &Path, + mut datastore: RemoteDatastore, + query: Query, + job_id: &str, +) -> Result<(), Box> { + let scan_ids = download_data(&mut datastore, &domain_id, query, dataset_path, input_path).await?; + + let mut params = vec![ + "-u", + "main.py", + "--mode", "global_refinement", + "--job_root_path", task_path.to_str().unwrap(), + "--output", output_path.to_str().unwrap(), + "--domain_id", &domain_id, + "--job_id", &job_id, + "--scans", + ]; + params.extend(scan_ids.iter().map(|s| s.as_str())); + + execute_python(params).await?; + upload_results(&domain_id, job_id, output_path.to_path_buf(), &mut datastore).await?; + std::fs::remove_dir_all(task_path)?; + Ok(()) +} diff --git a/server/src/local_refinement.rs b/server/src/local_refinement.rs new file mode 100644 index 0000000..d7f1ead --- /dev/null +++ b/server/src/local_refinement.rs @@ -0,0 +1,399 @@ +use std::{collections::HashMap, fs::{self, OpenOptions}, io::{Error, ErrorKind}, path::{Path, PathBuf}, pin::Pin, sync::{atomic::{AtomicI32, Ordering}, Arc, Mutex}, task::{Context, Poll}, time::Duration}; +use posemesh_domain::{auth::handshake, capabilities::public_key::PublicKeyStorage, datastore::{common::{data_id_generator, Datastore}, remote::RemoteDatastore}, message::read_prefix_size_message, protobuf::{domain_data::{Metadata, Query, UpsertMetadata},task::{self, LocalRefinementInputV1, LocalRefinementOutputV1}}}; +use posemesh_networking::{client::TClient, AsyncStream}; +use quick_protobuf::{deserialize_from_slice, serialize_into_vec}; +use futures::AsyncWrite; +use tokio::{sync::watch, time::sleep}; +use std::io::{BufReader, Read, Write}; +use zip::write::SimpleFileOptions; +use crate::utils::{execute_python, health, write_scan_data_summary}; + +const REFINED_SCAN_NAME: &str = "refined_scan_"; + +#[derive(Clone)] +struct FindScanResult { + id: Arc>, +} +impl FindScanResult { + fn new() -> Self { + Self { + id: Arc::new(Mutex::new("".to_string())) + } + } + fn scan_id(&self) -> String { + self.id.lock().unwrap().to_string() + } +} +impl AsyncWrite for FindScanResult { + fn poll_write(self: Pin<&mut Self>, _: &mut Context<'_>, content: &[u8]) -> Poll> { + if content.len() < 4 { + return Poll::Ready(Err(Error::new(ErrorKind::Other, "Content is too short"))); + } + let metadata = deserialize_from_slice::(&content[4..]).map_err(|e| Error::other(e))?; + let mut id = self.id.lock().unwrap(); + *id = metadata.id; + Poll::Ready(Ok(content.len())) + } + + fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } +} + +#[derive(Clone)] +struct ToFileSystem { + size: u32, + path: Option, + input_folder: PathBuf, + count: Arc>, + written: u32, + refined_res_id: Arc>>, +} +impl ToFileSystem { + fn new(input_folder: PathBuf) -> Self { + Self { + input_folder, + path: None, + size: 0, + count: Arc::new(Mutex::new(0)), + written: 0, + refined_res_id: Arc::new(Mutex::new(None)), + } + } + + fn count(&self) -> u32 { + self.count.lock().unwrap().clone() + } + + fn refined_res_id(&self) -> Option { + self.refined_res_id.lock().unwrap().clone() + } +} + +impl AsyncWrite for ToFileSystem { + fn poll_write(mut self: Pin<&mut Self>, _: &mut Context<'_>, content: &[u8]) -> Poll> { + if self.path.is_none() { + if content.len() < 4 { + return Poll::Ready(Err(Error::new(ErrorKind::Other, "Content is too short"))); + } + let metadata = deserialize_from_slice::(&content[4..]).map_err(|e| Error::other(e))?; + let filename = match metadata.name.as_str() { + "Manifest.json" => "Manifest.json".to_string(), + "FeaturePoints.ply" => "FeaturePoints.ply".to_string(), + "ARposes.csv" => "ARposes.csv".to_string(), + "PortalDetections.csv" => "PortalDetections.csv".to_string(), + "CameraIntrinsics.csv" => "CameraIntrinsics.csv".to_string(), + "Frames.csv" => "Frames.csv".to_string(), + "Gyro.csv" => "Gyro.csv".to_string(), + "Accel.csv" => "Accel.csv".to_string(), + "gyro_accel.csv" => "gyro_accel.csv".to_string(), + "Frames.mp4" => "Frames.mp4".to_string(), + _ => { + match metadata.data_type.as_str() { + "dmt_manifest_json" => "Manifest.json".to_string(), + "dmt_featurepoints_ply" | "dmt_pointcloud_ply" => "FeaturePoints.ply".to_string(), + "dmt_arposes_csv" => "ARposes.csv".to_string(), + "dmt_portal_detections_csv" | "dmt_observations_csv" => "PortalDetections.csv".to_string(), + "dmt_intrinsics_csv" | "dmt_cameraintrinsics_csv" => "CameraIntrinsics.csv".to_string(), + "dmt_frames_csv" => "Frames.csv".to_string(), + "dmt_gyro_csv" => "Gyro.csv".to_string(), + "dmt_accel_csv" => "Accel.csv".to_string(), + "dmt_gyroaccel_csv" => "gyro_accel.csv".to_string(), + "dmt_recording_mp4" => "Frames.mp4".to_string(), + _ => { + tracing::warn!("unknown domain data type: {}", metadata.data_type); + return Poll::Ready(Ok(0)); + } + } + } + }; + tracing::debug!("write to: {}", self.input_folder.join(&filename).to_str().unwrap()); + + self.path = Some(self.input_folder.join(&filename)); + self.written = 0; + self.size = metadata.size; + return Poll::Ready(Ok(content.len())); + } else { + self.written += content.len() as u32; + let path = self.path.as_ref().unwrap(); + let mut file = OpenOptions::new() + .create(true) + .append(true) + .open(path)?; + file.write_all(&content)?; + file.flush()?; + if self.written == self.size { + self.path = None; + self.written = 0; + self.size = 0; + let mut count = self.count.lock().unwrap(); + *count += 1; + } + return Poll::Ready(Ok(content.len())); + } + } + + fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn poll_close(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + self.path = None; + Poll::Ready(Ok(())) + } +} + +pub(crate) async fn v1(left_slots: Arc, base_path: String, mut stream: S, datastore: RemoteDatastore, mut c: C, key_loader: P) -> Result<(), Box> { + let claim = handshake(&mut stream, key_loader).await?; + let job_id = claim.job_id.clone(); + c.subscribe(job_id.clone()).await?; + let t = &mut task::Task { + name: claim.task_name.clone(), + receiver: Some(claim.receiver.clone()), + sender: claim.sender.clone(), + endpoint: "/local-refinement/v1".to_string(), + status: task::Status::STARTED, + access_token: None, + job_id: job_id.clone(), + output: None, + }; + let current_slots = left_slots.fetch_sub(1, Ordering::SeqCst); + let _guard = scopeguard::guard((), |_| { + left_slots.fetch_add(1, Ordering::SeqCst); + }); + + if current_slots < 0 { + tracing::warn!("Reconstruction has no vacancy, skipping this local refinement request"); + t.receiver = None; + t.status = task::Status::RETRY; + t.access_token = None; + let message = serialize_into_vec(t)?; + c.publish(job_id.clone(), message).await?; + return Ok(()); + } + + let res = start(base_path, &job_id, &claim.task_name, &mut stream).await; + match res { + Ok(context) => { + t.status = task::Status::STARTED; + let message = serialize_into_vec(t)?; + c.publish(job_id.clone(), message).await?; + let (tx, rx) = watch::channel(false); + + let heartbeat_handle = health(t.clone(), c.clone(), &job_id, rx).await; + + let _cleanup = scopeguard::guard(tx.clone(), |tx| { + let _ = tx.send(true); // Signal heartbeat task to stop + }); + + let output = run(&claim.domain_id, &job_id, &claim.task_name, context, datastore).await; + let _ = tx.send(true); // stop heartbeat task + match output { + Ok(output) => { + t.output = Some(task::Any { + type_url: "LocalRefinementOutputV1".to_string(), + value: serialize_into_vec(&output).expect("failed to serialize local refinement output"), + }); + t.status = task::Status::DONE; + } + Err(e) => { + tracing::error!("Failed to run local refinement: {}", e); + t.status = task::Status::FAILED; + t.output = Some(task::Any { + type_url: "Error".to_string(), + value: serialize_into_vec(&task::Error { + message: e.to_string(), + }).expect("failed to serialize local refinement output"), + }); + } + } + let _ = heartbeat_handle.await; + } + Err(e) => { + tracing::error!("Failed to start local refinement: {}", e); + t.status = task::Status::FAILED; + t.output = Some(task::Any { + type_url: "Error".to_string(), + value: serialize_into_vec(&task::Error { + message: e.to_string(), + }).expect("failed to serialize local refinement output"), + }); + } + } + let message = serialize_into_vec(t)?; + c.publish(job_id.clone(), message).await?; + + tracing::info!("finished local refinement {}", job_id); + + Ok(()) +} + +struct LocalRefinementContext { + query: Query, + task_folder: PathBuf, + scan_folder: PathBuf, + input_folder: PathBuf, + output_folder: PathBuf, + suffix: String, +} + +async fn start(base_path: String, job_id: &str, task_name: &str, mut stream: S) -> Result> { + let input = read_prefix_size_message::(&mut stream).await?; + + tracing::info!("Start executing {}, {:?}", task_name, input); + + // input.name_regexp looks .*_date + // get date from regexp + let query = input.query; + let query_clone = query.clone(); + let name_regexp = query.name_regexp; + if name_regexp.is_none() { + return Err("Name regexp is empty".into()); + } + + /* + get suffix from regexp + + | volumn/node_name + | | job_id + | | | datasets/suffix => input for local refinement + | | | refined/local/suffix + | | | | sfm/.(txt|bin|csv) => output for local refinement + upload refined_scan_2024-12-03_22-57-12 with type refined_scan_zip_v1 + + */ + let suffix = name_regexp.unwrap().replace(".*_", ""); + + let task_folder = Path::new(&base_path).join(job_id); + + let scan_folder = Path::new(&task_folder).join("datasets"); + let input_folder = Path::new(&scan_folder).join(&suffix.clone()); + let output_folder = Path::new(&task_folder).join("refined").join("local"); + fs::create_dir_all(&scan_folder)?; + fs::create_dir_all(&output_folder)?; + fs::create_dir_all(&input_folder)?; + + Ok(LocalRefinementContext { + query: query_clone, + task_folder, + scan_folder, + input_folder, + output_folder, + suffix, + }) +} + +async fn run(domain_id: &str, job_id: &str, task_name: &str, context: LocalRefinementContext, mut datastore: RemoteDatastore) -> Result> { + let query = context.query; + + let find_refine_result = FindScanResult::new(); + let mut find_refine_query = Query::default(); + find_refine_query.metadata_only = true; + find_refine_query.name_regexp = Some(format!("{}.*", REFINED_SCAN_NAME)); + let mut finding = datastore.load(domain_id.to_string(), find_refine_query, false, find_refine_result.clone()).await?; + if let Err(e) = finding.wait_for_done().await { + return Err(Box::new(e)); + } + if find_refine_result.scan_id() != "".to_string() { + return Ok(LocalRefinementOutputV1 { + result_ids: vec![find_refine_result.scan_id()], + }); + } + + let writer = ToFileSystem::new(context.input_folder.clone()); + let mut downloader = datastore.load(domain_id.to_string(), query, false, writer.clone()).await?; + if let Err(e) = downloader.wait_for_done().await { + let refined_res_id = writer.refined_res_id(); + if refined_res_id.is_some() { + let _ = fs::remove_dir_all(context.input_folder); + return Ok(LocalRefinementOutputV1 { + result_ids: vec![refined_res_id.unwrap()], + }); + } + return Err(Box::new(e)); + } + + if writer.count() == 0 { + return Err("No data downloaded".into()); + } + + tracing::info!("Finished downloading {} data for {}", writer.count(), task_name); + + write_scan_data_summary(context.input_folder.as_path(), context.task_folder.as_path().join("scan_data_summary.json").as_path())?; + + let params = vec![ + "-u", + "main.py", + "--mode", "local_refinement", + "--job_root_path", context.task_folder.to_str().unwrap(), + "--output", context.output_folder.to_str().unwrap(), + "--domain_id", domain_id, + "--job_id", job_id, + "--scans", context.suffix.as_str(), + ]; + + execute_python(params).await?; + + let sfm = context.output_folder.join(context.suffix.clone()).join("sfm"); + fs::create_dir_all(&sfm)?; + let zip_path = sfm.join(context.suffix.clone() + ".zip"); + let mut zip = zip::ZipWriter::new(fs::File::create(&zip_path)?); + let options = SimpleFileOptions::default().compression_method(zip::CompressionMethod::Stored); // No compression + + // open output folder/sfm, zip all txt, bin, csv files and upload + for entry in fs::read_dir(sfm)? { + let entry = entry?; + let path = entry.path(); + if path.is_dir() { + continue; + } + let ext = path.extension().expect("Failed to get extension").to_str().expect("Failed to convert extension to string"); + if ext == "txt" || ext == "bin" || ext == "csv" { + let str_path = path.to_str().expect("Failed to convert path to string"); + let file = fs::File::open(str_path)?; + let mut reader = BufReader::new(file); + zip.start_file(str_path, options)?; + + let mut buffer = [0u8; 8192]; // Use a buffer to stream in chunks + loop { + let bytes_read = reader.read(&mut buffer)?; + if bytes_read == 0 { + break; + } + zip.write_all(&buffer[..bytes_read])?; + } + } + } + zip.finish()?; + let zip_file_metadata = fs::metadata(&zip_path)?; + + let mut producer = datastore.upsert(domain_id.to_string()).await?; + let res_id = data_id_generator(); + let mut chunks = producer.push( + &UpsertMetadata { + size: zip_file_metadata.len() as u32, + name: format!("refined_scan_{}", context.suffix.clone()), + data_type: "refined_scan_zip_v1".to_string(), + id: res_id.clone(), + is_new: true, + properties: HashMap::new(), + }, + ).await?; + + let _ = chunks.next_chunk(&fs::read(&zip_path)?, false).await?; + while !producer.is_completed().await { + sleep(Duration::from_secs(3)).await; + } + producer.close().await; + std::fs::remove_dir_all(&context.input_folder)?; + + let output = LocalRefinementOutputV1 { + result_ids: vec![res_id], + }; + + return Ok(output); +} diff --git a/server/src/main.rs b/server/src/main.rs new file mode 100644 index 0000000..2e38a04 --- /dev/null +++ b/server/src/main.rs @@ -0,0 +1,144 @@ +use std::{collections::HashMap, sync::{atomic::{AtomicI32, Ordering}, Arc}, time::Duration}; + +use async_trait::async_trait; +use posemesh_domain::{auth::{AuthClient, AuthError}, capabilities::public_key::PublicKeyStorage, cluster::DomainCluster, datastore::remote::RemoteDatastore, protobuf::discovery::Capability}; +use posemesh_networking::client::Client; +use tokio::{self, select, signal::unix::{signal, SignalKind}}; +use futures::{lock::Mutex, StreamExt}; +use tracing_subscriber::{fmt, prelude::__tracing_subscriber_SubscriberExt, EnvFilter, Registry}; +mod local_refinement; +mod global_refinement; +mod utils; + +async fn shutdown_signal() { + let mut term_signal = signal(SignalKind::terminate()).expect("Failed to register SIGTERM handler"); + let mut int_signal = signal(SignalKind::interrupt()).expect("Failed to register SIGINT handler"); + + tokio::select! { + _ = term_signal.recv() => tracing::info!("Received SIGTERM, exiting..."), + _ = int_signal.recv() => tracing::info!("Received SIGINT, exiting..."), + } +} + +#[derive(Clone)] +struct PublicKeyLoader { + auth_clients: Arc>>, + client: Client, + cache_ttl: Duration, + domain_manager_id: String +} + +#[async_trait] +impl PublicKeyStorage for PublicKeyLoader { + async fn get_by_domain_id(&self, domain_id: String) -> Result, AuthError> { + let auth_clients = self.auth_clients.lock().await; + if let Some(client) = auth_clients.get(&domain_id) { + Ok(client.public_key().await) + } else { + drop(auth_clients); + let auth_client = AuthClient::initialize(self.client.clone(), &self.domain_manager_id.clone(), self.cache_ttl, &domain_id).await?; + let public_key = auth_client.public_key().await; + let mut auth_clients = self.auth_clients.lock().await; + auth_clients.insert(domain_id.clone(), auth_client); + Ok(public_key) + } + } +} + +impl PublicKeyLoader { + async fn cleanup(&self) { + let mut auth_clients = self.auth_clients.lock().await; + auth_clients.clear(); + } +} + +/* + * This is a simple example of a reconstruction node. It will connect to a set of bootstraps and execute reconstruction jobs. + * Usage: cargo run + * Example: cargo run 18808 reconstruction /ip4/127.0.0.1/udp/18800/quic-v1/p2p/12D3KooWDHaDQeuYeLM8b5zhNjqS7Pkh7KefqzCpDGpdwj5iE8pq + */ +#[tokio::main] +async fn main() -> Result<(), Box> { + let args: Vec = std::env::args().collect(); + if args.len() < 4 { + println!("Usage: {} ", args[0]); + return Ok(()); + } + let port = args[1].parse::().unwrap(); + let name = args[2].clone(); + let base_path = format!("./volume/{}", name); + let domain_manager = args[3].clone(); + let private_key_path = format!("{}/pkey", base_path); + let mut slots: i32 = 1; + if args.len() == 5 { + slots = args[4].parse::().unwrap(); + } + let left_slots: Arc = Arc::new(AtomicI32::new(slots)); + let subscriber = Registry::default() + .with(fmt::layer().with_file(true).with_line_number(true)) + .with(EnvFilter::try_new(std::env::var("RUST_LOG").unwrap_or_else(|_| "info".to_string())).unwrap_or_else(|_| EnvFilter::new("info"))); + tracing::subscriber::set_global_default(subscriber).expect("failed to set subscriber"); + + + let local_refinement_capability = Capability { + endpoint: "/local-refinement/v1".to_string(), + capacity: slots, + }; + let global_refinement_capability = Capability { + endpoint: "/global-refinement/v1".to_string(), + capacity: -1, // unlimited capacity + }; + let mut domain_cluster = DomainCluster::join(&domain_manager, &name, false, port, false, false, None, Some(private_key_path), vec![domain_manager.clone()]).await?; + let domain_manager_id = domain_cluster.manager_id.clone(); + let n = domain_cluster.peer.clone(); + let mut handlers = domain_cluster.with_capabilities(&vec![local_refinement_capability, global_refinement_capability]).await?; + let mut local_refinement_v1_handler = handlers.remove(0); + let mut global_refinement_v1_handler = handlers.remove(0); + let remote_storage = RemoteDatastore::new(domain_cluster); + let keys_loader = PublicKeyLoader { + auth_clients: Arc::new(Mutex::new(HashMap::new())), + client: n.client.clone(), + cache_ttl: Duration::from_secs(60*60*24), + domain_manager_id, + }; + + loop { + let mut c = n.client.clone(); + select! { + Some((_, stream)) = local_refinement_v1_handler.next() => { + let base_path = base_path.clone(); + let remote_storage = remote_storage.clone(); + let c = c.clone(); + let keys_loader = keys_loader.clone(); + let left_slots = left_slots.clone(); + tokio::spawn(async move { + if let Err(e) = local_refinement::v1(left_slots, base_path, stream, remote_storage, c, keys_loader).await { + tracing::error!("Local refinement error: {}", e); + } + }); + } + Some((_, stream)) = global_refinement_v1_handler.next() => { + let base_path = base_path.clone(); + let remote_storage = remote_storage.clone(); + let keys_loader = keys_loader.clone(); + let c = c.clone(); + tokio::spawn(async move { + if let Err(e) = global_refinement::v1(base_path, stream, remote_storage, c, keys_loader).await { + tracing::error!("Global Refinement Error: {}", e); + } + }); + } + _ = shutdown_signal() => { + c.cancel().await.unwrap_or_else(|e| { + tracing::error!("Failed to cancel client: {}", e); + }); + keys_loader.cleanup().await; + tracing::info!("Received termination signal, shutting down..."); + break; + } + else => break + } + } + + Ok(()) +} diff --git a/server/src/utils.rs b/server/src/utils.rs new file mode 100644 index 0000000..a7fe288 --- /dev/null +++ b/server/src/utils.rs @@ -0,0 +1,248 @@ +use posemesh_domain::{datastore::common::DomainError, protobuf::task::{Status, Task}}; +use posemesh_networking::{client::TClient, libp2p::NetworkError}; +use quick_protobuf::serialize_into_vec; +use tokio::{sync::watch, task::JoinHandle, time::interval}; +use std::{collections::HashSet, error::Error, fs, path::Path, process::Stdio, time::Duration}; +use serde_json::{json, Value}; +use tokio::{io::{AsyncBufReadExt, BufReader as TokioBufReader}, process::Command}; + +pub fn write_scan_data_summary( + scan_folder:&Path, + summary_json_path: &Path, +) -> Result<(), Box> { + let mut scan_count = 0; + let mut total_frame_count = 0; + let mut total_scan_duration = 0.0; + let mut scan_durations = Vec::new(); + let mut unique_portal_ids = HashSet::new(); + let mut portal_sizes = Vec::new(); + let mut devices_used = HashSet::new(); + let mut app_versions_used = HashSet::new(); + + let manifest_path = scan_folder.join("Manifest.json"); + if !manifest_path.exists() { + return Err("Manifest.json not found".into()); + } + + let manifest_data = fs::read_to_string(&manifest_path)?; + let manifest: Value = serde_json::from_str(&manifest_data)?; + + scan_count += 1; + + let frame_count = manifest["frameCount"].as_f64().unwrap_or(0.0) as i32; + let duration = manifest["duration"].as_f64().unwrap_or(0.0); + total_frame_count += frame_count; + total_scan_duration += duration; + scan_durations.push(duration); + + if let Some(portals) = manifest.get("portals").and_then(|p| p.as_array()) { + for portal in portals { + if let Some(portal_map) = portal.as_object() { + if let Some(portal_id) = portal_map.get("shortId").and_then(|id| id.as_str()) { + if unique_portal_ids.insert(portal_id.to_string()) { + if let Some(size) = portal_map.get("physicalSize").and_then(|s| s.as_f64()) { + portal_sizes.push(size); + } + } + } + } + } + } + + let device = if let (Some(brand), Some(model), Some(system_name), Some(system_version)) = ( + manifest.get("brand").and_then(|b| b.as_str()), + manifest.get("model").and_then(|m| m.as_str()), + manifest.get("systemName").and_then(|s| s.as_str()), + manifest.get("systemVersion").and_then(|v| v.as_str()), + ) { + format!("{} {} {} {}", brand, model, system_name, system_version) + } else { + "unknown".to_string() + }; + devices_used.insert(device); + + let app_version = if let (Some(version), Some(build_id)) = ( + manifest.get("appVersion").and_then(|v| v.as_str()), + manifest.get("buildId").and_then(|b| b.as_str()), + ) { + format!("{} (build {})", version, build_id) + } else { + "unknown".to_string() + }; + app_versions_used.insert(app_version); + + + scan_durations.sort_by(|a, b| a.partial_cmp(b).unwrap()); + let shortest_scan_duration = scan_durations.first().unwrap_or(&0.0); + let longest_scan_duration = scan_durations.last().unwrap_or(&0.0); + let median_scan_duration = scan_durations.get(scan_durations.len() / 2).unwrap_or(&0.0); + + let average_scan_duration = total_scan_duration / scan_count as f64; + let average_scan_frame_count = total_frame_count as f64 / scan_count as f64; + let average_scan_frame_rate = total_frame_count as f64 / total_scan_duration; + + let summary = json!({ + "scanCount": scan_count, + "totalFrameCount": total_frame_count, + "totalScanDuration": total_scan_duration, + "averageScanDuration": average_scan_duration, + "averageScanFrameCount": average_scan_frame_count, + "averageFrameRate": average_scan_frame_rate, + "shortestScanDuration": shortest_scan_duration, + "longestScanDuration": longest_scan_duration, + "medianScanDuration": median_scan_duration, + "portalCount": unique_portal_ids.len(), + "portalIDs": unique_portal_ids, + "portalSizes": portal_sizes, + "deviceVersionsUsed": devices_used, + "appVersionsUsed": app_versions_used, + }); + + fs::write( + summary_json_path, + serde_json::to_string_pretty(&summary)?, + )?; + + Ok(()) +} + +pub async fn health(task: Task, mut c: C, job_id: &str, rx: watch::Receiver) -> JoinHandle<()> { + let job_id_clone = job_id.to_string(); + tokio::spawn(async move { + let mut rx = rx.clone(); + let mut interval = interval(Duration::from_secs(30)); // Send heartbeat every 30 seconds + loop { + tokio::select! { + _ = interval.tick() => { + let mut progress_task = task.clone(); + progress_task.status = Status::PROCESSING; + if let Ok(message) = serialize_into_vec(&progress_task) { + if let Err(e) = c.publish(job_id_clone.clone(), message).await { + tracing::error!("Error publishing heartbeat: {}", e); + continue; + } + } else { + tracing::error!("Failed to serialize heartbeat"); + } + } + // Check if we should stop + Ok(_) = rx.changed() => { + break; + } + } + } + }) +} + +pub async fn execute_python(params: Vec<&str>) -> Result<(), Box> { + let mut child = Command::new("python3") + .args(params) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn()?; + + // Read stdout in real-time + if let Some(stdout) = child.stdout.take() { + let stdout_reader = TokioBufReader::new(stdout); + tokio::spawn(async move { + let mut lines = stdout_reader.lines(); + while let Ok(Some(line)) = lines.next_line().await { + println!("stdout: {}", line); + } + }); + } + + // Read stderr in real-time + if let Some(stderr) = child.stderr.take() { + let stderr_reader = TokioBufReader::new(stderr); + tokio::spawn(async move { + let mut lines = stderr_reader.lines(); + while let Ok(Some(line)) = lines.next_line().await { + println!("stderr: {}", line); + } + }); + } + + // Wait for the process to complete + let status = child.wait().await?; + if !status.success() { + tracing::info!("Python process failed"); + return Err(format!("Python process failed with status {}", status).into()); + } + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + use async_trait::async_trait; + use posemesh_networking::client::TClient; + use posemesh_networking::libp2p::NetworkError; + use tokio::sync::watch; + use tokio::time::{sleep, Duration}; + use std::sync::{Arc, Mutex}; + + // Mock Client to capture published messages + #[derive(Clone)] + struct MockClient { + published_messages: Arc>>>, + } + + impl MockClient { + fn new() -> Self { + MockClient { + published_messages: Arc::new(Mutex::new(Vec::new())), + } + } + + fn get_published_messages(&self) -> Vec> { + self.published_messages.lock().unwrap().clone() + } + } + + #[async_trait] + impl TClient for MockClient { + async fn publish(&mut self, _job_id: String, message: Vec) -> Result<(), NetworkError> { + self.published_messages.lock().unwrap().push(message); + Ok(()) + } + async fn subscribe(&mut self, _job_id: String) -> Result<(), NetworkError> { + Ok(()) + } + } + + #[tokio::test] + async fn test_health_sends_heartbeat() { + let task = Task { + status: Status::PROCESSING, + ..Default::default() + }; + let client = MockClient::new(); + let (tx, rx) = watch::channel(false); + // Start the health task + let heartbeat_handle = health(task, client.clone(), "job_id", rx).await; + + // Allow some time for heartbeats to be sent + sleep(Duration::from_secs(32)).await; + + // Check that heartbeats were sent + let messages = client.get_published_messages(); + assert!(messages.len() >= 1, "Expected at least 1 heartbeat, got {}", messages.len()); + + // Stop the heartbeat task + tx.send(true).unwrap(); + let _ = heartbeat_handle.await; + } + + #[tokio::test] + async fn test_execute_python_should_fail_when_python_script_does_not_exist() { + async fn run() -> Result<(), Box> { + let params = vec!["non_existent_script.py"]; + execute_python(params).await?; + Ok(()) + } + + let res = run().await; + assert!(res.is_err(), "Expected error when script does not exist"); + } +} diff --git a/utils/data_utils.py b/utils/data_utils.py index 1776a97..3270e57 100644 --- a/utils/data_utils.py +++ b/utils/data_utils.py @@ -18,6 +18,7 @@ from dateutil import parser from pathlib import Path from typing import NamedTuple, Dict +import sys floor_rotation = pycolmap.Rotation3d(np.array([0, 0.7071068, 0, 0.7071068])) floor_rotation_inv = pycolmap.Rotation3d(np.array([0, -0.7071068, 0, 0.7071068])) @@ -420,31 +421,43 @@ def save_qr_poses_csv(poses_per_qr, csv_path): csv_writer.writerow(row) def save_portal_csv(poses_per_qr, csv_path, image_ids_per_qr, portal_sizes, corners_per_qr): - with open(csv_path, mode='w', newline='') as csvfile: - csv_writer = csv.writer(csvfile) - - for short_id, qr_poses in poses_per_qr.items(): - - corresponding_image_ids = image_ids_per_qr[short_id] - corresponding_corners = corners_per_qr[short_id] - - for image_id, qr_pose, qr_corners in zip(corresponding_image_ids, qr_poses, corresponding_corners): - pos, quat = qr_pose.translation, qr_pose.rotation.quat - corner_array = [coord for coords in qr_corners for coord in coords] - # Create a row for the CSV - # Format - # image_id, portal_id, portal_size, px, py, pz, qx, qy, qz, qw - row = [ - image_id, - short_id, - portal_sizes[short_id], - pos[0], pos[1], pos[2], - quat[0], quat[1], quat[2], quat[3] - ] - - row.extend(corner_array) - # Write the row to the CSV file - csv_writer.writerow(row) + print(f"Saving portal CSV to {csv_path}") + try: + with open(csv_path, mode='w', newline='') as csvfile: + csv_writer = csv.writer(csvfile) + + print(f"Opening portal CSV file {csv_path}") + for short_id, qr_poses in poses_per_qr.items(): + + corresponding_image_ids = image_ids_per_qr[short_id] + corresponding_corners = corners_per_qr[short_id] + + print(f"Zipping portal {short_id} with images {corresponding_image_ids}") + for image_id, qr_pose, qr_corners in zip(corresponding_image_ids, qr_poses, corresponding_corners): + pos, quat = qr_pose.translation, qr_pose.rotation.quat + corner_array = [coord for coords in qr_corners for coord in coords] + print(f"Corner array: {corner_array}, {portal_sizes}") + # Create a row for the CSV + # Format + # image_id, portal_id, portal_size, px, py, pz, qx, qy, qz, qw + row = [ + image_id, + short_id, + portal_sizes[short_id], + pos[0], pos[1], pos[2], + quat[0], quat[1], quat[2], quat[3] + ] + print(f"Extend row: {row}") + row.extend(corner_array) + # Write the row to the CSV file + print(f"Writing row to CSV: {row}") + csv_writer.writerow(row) + print(f"Wrote row to CSV: {row}") + print(f"Saved portal CSV to {csv_path}") + except Exception as e: + print(f"Error saving portal CSV to {csv_path}") + print(e) + raise e def save_failed_manifest_json(json_path, job_root_path, job_status_details): save_manifest_json({}, json_path, job_root_path, job_status="failed", job_progress=100, job_status_details=job_status_details) @@ -1012,4 +1025,4 @@ def load_dataset_metadata( ar_poses_per_timestamp=ar_poses_per_timestamp, qr_detections_per_timestamp=qr_detections_per_timestamp, portal_sizes=portal_sizes - ) \ No newline at end of file + ) diff --git a/utils/dataset_utils.py b/utils/dataset_utils.py index 2981e84..0e0a83f 100644 --- a/utils/dataset_utils.py +++ b/utils/dataset_utils.py @@ -45,7 +45,6 @@ def __init__(self, message='No overlaps!'): class StitchingData: detections_per_qr: Dict[str, List[pycolmap.Rigid3d]] = None image_ids_per_qr: Dict[str, List[int]] = None - timestamp_per_image: Dict[str, int] = None arkit_precomputed: Dict = None placed_portal: Dict[str, pycolmap.Rigid3d] = None chunks_image_ids: List[List[int]] = None @@ -55,7 +54,6 @@ class StitchingData: def __post_init__(self): self.detections_per_qr = self.detections_per_qr or {} self.image_ids_per_qr = self.image_ids_per_qr or {} - self.timestamp_per_image = self.timestamp_per_image or {} self.arkit_precomputed = self.arkit_precomputed or {} self.placed_portal = self.placed_portal or {} self.chunks_image_ids = self.chunks_image_ids or [] @@ -208,11 +206,6 @@ def load_partial( if loaded_rec is None: return stitch_data - # Load frame timestamps - timestamp_chunk = _load_frame_timestamps(unzip_folder, logger) - if not timestamp_chunk: - return stitch_data - # Extract and process QR code detections qr_detections = _process_qr_detections(loaded_rec) @@ -243,7 +236,6 @@ def load_partial( loaded_rec, alignment_transform, qr_detections, - timestamp_chunk, stitch_data, with_3dpoints, logger @@ -368,7 +360,6 @@ def _process_reconstruction( loaded_rec: Model, alignment_transform: Optional[pycolmap.Rigid3d], qr_detections: List[Dict], - timestamp_chunk: Dict[str, int], stitch_data: StitchingData, with_3dpoints: bool, logger @@ -438,11 +429,6 @@ def _process_reconstruction( element.image_id = image_id_old_to_new[element.image_id] stitch_data.combined_rec.add_observation(point3D_id_new, element) - # Update timestamps - for filename, timestamp in timestamp_chunk.items(): - assert filename not in stitch_data.timestamp_per_image - stitch_data.timestamp_per_image[filename] = timestamp - # Process sorted image IDs sorted_image_ids = sorted(list(rec2.images.keys())) stitch_data.chunks_image_ids.append(sorted_image_ids)