From c5172104d04140df8036f7a6a59857bd5104b618 Mon Sep 17 00:00:00 2001 From: echobt Date: Wed, 18 Feb 2026 15:59:23 +0000 Subject: [PATCH 01/12] feat(auth): replace static hotkey/API-key auth with Bittensor validator whitelisting and 50% consensus Integrate dynamic validator whitelisting from Bittensor netuid 100 and consensus-based evaluation triggering, replacing the previous single AUTHORIZED_HOTKEY + WORKER_API_KEY authentication system. Authentication now uses a dynamic whitelist of validators fetched every 5 minutes from the Bittensor blockchain via bittensor-rs. Validators must have validator_permit, be active, and have >=10,000 TAO stake. POST /submit requests only trigger evaluations when >=50% of whitelisted validators submit the same archive payload (identified by SHA-256 hash). New modules: - src/validator_whitelist.rs: ValidatorWhitelist with parking_lot::RwLock, background refresh loop with 3-retry exponential backoff, connection resilience (keeps cached whitelist on failure), starts empty and rejects requests with 503 until first successful sync - src/consensus.rs: ConsensusManager using DashMap for lock-free vote tracking, PendingConsensus entries with TTL (default 60s), reaper loop every 30s, max 100 pending entries cap, duplicate vote detection Modified modules: - src/auth.rs: Removed AUTHORIZED_HOTKEY import, api_key field from AuthHeaders, X-Api-Key header extraction, InvalidApiKey error variant. verify_request() now takes &ValidatorWhitelist instead of API key string. Updated all tests accordingly. - src/config.rs: Removed AUTHORIZED_HOTKEY constant and worker_api_key field. Added bittensor_netuid, min_validator_stake_tao, validator_refresh_secs, consensus_threshold, consensus_ttl_secs with env var support and sensible defaults. Updated banner output. - src/handlers.rs: Added ValidatorWhitelist and ConsensusManager to AppState. submit_batch now: checks whitelist non-empty (503), validates against whitelist, computes SHA-256 of archive, records consensus vote, returns 202 with pending status or triggers evaluation on consensus. Moved active batch check to consensus-reached branch only. - src/main.rs: Added module declarations, creates ValidatorWhitelist and ConsensusManager, spawns background refresh and reaper tasks. - Cargo.toml: Added bittensor-rs git dependency and mandatory [patch.crates-io] for w3f-bls. - Dockerfile: Added protobuf-compiler, cmake, clang, mold build deps for bittensor-rs substrate dependencies. Copies .cargo config. - AGENTS.md and src/AGENTS.md: Updated data flow, module map, env vars, authentication docs to reflect new architecture. BREAKING CHANGE: WORKER_API_KEY env var and X-Api-Key header no longer required. All validators on Bittensor netuid 100 with sufficient stake are auto-whitelisted. --- AGENTS.md | 71 +- Cargo.lock | 6501 ++++++++++++++++++++++++++++++------ Cargo.toml | 6 + Dockerfile | 3 +- src/AGENTS.md | 47 +- src/auth.rs | 62 +- src/config.rs | 49 +- src/consensus.rs | 232 ++ src/handlers.rs | 174 +- src/main.rs | 21 + src/validator_whitelist.rs | 121 + 11 files changed, 6065 insertions(+), 1222 deletions(-) create mode 100644 src/consensus.rs create mode 100644 src/validator_whitelist.rs diff --git a/AGENTS.md b/AGENTS.md index fbe4900..3fca2e8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,29 +11,51 @@ This is a **single-crate Rust binary** (`term-executor`) built with Axum. There ### Data Flow ``` -Client → POST /submit (multipart archive) → term-executor - 1. Authenticate via X-Hotkey, X-Nonce, X-Signature, X-Api-Key headers - 2. Extract uploaded archive (zip/tar.gz) containing tasks/ and agent_code/ - 3. Parse each task: workspace.yaml, prompt.md, tests/ - 4. For each task (concurrently, up to limit): - a. git clone the target repository at base_commit - b. Run install commands (pip install, etc.) - c. Write & execute agent code in the repo - d. Write test source files into the repo - e. Run test scripts (bash), collect exit codes - 5. Aggregate results (reward per task, aggregate reward) - 6. Stream progress via WebSocket (GET /ws?batch_id=...) - 7. Return results via GET /batch/{id} +Validator → POST /submit (multipart archive) → term-executor + 1. Authenticate via X-Hotkey, X-Nonce, X-Signature headers + 2. Verify hotkey is in the dynamic validator whitelist (Bittensor netuid 100, >10k TAO stake) + 3. Compute SHA-256 hash of archive bytes + 4. Record vote in ConsensusManager + 5. If <50% of whitelisted validators have voted for this hash: + → Return 202 Accepted with pending_consensus status + 6. If ≥50% consensus reached: + a. Extract uploaded archive (zip/tar.gz) containing tasks/ and agent_code/ + b. Parse each task: workspace.yaml, prompt.md, tests/ + c. For each task (concurrently, up to limit): + i. git clone the target repository at base_commit + ii. Run install commands (pip install, etc.) + iii. Write & execute agent code in the repo + iv. Write test source files into the repo + v. Run test scripts (bash), collect exit codes + d. Aggregate results (reward per task, aggregate reward) + e. Stream progress via WebSocket (GET /ws?batch_id=...) + f. Return results via GET /batch/{id} +``` + +### Background Tasks + +``` +ValidatorWhitelist refresh loop (every 5 minutes): + 1. Connect to Bittensor subtensor via BittensorClient::with_failover() + 2. Sync metagraph for netuid 100 + 3. Filter validators: validator_permit && active && stake >= 10,000 TAO + 4. Atomically replace whitelist with new set of SS58 hotkeys + 5. On failure: retry up to 3 times with exponential backoff, keep cached whitelist + +ConsensusManager reaper loop (every 30 seconds): + 1. Remove pending consensus entries older than TTL (default 60s) ``` ### Module Map | File | Responsibility | |---|---| -| `src/main.rs` | Entry point — bootstraps config, session manager, executor, Axum server, reaper tasks | -| `src/config.rs` | `Config` struct loaded from environment variables with defaults; `AUTHORIZED_HOTKEY` constant | +| `src/main.rs` | Entry point — bootstraps config, session manager, executor, validator whitelist, consensus manager, Axum server, background tasks | +| `src/config.rs` | `Config` struct loaded from environment variables with defaults; Bittensor and consensus configuration | | `src/handlers.rs` | Axum route handlers: `/health`, `/status`, `/metrics`, `/submit`, `/batch/{id}`, `/batch/{id}/tasks`, `/batch/{id}/task/{task_id}`, `/batches` | -| `src/auth.rs` | Authentication: `extract_auth_headers()`, `verify_request()`, `validate_ss58()`, sr25519 signature verification via `verify_sr25519_signature()`, `NonceStore` for replay protection, `AuthHeaders`/`AuthError` types | +| `src/auth.rs` | Authentication: `extract_auth_headers()`, `verify_request()` (whitelist-based), `validate_ss58()`, sr25519 signature verification via `verify_sr25519_signature()`, `NonceStore` for replay protection, `AuthHeaders`/`AuthError` types | +| `src/validator_whitelist.rs` | Dynamic validator whitelist — fetches validators from Bittensor netuid 100 every 5 minutes, filters by stake ≥10k TAO, stores SS58 hotkeys in `parking_lot::RwLock` | +| `src/consensus.rs` | 50% consensus manager — tracks pending votes per archive hash in `DashMap`, triggers evaluation when ≥50% of whitelisted validators submit same payload, TTL reaper for expired entries | | `src/executor.rs` | Core evaluation engine — spawns batch tasks that clone repos, run agents, run tests concurrently | | `src/session.rs` | `SessionManager` with `DashMap`, `Batch`, `BatchResult`, `TaskResult`, `BatchStatus`, `TaskStatus`, `WsEvent` types | | `src/task.rs` | Archive extraction (zip/tar.gz), task directory parsing, agent code loading, language detection | @@ -43,8 +65,10 @@ Client → POST /submit (multipart archive) → term-executor ### Key Shared State (via `Arc`) -- `AppState` (in `handlers.rs`) holds `Config`, `SessionManager`, `Metrics`, `Executor`, `NonceStore`, `started_at` +- `AppState` (in `handlers.rs`) holds `Config`, `SessionManager`, `Metrics`, `Executor`, `NonceStore`, `started_at`, `ValidatorWhitelist`, `ConsensusManager` - `SessionManager` uses `DashMap>` for lock-free concurrent access +- `ValidatorWhitelist` uses `parking_lot::RwLock>` for concurrent read access with rare writes +- `ConsensusManager` uses `DashMap` for lock-free concurrent vote tracking - Per-batch `Semaphore` in `executor.rs` controls concurrent tasks within a batch (configurable, default: 8) - `broadcast::Sender` per batch for WebSocket event streaming @@ -60,6 +84,7 @@ Client → POST /submit (multipart archive) → term-executor - **Error Handling**: `anyhow` 1 + `thiserror` 2 - **Logging**: `tracing` + `tracing-subscriber` with env-filter - **Crypto/Identity**: `sha2`, `hex`, `base64`, `bs58` (SS58 address validation), `schnorrkel` 0.11 (sr25519 signature verification), `rand_core` 0.6, `uuid` v4 +- **Blockchain**: `bittensor-rs` (git dependency) for Bittensor validator whitelisting via subtensor RPC - **Time**: `chrono` with serde support - **Build Tooling**: `mold` linker via `.cargo/config.toml`, `clang` as linker driver - **Container**: Multi-stage Dockerfile — `rust:1.93-slim-bookworm` builder → `debian:bookworm-slim` runtime (includes python3, pip, venv, build-essential, git, curl) @@ -71,13 +96,13 @@ Client → POST /submit (multipart archive) → term-executor 2. **All clippy warnings are errors.** Run `cargo +nightly clippy --all-targets -- -D warnings` locally. CI runs the same command and will fail on any warning. -3. **Never expose secrets in logs or responses.** The `AUTHORIZED_HOTKEY` in `src/config.rs` is the only authorized SS58 hotkey. Auth failures log only the rejection, never the submitted hotkey value. Follow this pattern for any new secrets. +3. **Never expose secrets in logs or responses.** Auth failures log only the rejection, never the submitted hotkey value. Follow this pattern for any new secrets. 4. **All process execution MUST have timeouts.** Every call to `run_cmd`/`run_shell` in `src/executor.rs` takes a `Duration` timeout. Never spawn a child process without a timeout — agent code is untrusted and may hang forever. 5. **Output MUST be truncated.** The `truncate_output()` function in `src/executor.rs` caps output at `MAX_OUTPUT` (1MB). Any new command output capture must use this function to prevent memory exhaustion from malicious agent output. -6. **Shared state must use `Arc` + lock-free structures.** `SessionManager` uses `DashMap` (not `Mutex`). Metrics use `AtomicU64`. New shared state should follow these patterns — never use `std::sync::Mutex` for hot-path data. +6. **Shared state must use `Arc` + lock-free structures.** `SessionManager` uses `DashMap` (not `Mutex`). Metrics use `AtomicU64`. `ValidatorWhitelist` uses `parking_lot::RwLock`. `ConsensusManager` uses `DashMap`. New shared state should follow these patterns — never use `std::sync::Mutex` for hot-path data. 7. **Semaphore must gate task concurrency.** The per-batch `Semaphore` in `executor.rs` limits concurrent tasks within a batch. The `SessionManager::has_active_batch()` check prevents multiple batches from running simultaneously. @@ -164,8 +189,12 @@ Both hooks are activated via `git config core.hooksPath .githooks`. | `MAX_ARCHIVE_BYTES` | `524288000` | Max uploaded archive size (500MB) | | `MAX_OUTPUT_BYTES` | `1048576` | Max captured output per command (1MB) | | `WORKSPACE_BASE` | `/tmp/sessions` | Base directory for session workspaces | -| `WORKER_API_KEY` | *(required)* | API key that whitelisted hotkeys must provide via `X-Api-Key` header | +| `BITTENSOR_NETUID` | `100` | Bittensor subnet ID for validator lookup | +| `MIN_VALIDATOR_STAKE_TAO` | `10000` | Minimum TAO stake for validator whitelisting | +| `VALIDATOR_REFRESH_SECS` | `300` | Interval for refreshing validator whitelist (seconds) | +| `CONSENSUS_THRESHOLD` | `0.5` | Fraction of validators required for consensus (0.0–1.0) | +| `CONSENSUS_TTL_SECS` | `60` | TTL for pending consensus entries (seconds) | ## Authentication -Authentication requires four HTTP headers: `X-Hotkey` (SS58 address), `X-Nonce` (unique per-request), `X-Signature` (sr25519 hex signature of `hotkey + nonce`), and `X-Api-Key`. The authorized hotkey is hardcoded as `AUTHORIZED_HOTKEY` in `src/config.rs`. The API key is configured via the `WORKER_API_KEY` environment variable (required). Verification steps: hotkey must match `AUTHORIZED_HOTKEY`, API key must match, SS58 format must be valid, nonce must not have been seen before (replay protection via `NonceStore` in `src/auth.rs` with 5-minute TTL), and the sr25519 signature must verify against the hotkey's public key using the Substrate signing context. Only requests passing all checks can submit batches via `POST /submit`. All other endpoints are open. +Authentication requires three HTTP headers: `X-Hotkey` (SS58 address), `X-Nonce` (unique per-request), and `X-Signature` (sr25519 hex signature of `hotkey + nonce`). The authorized hotkeys are dynamically loaded from the Bittensor blockchain — all validators on netuid 100 with ≥10,000 TAO stake and an active validator permit are whitelisted. The whitelist refreshes every 5 minutes. Verification steps: hotkey must be in the validator whitelist, SS58 format must be valid, nonce must not have been seen before (replay protection via `NonceStore` in `src/auth.rs` with 5-minute TTL), and the sr25519 signature must verify against the hotkey's public key using the Substrate signing context. Only requests passing all checks can submit batches via `POST /submit`. Evaluations are only triggered when ≥50% of whitelisted validators have submitted the same archive payload (identified by SHA-256 hash). All other endpoints are open. diff --git a/Cargo.lock b/Cargo.lock index 78e393e..787c7a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,25 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli", +] + [[package]] name = "adler2" version = "2.0.1" @@ -29,6 +48,33 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom 0.3.4", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.4" @@ -38,6 +84,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -48,1830 +100,5457 @@ dependencies = [ ] [[package]] -name = "anyhow" -version = "1.0.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" - -[[package]] -name = "arbitrary" -version = "1.4.2" +name = "anstream" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ - "derive_arbitrary", + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", ] [[package]] -name = "arrayref" -version = "0.3.9" +name = "anstyle" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] -name = "arrayvec" -version = "0.7.6" +name = "anstyle-parse" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] [[package]] -name = "async-trait" -version = "0.1.89" +name = "anstyle-query" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "proc-macro2", - "quote", - "syn", + "windows-sys 0.60.2", ] [[package]] -name = "atomic-waker" -version = "1.1.2" +name = "anstyle-wincon" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.60.2", +] [[package]] -name = "autocfg" -version = "1.5.0" +name = "anyhow" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" [[package]] -name = "axum" -version = "0.7.9" +name = "arbitrary" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" dependencies = [ - "async-trait", - "axum-core", - "base64", - "bytes", - "futures-util", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-util", - "itoa", - "matchit", - "memchr", - "mime", - "multer", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "serde_json", - "serde_path_to_error", - "serde_urlencoded", - "sha1", - "sync_wrapper", - "tokio", - "tokio-tungstenite", - "tower", - "tower-layer", - "tower-service", - "tracing", + "derive_arbitrary", ] [[package]] -name = "axum-core" -version = "0.4.5" +name = "arc-swap" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +checksum = "f9f3647c145568cec02c42054e07bdf9a5a698e15b466fb2341bfc393cd24aa5" dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "http-body-util", - "mime", - "pin-project-lite", "rustversion", - "sync_wrapper", - "tower-layer", - "tower-service", - "tracing", ] [[package]] -name = "base64" -version = "0.22.1" +name = "argon2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" +dependencies = [ + "base64ct", + "blake2", + "cpufeatures", + "password-hash", +] [[package]] -name = "bitflags" -version = "2.11.0" +name = "ark-bls12-377" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "fb00293ba84f51ce3bd026bd0de55899c4e68f0a39a5728cebae3a73ffdc0a4f" +dependencies = [ + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-std 0.4.0", +] [[package]] -name = "block-buffer" -version = "0.10.4" +name = "ark-bls12-381" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" dependencies = [ - "generic-array", + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", ] [[package]] -name = "bs58" -version = "0.5.1" +name = "ark-bls12-381" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +checksum = "3df4dcc01ff89867cd86b0da835f23c3f02738353aaee7dde7495af71363b8d5" dependencies = [ - "tinyvec", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", ] [[package]] -name = "bumpalo" -version = "3.19.1" +name = "ark-ec" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff 0.4.2", + "ark-poly 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "hashbrown 0.13.2", + "itertools 0.10.5", + "num-traits", + "zeroize", +] [[package]] -name = "byteorder" -version = "1.5.0" +name = "ark-ec" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce" +dependencies = [ + "ahash", + "ark-ff 0.5.0", + "ark-poly 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "educe", + "fnv", + "hashbrown 0.15.5", + "itertools 0.13.0", + "num-bigint", + "num-integer", + "num-traits", + "zeroize", +] [[package]] -name = "bytes" -version = "1.11.1" +name = "ark-ed-on-bls12-381-bandersnatch" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "1786b2e3832f6f0f7c8d62d5d5a282f6952a1ab99981c54cd52b6ac1d8f02df5" +dependencies = [ + "ark-bls12-381 0.5.0", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-std 0.5.0", +] [[package]] -name = "bzip2" -version = "0.5.2" +name = "ark-ff" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" dependencies = [ - "bzip2-sys", + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", ] [[package]] -name = "bzip2-sys" -version = "0.1.13+1.0.8" +name = "ark-ff" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" -dependencies = [ - "cc", - "pkg-config", +checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" +dependencies = [ + "ark-ff-asm 0.5.0", + "ark-ff-macros 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "arrayvec 0.7.6", + "digest 0.10.7", + "educe", + "itertools 0.13.0", + "num-bigint", + "num-traits", + "paste", + "zeroize", ] [[package]] -name = "cc" -version = "1.2.56" +name = "ark-ff-asm" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" dependencies = [ - "find-msvc-tools", - "jobserver", - "libc", - "shlex", + "quote", + "syn 1.0.109", ] [[package]] -name = "cfg-if" -version = "1.0.4" +name = "ark-ff-asm" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" +dependencies = [ + "quote", + "syn 2.0.115", +] [[package]] -name = "chrono" -version = "0.4.43" +name = "ark-ff-macros" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ - "iana-time-zone", - "js-sys", + "num-bigint", "num-traits", - "serde", - "wasm-bindgen", - "windows-link", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "cipher" -version = "0.4.4" +name = "ark-ff-macros" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" dependencies = [ - "crypto-common", - "inout", + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.115", ] [[package]] -name = "constant_time_eq" -version = "0.3.1" +name = "ark-poly" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "hashbrown 0.13.2", +] [[package]] -name = "core-foundation" -version = "0.9.4" +name = "ark-poly" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27" dependencies = [ - "core-foundation-sys", - "libc", + "ahash", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "educe", + "fnv", + "hashbrown 0.15.5", ] [[package]] -name = "core-foundation" -version = "0.10.1" +name = "ark-serialize" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ - "core-foundation-sys", - "libc", + "ark-serialize-derive 0.4.2", + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint", ] [[package]] -name = "core-foundation-sys" -version = "0.8.7" +name = "ark-serialize" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" +dependencies = [ + "ark-serialize-derive 0.5.0", + "ark-std 0.5.0", + "arrayvec 0.7.6", + "digest 0.10.7", + "num-bigint", +] [[package]] -name = "cpufeatures" -version = "0.2.17" +name = "ark-serialize-derive" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" dependencies = [ - "libc", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "crc" -version = "3.4.0" +name = "ark-serialize-derive" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" dependencies = [ - "crc-catalog", + "proc-macro2", + "quote", + "syn 2.0.115", ] [[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.5.0" +name = "ark-std" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ - "cfg-if", + "num-traits", + "rand 0.8.5", ] [[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crypto-common" -version = "0.1.7" +name = "ark-std" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" dependencies = [ - "generic-array", - "rand_core", - "typenum", + "num-traits", + "rand 0.8.5", ] [[package]] -name = "curve25519-dalek" -version = "4.1.3" +name = "ark-transcript" +version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +checksum = "47c1c928edb9d8ff24cb5dcb7651d3a98494fff3099eee95c2404cd813a9139f" dependencies = [ - "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "digest", - "fiat-crypto", - "rustc_version", - "subtle", - "zeroize", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "digest 0.10.7", + "rand_core 0.6.4", + "sha3", ] [[package]] -name = "curve25519-dalek-derive" +name = "ark-vrf" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn", +checksum = "0d63e9780640021b74d02b32895d8cec1b4abe8e5547b560a6bda6b14b78c6da" +dependencies = [ + "ark-bls12-381 0.5.0", + "ark-ec 0.5.0", + "ark-ed-on-bls12-381-bandersnatch", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "digest 0.10.7", + "rand_chacha 0.3.1", + "sha2 0.10.9", + "w3f-ring-proof", + "zeroize", ] [[package]] -name = "dashmap" -version = "6.1.0" +name = "array-bytes" +version = "6.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" -dependencies = [ - "cfg-if", - "crossbeam-utils", - "hashbrown 0.14.5", - "lock_api", - "once_cell", - "parking_lot_core", -] +checksum = "5d5dde061bd34119e902bbb2d9b90c5692635cf59fb91d582c2b68043f1b8293" [[package]] -name = "data-encoding" -version = "2.10.0" +name = "arrayref" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] -name = "deflate64" -version = "0.1.10" +name = "arrayvec" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26bf8fc351c5ed29b5c2f0cbbac1b209b74f60ecd62e675a998df72c49af5204" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", +] [[package]] -name = "deranged" -version = "0.5.6" +name = "arrayvec" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc3dc5ad92c2e2d1c193bbbbdf2ea477cb81331de4f3103f267ca18368b988c4" -dependencies = [ - "powerfmt", -] +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] -name = "derive_arbitrary" -version = "1.4.2" +name = "async-channel" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" dependencies = [ - "proc-macro2", - "quote", - "syn", + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", ] [[package]] -name = "digest" -version = "0.10.7" +name = "async-executor" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a" dependencies = [ - "block-buffer", - "crypto-common", - "subtle", + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "pin-project-lite", + "slab", ] [[package]] -name = "displaydoc" -version = "0.2.5" +name = "async-fs" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5" dependencies = [ - "proc-macro2", - "quote", - "syn", + "async-lock", + "blocking", + "futures-lite", ] [[package]] -name = "encoding_rs" -version = "0.8.35" +name = "async-io" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" dependencies = [ + "autocfg", "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "windows-sys 0.61.2", ] [[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.14" +name = "async-lock" +version = "3.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" dependencies = [ - "libc", - "windows-sys 0.61.2", + "event-listener", + "event-listener-strategy", + "pin-project-lite", ] [[package]] -name = "fastrand" -version = "2.3.0" +name = "async-net" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" +dependencies = [ + "async-io", + "blocking", + "futures-lite", +] [[package]] -name = "fiat-crypto" -version = "0.2.9" +name = "async-process" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" +dependencies = [ + "async-channel", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix", +] [[package]] -name = "filetime" -version = "0.2.27" +name = "async-signal" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" +checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" dependencies = [ + "async-io", + "async-lock", + "atomic-waker", "cfg-if", - "libc", - "libredox", + "futures-core", + "futures-io", + "rustix", + "signal-hook-registry", + "slab", + "windows-sys 0.61.2", ] [[package]] -name = "find-msvc-tools" -version = "0.1.9" +name = "async-task" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] -name = "flate2" -version = "1.1.9" +name = "async-trait" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ - "crc32fast", - "miniz_oxide", + "proc-macro2", + "quote", + "syn 2.0.115", ] [[package]] -name = "fnv" -version = "1.0.7" +name = "atomic-take" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +checksum = "a8ab6b55fe97976e46f91ddbed8d147d966475dc29b2032757ba47e02376fbc3" [[package]] -name = "foldhash" -version = "0.1.5" +name = "atomic-waker" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] -name = "foreign-types" -version = "0.3.2" +name = "autocfg" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "aws-lc-rs" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9a7b350e3bb1767102698302bc37256cbd48422809984b98d292c40e2579aa9" dependencies = [ - "foreign-types-shared", + "aws-lc-sys", + "zeroize", ] [[package]] -name = "foreign-types-shared" -version = "0.1.1" +name = "aws-lc-sys" +version = "0.37.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +checksum = "b092fe214090261288111db7a2b2c2118e5a7f30dc2569f1732c4069a6840549" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] [[package]] -name = "form_urlencoded" -version = "1.2.2" +name = "axum" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" dependencies = [ + "async-trait", + "axum-core", + "axum-macros", + "base64", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "multer", "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sha1", + "sync_wrapper", + "tokio", + "tokio-tungstenite", + "tower", + "tower-layer", + "tower-service", + "tracing", ] [[package]] -name = "futures" -version = "0.3.31" +name = "axum-core" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", + "async-trait", + "bytes", "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper", + "tower-layer", + "tower-service", + "tracing", ] [[package]] -name = "futures-channel" -version = "0.3.31" +name = "axum-macros" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "57d123550fa8d071b7255cb0cc04dc302baa6c8c4a79f55701552684d8399bce" dependencies = [ - "futures-core", - "futures-sink", + "proc-macro2", + "quote", + "syn 2.0.115", ] [[package]] -name = "futures-core" -version = "0.3.31" +name = "axum-server" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "c1ab4a3ec9ea8a657c72d99a03a824af695bd0fb5ec639ccbd9cd3543b41a5f9" +dependencies = [ + "arc-swap", + "bytes", + "fs-err 3.3.0", + "http", + "http-body", + "hyper", + "hyper-util", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] [[package]] -name = "futures-executor" -version = "0.3.31" +name = "backoff" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" dependencies = [ "futures-core", - "futures-task", - "futures-util", + "getrandom 0.2.17", + "instant", + "pin-project-lite", + "rand 0.8.5", + "tokio", ] [[package]] -name = "futures-io" -version = "0.3.31" +name = "backtrace" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-link", +] [[package]] -name = "futures-macro" -version = "0.3.31" +name = "base16ct" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] -name = "futures-sink" -version = "0.3.31" +name = "base58" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" [[package]] -name = "futures-task" -version = "0.3.31" +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] -name = "futures-util" -version = "0.3.31" +name = "base64ct" +version = "1.8.3" 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", -] +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] -name = "generic-array" -version = "0.14.7" +name = "binary-merkle-tree" +version = "16.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "95c9f6900c9fd344d53fbdfb36e1343429079d73f4168c8ef48884bf15616dbd" dependencies = [ - "typenum", - "version_check", + "hash-db", + "log", + "parity-scale-codec", ] [[package]] -name = "getrandom" -version = "0.2.17" +name = "bip39" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +checksum = "90dbd31c98227229239363921e60fcf5e558e43ec69094d46fc4996f08d1d5bc" dependencies = [ - "cfg-if", - "libc", - "wasi", + "bitcoin_hashes 0.14.1", + "serde", + "unicode-normalization", ] [[package]] -name = "getrandom" -version = "0.3.4" +name = "bitcoin-internals" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "r-efi", - "wasip2", - "wasm-bindgen", -] +checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" [[package]] -name = "getrandom" -version = "0.4.1" +name = "bitcoin_hashes" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" +checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasip2", - "wasip3", + "bitcoin-internals", + "hex-conservative 0.1.2", ] [[package]] -name = "getrandom_or_panic" -version = "0.0.3" +name = "bitcoin_hashes" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea1015b5a70616b688dc230cfe50c8af89d972cb132d5a622814d29773b10b9" +checksum = "26ec84b80c482df901772e931a9a681e26a1b9ee2302edeff23cb30328745c8b" dependencies = [ - "rand", - "rand_core", + "hex-conservative 0.2.2", ] [[package]] -name = "h2" -version = "0.4.13" +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" + +[[package]] +name = "bittensor-rs" +version = "0.1.0" +source = "git+https://github.com/cortexlm/bittensor-rs?branch=main#eb58916af5a4d7fef74ef00ea0d61519880b101f" dependencies = [ - "atomic-waker", + "anyhow", + "argon2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "async-trait", + "axum", + "axum-server", + "backoff", + "base64", + "bip39", "bytes", - "fnv", - "futures-core", - "futures-sink", + "chrono", + "clap", + "comfy-table", + "console", + "crypto_secretbox", + "dialoguer", + "dirs", + "futures", + "governor", + "hex", "http", - "indexmap", - "slab", + "indicatif", + "num-traits", + "parity-scale-codec", + "rand 0.9.2", + "rand_chacha 0.3.1", + "regex", + "reqwest", + "scale-decode", + "scale-encode", + "scale-info", + "serde", + "serde_json", + "sha2 0.10.9", + "sp-core", + "sp-runtime", + "subxt", + "thiserror 2.0.18", + "tle", "tokio", - "tokio-util", + "tokio-retry", + "tower", + "tower-http", "tracing", + "tracing-appender", + "tracing-subscriber", + "uuid", + "w3f-bls 0.1.3", + "zeroize", ] [[package]] -name = "hashbrown" -version = "0.14.5" +name = "bitvec" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] [[package]] -name = "hashbrown" -version = "0.15.5" +name = "blake2" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "foldhash", + "digest 0.10.7", ] [[package]] -name = "hashbrown" -version = "0.16.1" +name = "blake2-rfc" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +dependencies = [ + "arrayvec 0.4.12", + "constant_time_eq 0.1.5", +] [[package]] -name = "heck" -version = "0.5.0" +name = "blake2b_simd" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +checksum = "b79834656f71332577234b50bfc009996f7449e0c056884e6a02492ded0ca2f3" +dependencies = [ + "arrayref", + "arrayvec 0.7.6", + "constant_time_eq 0.4.2", +] [[package]] -name = "hex" -version = "0.4.3" +name = "block-buffer" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] [[package]] -name = "hmac" -version = "0.12.1" +name = "block-buffer" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "digest", + "generic-array", ] [[package]] -name = "http" -version = "1.4.0" +name = "blocking" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" dependencies = [ - "bytes", - "itoa", + "async-channel", + "async-task", + "futures-io", + "futures-lite", + "piper", ] [[package]] -name = "http-body" -version = "1.0.1" +name = "bounded-collections" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +checksum = "dee8eddd066a8825ec5570528e6880471210fd5d88cb6abbe1cfdd51ca249c33" dependencies = [ - "bytes", - "http", + "jam-codec", + "log", + "parity-scale-codec", + "scale-info", + "serde", ] [[package]] -name = "http-body-util" -version = "0.1.3" +name = "bs58" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "pin-project-lite", + "tinyvec", ] [[package]] -name = "httparse" -version = "1.10.1" +name = "bumpalo" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] -name = "httpdate" -version = "1.0.3" +name = "byte-slice-cast" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" [[package]] -name = "hyper" -version = "1.8.1" +name = "byteorder" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" -dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "pin-utils", - "smallvec", - "tokio", - "want", -] +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] -name = "hyper-rustls" -version = "0.27.7" +name = "bytes" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "bzip2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" dependencies = [ - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", + "bzip2-sys", ] [[package]] -name = "hyper-tls" -version = "0.6.0" +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 = "cc" +version = "1.2.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + +[[package]] +name = "chrono" +version = "0.4.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link", +] + +[[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 = "4.5.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5caf74d17c3aec5495110c34cc3f78644bfa89af6c8993ed4de2790e49b6499" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "370daa45065b80218950227371916a1633217ae42b2715b2287b606dcd618e24" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "clap_lex" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" + +[[package]] +name = "cmake" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" +dependencies = [ + "cc", +] + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "comfy-table" +version = "7.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958c5d6ecf1f214b4c2bbbbf6ab9523a864bd136dcf71a7e8904799acfe1ad47" +dependencies = [ + "crossterm", + "unicode-segmentation", + "unicode-width", +] + +[[package]] +name = "common-path" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2382f75942f4b3be3690fe4f86365e9c853c1587d6ee58212cebf6e2a9ccd101" + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "console" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "unicode-width", + "windows-sys 0.59.0", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const_format" +version = "0.2.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "constant_time_eq" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" + +[[package]] +name = "convert_case" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" +dependencies = [ + "unicode-segmentation", +] + +[[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" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +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 = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +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.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crossterm" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" +dependencies = [ + "bitflags 2.11.0", + "crossterm_winapi", + "document-features", + "parking_lot", + "rustix", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[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.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "crypto_secretbox" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d6cf87adf719ddf43a805e92c6870a531aedda35ff640442cbaf8674e141e1" +dependencies = [ + "aead", + "cipher", + "generic-array", + "poly1305", + "salsa20", + "subtle", + "zeroize", +] + +[[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 0.10.7", + "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.115", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.115", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data-encoding" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" + +[[package]] +name = "deflate64" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26bf8fc351c5ed29b5c2f0cbbac1b209b74f60ecd62e675a998df72c49af5204" + +[[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 = "deranged" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc3dc5ad92c2e2d1c193bbbbdf2ea477cb81331de4f3103f267ca18368b988c4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive-syn-parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "derive-where" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "derive_arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl 1.0.0", +] + +[[package]] +name = "derive_more" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +dependencies = [ + "derive_more-impl 2.1.1", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "derive_more-impl" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.115", + "unicode-xid", +] + +[[package]] +name = "dialoguer" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bce805d770f407bc62102fca7c2c64ceef2fbcb2b8bd19d2765ce093980de" +dependencies = [ + "console", + "shell-words", + "tempfile", + "thiserror 1.0.69", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[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.115", +] + +[[package]] +name = "docify" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a772b62b1837c8f060432ddcc10b17aae1453ef17617a99bc07789252d2a5896" +dependencies = [ + "docify_macros", +] + +[[package]] +name = "docify_macros" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60e6be249b0a462a14784a99b19bf35a667bb5e09de611738bb7362fa4c95ff7" +dependencies = [ + "common-path", + "derive-syn-parse", + "once_cell", + "proc-macro2", + "quote", + "regex", + "syn 2.0.115", + "termcolor", + "toml", + "walkdir", +] + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "serdect", + "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.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2 0.10.9", + "subtle", + "zeroize", +] + +[[package]] +name = "ed25519-zebra" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0017d969298eec91e3db7a2985a8cab4df6341d86e6f3a6f5878b13fb7846bc9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "hashbrown 0.15.5", + "pkcs8", + "rand_core 0.6.4", + "sha2 0.10.9", + "subtle", + "zeroize", +] + +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[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 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "serdect", + "subtle", + "zeroize", +] + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enum-ordinalize" +version = "4.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a1091a7bb1f8f2c4b28f1fe2cef4980ca2d410a3d727d67ecc3178c9b0800f0" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "environmental" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48c92028aaa870e83d51c64e5d4e0b6981b360c522198c23959f219a4e1b15b" + +[[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.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +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 = "expander" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2c470c71d91ecbd179935b24170459e926382eaaa86b590b78814e180d8a8e2" +dependencies = [ + "blake2", + "file-guard", + "fs-err 2.11.0", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[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 = "file-guard" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21ef72acf95ec3d7dbf61275be556299490a245f017cf084bd23b4f68cf9407c" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "filetime" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" +dependencies = [ + "cfg-if", + "libc", + "libredox", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +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 = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "frame-decode" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c470df86cf28818dd3cd2fc4667b80dbefe2236c722c3dc1d09e7c6c82d6dfcd" +dependencies = [ + "frame-metadata", + "parity-scale-codec", + "scale-decode", + "scale-encode", + "scale-info", + "scale-type-resolver", + "sp-crypto-hashing", + "thiserror 2.0.18", +] + +[[package]] +name = "frame-metadata" +version = "23.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba5be0edbdb824843a0f9c6f0906ecfc66c5316218d74457003218b24909ed0" +dependencies = [ + "cfg-if", + "parity-scale-codec", + "scale-info", + "serde", +] + +[[package]] +name = "fs-err" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +dependencies = [ + "autocfg", +] + +[[package]] +name = "fs-err" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fde052dbfc920003cfd2c8e2c6e6d4cc7c1091538c3a24226cec0665ab08c0" +dependencies = [ + "autocfg", + "tokio", +] + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.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-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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "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.115", +] + +[[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-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + +[[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.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasip2", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", + "wasip3", +] + +[[package]] +name = "getrandom_or_panic" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea1015b5a70616b688dc230cfe50c8af89d972cb132d5a622814d29773b10b9" +dependencies = [ + "rand 0.8.5", + "rand_core 0.6.4", +] + +[[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.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + +[[package]] +name = "governor" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9efcab3c1958580ff1f25a2a41be1668f7603d849bb63af523b208a3cc1223b8" +dependencies = [ + "cfg-if", + "dashmap", + "futures-sink", + "futures-timer", + "futures-util", + "getrandom 0.3.4", + "hashbrown 0.16.1", + "nonzero_ext", + "parking_lot", + "portable-atomic", + "quanta", + "rand 0.9.2", + "smallvec", + "spinning_top", + "web-time", +] + +[[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.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" + +[[package]] +name = "hash-db" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e7d7786361d7425ae2fe4f9e407eb0efaa0840f5212d109cc018c40c35c6ab4" + +[[package]] +name = "hash256-std-hasher" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" +dependencies = [ + "crunchy", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.1.5", + "serde", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", +] + +[[package]] +name = "hdrhistogram" +version = "7.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" +dependencies = [ + "byteorder", + "num-traits", +] + +[[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.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-conservative" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20" + +[[package]] +name = "hex-conservative" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda06d18ac606267c40c04e41b9947729bf8b9efe74bd4e82b61a5f26a510b9f" +dependencies = [ + "arrayvec 0.7.6", +] + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array", + "hmac 0.8.1", +] + +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[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", + "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 = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ - "bytes", - "http-body-util", - "hyper", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "impl-codec" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d40b9d5e17727407e55028eafc22b2dc68781786e6d7eb8a21103f5058e3a14" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-num-traits" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "803d15461ab0dcc56706adf266158acbc44ccf719bf7d0af30705f58b90a4b8c" +dependencies = [ + "integer-sqrt", + "num-traits", + "uint", +] + +[[package]] +name = "impl-serde" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a143eada6a1ec4aefa5049037a26a6d597bfd64f8c026d07b77133e02b7dd0b" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", + "serde", + "serde_core", +] + +[[package]] +name = "indicatif" +version = "0.17.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" +dependencies = [ + "console", + "number_prefix", + "portable-atomic", + "unicode-width", + "web-time", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "integer-sqrt" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" +dependencies = [ + "num-traits", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + +[[package]] +name = "jam-codec" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb948eace373d99de60501a02fb17125d30ac632570de20dccc74370cdd611b9" +dependencies = [ + "arrayvec 0.7.6", + "bitvec", + "byte-slice-cast", + "const_format", + "impl-trait-for-tuples", + "jam-codec-derive", + "rustversion", + "serde", +] + +[[package]] +name = "jam-codec-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "319af585c4c8a6b5552a52b7787a1ab3e4d59df7614190b1f85b9b842488789d" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "jsonrpsee" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e281ae70cc3b98dac15fced3366a880949e65fc66e345ce857a5682d152f3e62" +dependencies = [ + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", + "jsonrpsee-ws-client", +] + +[[package]] +name = "jsonrpsee-client-transport" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4280b709ac3bb5e16cf3bad5056a0ec8df55fa89edfe996361219aadc2c7ea" +dependencies = [ + "base64", + "futures-util", + "http", + "jsonrpsee-core", + "pin-project", + "rustls", + "rustls-pki-types", + "rustls-platform-verifier", + "soketto", + "thiserror 1.0.69", + "tokio", + "tokio-rustls", + "tokio-util", + "tracing", + "url", +] + +[[package]] +name = "jsonrpsee-core" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "348ee569eaed52926b5e740aae20863762b16596476e943c9e415a6479021622" +dependencies = [ + "async-trait", + "futures-timer", + "futures-util", + "jsonrpsee-types", + "pin-project", + "rustc-hash", + "serde", + "serde_json", + "thiserror 1.0.69", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "jsonrpsee-types" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0f05e0028e55b15dbd2107163b3c744cd3bb4474f193f95d9708acbf5677e44" +dependencies = [ + "http", + "serde", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "jsonrpsee-ws-client" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78fc744f17e7926d57f478cf9ca6e1ee5d8332bf0514860b1a3cdf1742e614cc" +dependencies = [ + "http", + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", + "url", +] + +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "serdect", + "sha2 0.10.9", +] + +[[package]] +name = "keccak" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "keccak-hash" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e1b8590eb6148af2ea2d75f38e7d29f5ca970d5a4df456b3ef19b8b415d0264" +dependencies = [ + "primitive-types", + "tiny-keccak", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[package]] +name = "libc" +version = "0.2.182" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" + +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "libredox" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +dependencies = [ + "bitflags 2.11.0", + "libc", + "redox_syscall 0.7.1", +] + +[[package]] +name = "libsecp256k1" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79019718125edc905a079a70cfa5f3820bc76139fc91d6f9abc27ea2a887139" +dependencies = [ + "arrayref", + "base64", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.8.5", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.5", +] + +[[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.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "memory-db" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e300c54e3239a86f9c61cc63ab0f03862eb40b1c6e065dc6fd6ceaeff6da93d" +dependencies = [ + "foldhash 0.1.5", + "hash-db", + "hashbrown 0.15.5", +] + +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "multer" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http", + "httparse", + "memchr", + "mime", + "spin", + "version_check", +] + +[[package]] +name = "multi-stash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685a9ac4b61f4e728e1d2c6a7844609c16527aeb5e6c865915c08e619c16410f" + +[[package]] +name = "native-tls" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5d26952a508f321b4d3d2e80e78fc2603eaefcdf0c30783867f19586518bdc" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "nom" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" +dependencies = [ + "memchr", +] + +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + +[[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.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" + +[[package]] +name = "num-format" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3" +dependencies = [ + "arrayvec 0.7.6", + "itoa", +] + +[[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-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "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.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "openssl" +version = "0.10.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" +dependencies = [ + "bitflags 2.11.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + +[[package]] +name = "openssl-sys" +version = "0.9.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "parity-bip39" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e69bf016dc406eff7d53a7d3f7cf1c2e72c82b9088aac1118591e36dd2cd3e9" +dependencies = [ + "bitcoin_hashes 0.13.0", + "rand 0.8.5", + "rand_core 0.6.4", + "serde", + "unicode-normalization", +] + +[[package]] +name = "parity-scale-codec" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799781ae679d79a948e13d4824a40970bfa500058d245760dd857301059810fa" +dependencies = [ + "arrayvec 0.7.6", + "bitvec", + "byte-slice-cast", + "bytes", + "const_format", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "rustversion", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b4653168b563151153c9e4c08ebed57fb8262bebfa79711552fa983c623e7a" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.18", + "smallvec", + "windows-link", +] + +[[package]] +name = "password-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest 0.10.7", + "hmac 0.12.1", + "password-hash", +] + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[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.115", +] + +[[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 = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[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 = "polkavm-common" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a5794b695626ba70d29e66e3f4f4835767452a6723f3a0bc20884b07088fe8" + +[[package]] +name = "polkavm-derive" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95282a203ae1f6828a04ff334145c3f6dc718bba6d3959805d273358b45eab93" +dependencies = [ + "polkavm-derive-impl-macro", +] + +[[package]] +name = "polkavm-derive-impl" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6069dc7995cde6e612b868a02ce48b54397c6d2582bd1b97b63aabbe962cd779" +dependencies = [ + "polkavm-common", + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "polkavm-derive-impl-macro" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581d34cafec741dc5ffafbb341933c205b6457f3d76257a9d99fb56687219c91" +dependencies = [ + "polkavm-derive-impl", + "syn 2.0.115", +] + +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix", + "windows-sys 0.61.2", +] + +[[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.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + +[[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 = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.115", +] + +[[package]] +name = "primitive-types" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d15600a7d856470b7d278b3fe0e311fe28c2526348549f8ef2ff7db3299c87f5" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-num-traits", + "impl-serde", + "scale-info", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit 0.23.10+spec-1.0.0", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prometheus" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" +dependencies = [ + "cfg-if", + "fnv", + "lazy_static", + "memchr", + "parking_lot", + "thiserror 1.0.69", +] + +[[package]] +name = "quanta" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ab5a9d756f0d97bdc89019bd2e4ea098cf9cde50ee7564dde6b81ccc8f06c7" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi", + "web-sys", + "winapi", +] + +[[package]] +name = "quote" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", ] [[package]] -name = "hyper-util" -version = "0.1.20" +name = "rand" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + +[[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.5", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "raw-cpuid" +version = "11.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" +dependencies = [ + "bitflags 2.11.0", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.11.0", +] + +[[package]] +name = "redox_syscall" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35985aa610addc02e24fc232012c86fd11f14111180f902b67e2d5331f8ebf2b" +dependencies = [ + "bitflags 2.11.0", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror 1.0.69", +] + +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" + +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64", "bytes", - "futures-channel", + "encoding_rs", + "futures-core", "futures-util", + "h2", "http", "http-body", + "http-body-util", "hyper", - "ipnet", - "libc", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "js-sys", + "log", + "mime", + "native-tls", "percent-encoding", "pin-project-lite", - "socket2", - "system-configuration", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", "tokio", + "tokio-native-tls", + "tokio-util", + "tower", + "tower-http", "tower-service", - "tracing", - "windows-registry", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", ] [[package]] -name = "iana-time-zone" -version = "0.1.65" +name = "rfc6979" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core", + "hmac 0.12.1", + "subtle", ] [[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" +name = "ring" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", ] [[package]] -name = "icu_collections" +name = "rustc-demangle" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" + +[[package]] +name = "rustc-hash" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", + "semver", ] [[package]] -name = "icu_locale_core" -version = "2.1.1" +name = "rustix" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", + "bitflags 2.11.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +dependencies = [ + "aws-lc-rs", + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +dependencies = [ + "zeroize", ] [[package]] -name = "icu_normalizer" -version = "2.1.1" +name = "rustls-platform-verifier" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "19787cda76408ec5404443dc8b31795c87cd8fec49762dc75fa727740d34acc1" dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs 0.26.11", + "windows-sys 0.52.0", ] [[package]] -name = "icu_normalizer_data" -version = "2.1.1" +name = "rustls-platform-verifier-android" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] -name = "icu_properties" -version = "2.1.2" +name = "rustls-webpki" +version = "0.103.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" dependencies = [ - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", + "aws-lc-rs", + "ring", + "rustls-pki-types", + "untrusted", ] [[package]] -name = "icu_properties_data" -version = "2.1.2" +name = "rustversion" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] -name = "icu_provider" -version = "2.1.1" +name = "ruzstd" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] +checksum = "e5ff0cc5e135c8870a775d3320910cd9b564ec036b4dc0b8741629020be63f01" [[package]] -name = "id-arena" -version = "2.3.0" +name = "ryu" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] -name = "idna" -version = "1.1.0" +name = "salsa20" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", + "cipher", ] [[package]] -name = "idna_adapter" -version = "1.2.1" +name = "same-file" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ - "icu_normalizer", - "icu_properties", + "winapi-util", ] [[package]] -name = "indexmap" -version = "2.13.0" +name = "scale-bits" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "27243ab0d2d6235072b017839c5f0cd1a3b1ce45c0f7a715363b0c7d36c76c94" dependencies = [ - "equivalent", - "hashbrown 0.16.1", + "parity-scale-codec", + "scale-info", + "scale-type-resolver", "serde", - "serde_core", ] [[package]] -name = "inout" -version = "0.1.4" +name = "scale-decode" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +checksum = "8d6ed61699ad4d54101ab5a817169259b5b0efc08152f8632e61482d8a27ca3d" dependencies = [ - "generic-array", + "parity-scale-codec", + "primitive-types", + "scale-bits", + "scale-decode-derive", + "scale-type-resolver", + "smallvec", + "thiserror 2.0.18", ] [[package]] -name = "ipnet" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "iri-string" -version = "0.7.10" +name = "scale-decode-derive" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +checksum = "65cb245f7fdb489e7ba43a616cbd34427fe3ba6fe0edc1d0d250085e6c84f3ec" dependencies = [ - "memchr", - "serde", + "darling", + "proc-macro2", + "quote", + "syn 2.0.115", ] [[package]] -name = "itoa" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" - -[[package]] -name = "jobserver" -version = "0.1.34" +name = "scale-encode" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "f2a976d73564a59e482b74fd5d95f7518b79ca8c8ca5865398a4d629dd15ee50" dependencies = [ - "getrandom 0.3.4", - "libc", + "parity-scale-codec", + "primitive-types", + "scale-bits", + "scale-encode-derive", + "scale-type-resolver", + "smallvec", + "thiserror 2.0.18", ] [[package]] -name = "js-sys" -version = "0.3.85" +name = "scale-encode-derive" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +checksum = "17020f2d59baabf2ddcdc20a4e567f8210baf089b8a8d4785f5fd5e716f92038" dependencies = [ - "once_cell", - "wasm-bindgen", + "darling", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.115", ] [[package]] -name = "keccak" -version = "0.1.6" +name = "scale-info" +version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" dependencies = [ - "cpufeatures", + "bitvec", + "cfg-if", + "derive_more 1.0.0", + "parity-scale-codec", + "scale-info-derive", + "serde", ] [[package]] -name = "lazy_static" -version = "1.5.0" +name = "scale-info-derive" +version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.115", +] [[package]] -name = "leb128fmt" -version = "0.1.0" +name = "scale-type-resolver" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" +checksum = "f0cded6518aa0bd6c1be2b88ac81bf7044992f0f154bfbabd5ad34f43512abcb" +dependencies = [ + "scale-info", + "smallvec", +] [[package]] -name = "libc" -version = "0.2.182" +name = "scale-typegen" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" +checksum = "05c61b6b706a3eaad63b506ab50a1d2319f817ae01cf753adcc3f055f9f0fcd6" +dependencies = [ + "proc-macro2", + "quote", + "scale-info", + "syn 2.0.115", + "thiserror 2.0.18", +] [[package]] -name = "libredox" -version = "0.1.12" +name = "scale-value" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +checksum = "b3b64809a541e8d5a59f7a9d67cc700cdf5d7f907932a83a0afdedc90db07ccb" dependencies = [ - "bitflags", - "libc", - "redox_syscall 0.7.1", + "base58", + "blake2", + "either", + "parity-scale-codec", + "scale-bits", + "scale-decode", + "scale-encode", + "scale-type-resolver", + "serde", + "thiserror 2.0.18", + "yap", ] [[package]] -name = "linux-raw-sys" -version = "0.11.0" +name = "schannel" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +dependencies = [ + "windows-sys 0.61.2", +] [[package]] -name = "litemap" -version = "0.8.1" +name = "schnellru" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "356285bbf17bea63d9e52e96bd18f039672ac92b55b8cb997d6162a2a37d1649" +dependencies = [ + "ahash", + "cfg-if", + "hashbrown 0.13.2", +] [[package]] -name = "lock_api" -version = "0.4.14" +name = "schnorrkel" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +checksum = "6e9fcb6c2e176e86ec703e22560d99d65a5ee9056ae45a08e13e84ebf796296f" dependencies = [ - "scopeguard", + "aead", + "arrayref", + "arrayvec 0.7.6", + "curve25519-dalek", + "getrandom_or_panic", + "merlin", + "rand_core 0.6.4", + "serde_bytes", + "sha2 0.10.9", + "subtle", + "zeroize", ] [[package]] -name = "log" -version = "0.4.29" +name = "scopeguard" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] -name = "lzma-rs" -version = "0.3.0" +name = "sec1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ - "byteorder", - "crc", + "base16ct", + "der", + "generic-array", + "pkcs8", + "serdect", + "subtle", + "zeroize", ] [[package]] -name = "lzma-sys" -version = "0.1.20" +name = "secp256k1" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +checksum = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10" dependencies = [ - "cc", - "libc", - "pkg-config", + "secp256k1-sys", ] [[package]] -name = "matchers" -version = "0.2.0" +name = "secp256k1-sys" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +checksum = "e5d1746aae42c19d583c3c1a8c646bfad910498e2051c551a7f2e3c0c9fbb7eb" dependencies = [ - "regex-automata", + "cc", ] [[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - -[[package]] -name = "memchr" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" - -[[package]] -name = "merlin" -version = "3.0.0" +name = "secrecy" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" dependencies = [ - "byteorder", - "keccak", - "rand_core", "zeroize", ] [[package]] -name = "mime" -version = "0.3.17" +name = "security-framework" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +checksum = "d17b898a6d6948c3a8ee4372c17cb384f90d2e6e912ef00895b14fd7ab54ec38" +dependencies = [ + "bitflags 2.11.0", + "core-foundation 0.10.1", + "core-foundation-sys", + "libc", + "security-framework-sys", +] [[package]] -name = "miniz_oxide" -version = "0.8.9" +name = "security-framework-sys" +version = "2.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +checksum = "321c8673b092a9a42605034a9879d73cb79101ed5fd117bc9a597b89b4e9e61a" dependencies = [ - "adler2", - "simd-adler32", + "core-foundation-sys", + "libc", ] [[package]] -name = "mio" -version = "1.1.1" +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + +[[package]] +name = "serde" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ - "libc", - "wasi", - "windows-sys 0.61.2", + "serde_core", + "serde_derive", ] [[package]] -name = "multer" -version = "3.1.0" +name = "serde_bytes" +version = "0.11.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" dependencies = [ - "bytes", - "encoding_rs", - "futures-util", - "http", - "httparse", - "memchr", - "mime", - "spin", - "version_check", + "serde", + "serde_core", ] [[package]] -name = "native-tls" -version = "0.2.16" +name = "serde_cbor" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5d26952a508f321b4d3d2e80e78fc2603eaefcdf0c30783867f19586518bdc" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", + "half", + "serde", ] [[package]] -name = "nu-ansi-term" -version = "0.50.3" +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ - "windows-sys 0.61.2", + "serde_derive", ] [[package]] -name = "num-conv" -version = "0.2.0" +name = "serde_derive" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", +] [[package]] -name = "num-traits" -version = "0.2.19" +name = "serde_json" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ - "autocfg", + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", ] [[package]] -name = "once_cell" -version = "1.21.3" +name = "serde_path_to_error" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", +] [[package]] -name = "openssl" -version = "0.10.75" +name = "serde_spanned" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", + "serde", ] [[package]] -name = "openssl-macros" -version = "0.1.1" +name = "serde_urlencoded" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ - "proc-macro2", - "quote", - "syn", + "form_urlencoded", + "itoa", + "ryu", + "serde", ] [[package]] -name = "openssl-probe" -version = "0.2.1" +name = "serde_yaml" +version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] [[package]] -name = "openssl-sys" -version = "0.9.111" +name = "serdect" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", + "base16ct", + "serde", ] [[package]] -name = "parking_lot" -version = "0.12.5" +name = "sha1" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ - "lock_api", - "parking_lot_core", + "cfg-if", + "cpufeatures", + "digest 0.10.7", ] [[package]] -name = "parking_lot_core" -version = "0.9.12" +name = "sha2" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ + "block-buffer 0.9.0", "cfg-if", - "libc", - "redox_syscall 0.5.18", - "smallvec", - "windows-link", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", ] [[package]] -name = "pbkdf2" -version = "0.12.2" +name = "sha2" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ - "digest", - "hmac", + "cfg-if", + "cpufeatures", + "digest 0.10.7", ] [[package]] -name = "percent-encoding" -version = "2.3.2" +name = "sha3" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] [[package]] -name = "pin-project-lite" -version = "0.2.16" +name = "sharded-slab" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] [[package]] -name = "pin-utils" -version = "0.1.0" +name = "shell-words" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" [[package]] -name = "pkg-config" -version = "0.3.32" +name = "shlex" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] -name = "potential_utf" -version = "0.1.4" +name = "signal-hook-registry" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ - "zerovec", + "errno", + "libc", ] [[package]] -name = "powerfmt" -version = "0.2.0" +name = "signature" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] [[package]] -name = "ppv-lite86" -version = "0.2.21" +name = "simd-adler32" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" [[package]] -name = "prettyplease" -version = "0.2.37" +name = "simple-mermaid" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] +checksum = "620a1d43d70e142b1d46a929af51d44f383db9c7a2ec122de2cd992ccfcf3c18" [[package]] -name = "proc-macro2" -version = "1.0.106" +name = "siphasher" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" [[package]] -name = "quote" -version = "1.0.44" +name = "slab" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" -dependencies = [ - "proc-macro2", -] +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] -name = "r-efi" -version = "5.3.0" +name = "smallvec" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] -name = "rand" -version = "0.8.5" +name = "smol" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "a33bd3e260892199c3ccfc487c88b2da2265080acb316cd920da72fdfd7c599f" dependencies = [ - "libc", - "rand_chacha", - "rand_core", + "async-channel", + "async-executor", + "async-fs", + "async-io", + "async-lock", + "async-net", + "async-process", + "blocking", + "futures-lite", ] [[package]] -name = "rand_chacha" -version = "0.3.1" +name = "smoldot" +version = "0.19.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +checksum = "e16e5723359f0048bf64bfdfba64e5732a56847d42c4fd3fe56f18280c813413" dependencies = [ - "ppv-lite86", - "rand_core", + "arrayvec 0.7.6", + "async-lock", + "atomic-take", + "base64", + "bip39", + "blake2-rfc", + "bs58", + "chacha20", + "crossbeam-queue", + "derive_more 2.1.1", + "ed25519-zebra", + "either", + "event-listener", + "fnv", + "futures-lite", + "futures-util", + "hashbrown 0.15.5", + "hex", + "hmac 0.12.1", + "itertools 0.14.0", + "libm", + "libsecp256k1", + "merlin", + "nom", + "num-bigint", + "num-rational", + "num-traits", + "pbkdf2", + "pin-project", + "poly1305", + "rand 0.8.5", + "rand_chacha 0.3.1", + "ruzstd", + "schnorrkel", + "serde", + "serde_json", + "sha2 0.10.9", + "sha3", + "siphasher", + "slab", + "smallvec", + "soketto", + "twox-hash 2.1.2", + "wasmi", + "x25519-dalek", + "zeroize", ] [[package]] -name = "rand_core" -version = "0.6.4" +name = "smoldot-light" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "f1bba9e591716567d704a8252feeb2f1261a286e1e2cbdd4e49e9197c34a14e2" dependencies = [ - "getrandom 0.2.17", + "async-channel", + "async-lock", + "base64", + "blake2-rfc", + "bs58", + "derive_more 2.1.1", + "either", + "event-listener", + "fnv", + "futures-channel", + "futures-lite", + "futures-util", + "hashbrown 0.15.5", + "hex", + "itertools 0.14.0", + "log", + "lru", + "parking_lot", + "pin-project", + "rand 0.8.5", + "rand_chacha 0.3.1", + "serde", + "serde_json", + "siphasher", + "slab", + "smol", + "smoldot", + "zeroize", ] [[package]] -name = "redox_syscall" -version = "0.5.18" +name = "socket2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" dependencies = [ - "bitflags", + "libc", + "windows-sys 0.60.2", ] [[package]] -name = "redox_syscall" -version = "0.7.1" +name = "soketto" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35985aa610addc02e24fc232012c86fd11f14111180f902b67e2d5331f8ebf2b" +checksum = "2e859df029d160cb88608f5d7df7fb4753fd20fdfb4de5644f3d8b8440841721" dependencies = [ - "bitflags", + "base64", + "bytes", + "futures", + "httparse", + "log", + "rand 0.8.5", + "sha1", ] [[package]] -name = "regex-automata" -version = "0.4.14" +name = "sp-application-crypto" +version = "43.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "e6067f30cf3fb9270471cf24a65d73b33330f32573abab2d97196f83fc076de0" dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-io", ] [[package]] -name = "regex-syntax" -version = "0.8.9" +name = "sp-arithmetic" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" +checksum = "c5f4755af7cc57f4a2a830e134b403fc832caa5d93dacb970ffc7ac717f38c40" +dependencies = [ + "docify", + "integer-sqrt", + "num-traits", + "parity-scale-codec", + "scale-info", + "serde", + "static_assertions", +] [[package]] -name = "reqwest" -version = "0.12.28" +name = "sp-core" +version = "38.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +checksum = "707602208776d0e19d4269bb3f68c5306cacbdfabbb2e4d8d499af7b907bb0a3" dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-tls", - "hyper-util", - "js-sys", + "ark-vrf", + "array-bytes", + "bitflags 1.3.2", + "blake2", + "bounded-collections", + "bs58", + "dyn-clone", + "ed25519-zebra", + "futures", + "hash-db", + "hash256-std-hasher", + "impl-serde", + "itertools 0.11.0", + "k256", + "libsecp256k1", "log", - "mime", - "native-tls", - "percent-encoding", - "pin-project-lite", - "rustls-pki-types", + "merlin", + "parity-bip39", + "parity-scale-codec", + "parking_lot", + "paste", + "primitive-types", + "rand 0.8.5", + "scale-info", + "schnorrkel", + "secp256k1", + "secrecy", "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tokio-native-tls", - "tokio-util", - "tower", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", + "sha2 0.10.9", + "sp-crypto-hashing", + "sp-debug-derive", + "sp-externalities", + "sp-std", + "sp-storage", + "ss58-registry", + "substrate-bip39", + "thiserror 1.0.69", + "tracing", + "w3f-bls 0.1.9", + "zeroize", ] [[package]] -name = "ring" -version = "0.17.14" +name = "sp-crypto-hashing" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +checksum = "bc9927a7f81334ed5b8a98a4a978c81324d12bd9713ec76b5c68fd410174c5eb" dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.17", - "libc", - "untrusted", - "windows-sys 0.52.0", + "blake2b_simd", + "byteorder", + "digest 0.10.7", + "sha2 0.10.9", + "sha3", + "twox-hash 1.6.3", ] [[package]] -name = "rustc_version" -version = "0.4.1" +name = "sp-debug-derive" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +checksum = "48d09fa0a5f7299fb81ee25ae3853d26200f7a348148aed6de76be905c007dbe" dependencies = [ - "semver", + "proc-macro2", + "quote", + "syn 2.0.115", ] [[package]] -name = "rustix" -version = "1.1.3" +name = "sp-externalities" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +checksum = "30cbf059dce180a8bf8b6c8b08b6290fa3d1c7f069a60f1df038ab5dd5fc0ba6" dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.61.2", + "environmental", + "parity-scale-codec", + "sp-storage", ] [[package]] -name = "rustls" -version = "0.23.36" +name = "sp-io" +version = "43.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +checksum = "cf2059e3b338c0174e8dc9e144cc7e612165ca4c960c3a23c6c99c29ef34768f" dependencies = [ - "once_cell", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", + "bytes", + "docify", + "ed25519-dalek", + "libsecp256k1", + "log", + "parity-scale-codec", + "polkavm-derive", + "rustversion", + "secp256k1", + "sp-core", + "sp-crypto-hashing", + "sp-externalities", + "sp-keystore", + "sp-runtime-interface", + "sp-state-machine", + "sp-tracing", + "sp-trie", + "tracing", + "tracing-core", ] [[package]] -name = "rustls-pki-types" -version = "1.14.0" +name = "sp-keystore" +version = "0.44.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +checksum = "8a5c0b829014afc22e992be2c198f2677592db43267fc218e9f3207dbbfb6fbb" dependencies = [ - "zeroize", + "parity-scale-codec", + "parking_lot", + "sp-core", + "sp-externalities", ] [[package]] -name = "rustls-webpki" -version = "0.103.9" +name = "sp-panic-handler" +version = "13.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "c8b52e69a577cbfdea62bfaf16f59eb884422ce98f78b5cd8d9bf668776bced1" dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", + "backtrace", + "regex", ] [[package]] -name = "rustversion" -version = "1.0.22" +name = "sp-runtime" +version = "44.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "ee57bb77e94c26306501426ac82aca401bb80ee2279ecdba148f68e76cf58247" +dependencies = [ + "binary-merkle-tree", + "docify", + "either", + "hash256-std-hasher", + "impl-trait-for-tuples", + "log", + "num-traits", + "parity-scale-codec", + "paste", + "rand 0.8.5", + "scale-info", + "serde", + "simple-mermaid", + "sp-application-crypto", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-std", + "sp-trie", + "sp-weights", + "tracing", + "tuplex", +] [[package]] -name = "ryu" -version = "1.0.23" +name = "sp-runtime-interface" +version = "32.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +checksum = "efdc2bc2adbfb9b4396ae07c7d94db20414d2351608e29e1f44e4f643b387c70" +dependencies = [ + "bytes", + "impl-trait-for-tuples", + "parity-scale-codec", + "polkavm-derive", + "sp-externalities", + "sp-runtime-interface-proc-macro", + "sp-std", + "sp-storage", + "sp-tracing", + "sp-wasm-interface", + "static_assertions", +] [[package]] -name = "schannel" -version = "0.1.28" +name = "sp-runtime-interface-proc-macro" +version = "20.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +checksum = "04178084ae654b3924934a56943ee73e3562db4d277e948393561b08c3b5b5fe" dependencies = [ - "windows-sys 0.61.2", + "Inflector", + "expander", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.115", ] [[package]] -name = "schnorrkel" -version = "0.11.5" +name = "sp-state-machine" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e9fcb6c2e176e86ec703e22560d99d65a5ee9056ae45a08e13e84ebf796296f" +checksum = "042677239cca40eb6a0d70e0b220f5693516f59853c2d678de471a79652cd16e" dependencies = [ - "aead", - "arrayref", - "arrayvec", - "curve25519-dalek", - "getrandom_or_panic", - "merlin", - "rand_core", - "serde_bytes", - "sha2", - "subtle", - "zeroize", + "hash-db", + "log", + "parity-scale-codec", + "parking_lot", + "rand 0.8.5", + "smallvec", + "sp-core", + "sp-externalities", + "sp-panic-handler", + "sp-trie", + "thiserror 1.0.69", + "tracing", + "trie-db", ] [[package]] -name = "scopeguard" -version = "1.2.0" +name = "sp-std" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +checksum = "12f8ee986414b0a9ad741776762f4083cd3a5128449b982a3919c4df36874834" [[package]] -name = "security-framework" -version = "3.6.0" +name = "sp-storage" +version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d17b898a6d6948c3a8ee4372c17cb384f90d2e6e912ef00895b14fd7ab54ec38" +checksum = "ee3b70ca340e41cde9d2e069d354508a6e37a6573d66f7cc38f11549002f64ec" dependencies = [ - "bitflags", - "core-foundation 0.10.1", - "core-foundation-sys", - "libc", - "security-framework-sys", + "impl-serde", + "parity-scale-codec", + "ref-cast", + "serde", + "sp-debug-derive", ] [[package]] -name = "security-framework-sys" -version = "2.16.0" +name = "sp-tracing" +version = "19.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "321c8673b092a9a42605034a9879d73cb79101ed5fd117bc9a597b89b4e9e61a" +checksum = "f2c7372456c39cc81e15befe54d0caab8378f2b30fd34d1bcb5f0f56631c6b6e" dependencies = [ - "core-foundation-sys", - "libc", + "parity-scale-codec", + "regex", + "tracing", + "tracing-core", + "tracing-subscriber", ] [[package]] -name = "semver" -version = "1.0.27" +name = "sp-trie" +version = "41.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "0e34c2336d82297f453340adb1188ec0592abcd862df1f7027994b8e1e5fc139" +dependencies = [ + "ahash", + "foldhash 0.1.5", + "hash-db", + "hashbrown 0.15.5", + "memory-db", + "nohash-hasher", + "parity-scale-codec", + "parking_lot", + "rand 0.8.5", + "scale-info", + "schnellru", + "sp-core", + "sp-externalities", + "substrate-prometheus-endpoint", + "thiserror 1.0.69", + "tracing", + "trie-db", + "trie-root", +] [[package]] -name = "serde" -version = "1.0.228" +name = "sp-wasm-interface" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "dd177d0658f3df0492f28bd39d665133a7868db5aa66c8642c949b6265430719" dependencies = [ - "serde_core", - "serde_derive", + "anyhow", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", ] [[package]] -name = "serde_bytes" -version = "0.11.19" +name = "sp-weights" +version = "33.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +checksum = "b4c34d353fdc6469da8fae9248ffc1f34faaf04bec8cabc43fd77681dcbc8517" dependencies = [ + "bounded-collections", + "parity-scale-codec", + "scale-info", "serde", - "serde_core", + "smallvec", + "sp-arithmetic", + "sp-debug-derive", ] [[package]] -name = "serde_core" -version = "1.0.228" +name = "spin" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] -name = "serde_derive" -version = "1.0.228" +name = "spinning_top" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" dependencies = [ - "proc-macro2", - "quote", - "syn", + "lock_api", ] [[package]] -name = "serde_json" -version = "1.0.149" +name = "spki" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", + "base64ct", + "der", ] [[package]] -name = "serde_path_to_error" -version = "0.1.20" +name = "ss58-registry" +version = "1.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +checksum = "19409f13998e55816d1c728395af0b52ec066206341d939e22e7766df9b494b8" dependencies = [ - "itoa", + "Inflector", + "num-format", + "proc-macro2", + "quote", "serde", - "serde_core", + "serde_json", + "unicode-xid", ] [[package]] -name = "serde_urlencoded" -version = "0.7.1" +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "static_assertions" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" +name = "strsim" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" -dependencies = [ - "indexmap", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", -] +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] -name = "sha1" -version = "0.10.6" +name = "substrate-bip39" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "ca58ffd742f693dc13d69bdbb2e642ae239e0053f6aab3b104252892f856700a" dependencies = [ - "cfg-if", - "cpufeatures", - "digest", + "hmac 0.12.1", + "pbkdf2", + "schnorrkel", + "sha2 0.10.9", + "zeroize", ] [[package]] -name = "sha2" -version = "0.10.9" +name = "substrate-prometheus-endpoint" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "d23e4bc8e910a312820d589047ab683928b761242dbe31dee081fbdb37cbe0be" dependencies = [ - "cfg-if", - "cpufeatures", - "digest", + "http-body-util", + "hyper", + "hyper-util", + "log", + "prometheus", + "thiserror 1.0.69", + "tokio", ] [[package]] -name = "sharded-slab" -version = "0.1.7" +name = "subtle" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] -name = "shlex" -version = "1.3.0" +name = "subxt" +version = "0.44.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "3e689b7f5635ffd08301b1b7d427300f7c10bc0e66069c4068d36ce6921bc736" +dependencies = [ + "async-trait", + "derive-where", + "either", + "frame-metadata", + "futures", + "hex", + "jsonrpsee", + "parity-scale-codec", + "primitive-types", + "scale-bits", + "scale-decode", + "scale-encode", + "scale-info", + "scale-value", + "serde", + "serde_json", + "sp-crypto-hashing", + "subxt-core", + "subxt-lightclient", + "subxt-macro", + "subxt-metadata", + "subxt-rpcs", + "thiserror 2.0.18", + "tokio", + "tokio-util", + "tracing", + "url", + "wasm-bindgen-futures", + "web-time", +] [[package]] -name = "signal-hook-registry" -version = "1.4.8" +name = "subxt-codegen" +version = "0.44.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +checksum = "740eedc385673e6c5e0de60d2ea6d12d311359d3ccea35b86b9161e3acaf938f" dependencies = [ - "errno", - "libc", + "heck", + "parity-scale-codec", + "proc-macro2", + "quote", + "scale-info", + "scale-typegen", + "subxt-metadata", + "syn 2.0.115", + "thiserror 2.0.18", ] [[package]] -name = "simd-adler32" -version = "0.3.8" +name = "subxt-core" +version = "0.44.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "1f2f40f6145c1805e37339c4e460c4a18fcafae913b15d2c648b7cac991fd903" +dependencies = [ + "base58", + "blake2", + "derive-where", + "frame-decode", + "frame-metadata", + "hashbrown 0.14.5", + "hex", + "impl-serde", + "keccak-hash", + "parity-scale-codec", + "primitive-types", + "scale-bits", + "scale-decode", + "scale-encode", + "scale-info", + "scale-value", + "serde", + "serde_json", + "sp-crypto-hashing", + "subxt-metadata", + "thiserror 2.0.18", + "tracing", +] [[package]] -name = "slab" -version = "0.4.12" +name = "subxt-lightclient" +version = "0.44.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" +checksum = "61321269d3dcc65b8f884eb4d10e393f7bca22b0688d373a0285d4e8ad7221be" +dependencies = [ + "futures", + "futures-util", + "serde", + "serde_json", + "smoldot-light", + "thiserror 2.0.18", + "tokio", + "tokio-stream", + "tracing", +] [[package]] -name = "smallvec" -version = "1.15.1" +name = "subxt-macro" +version = "0.44.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "efc6c5054278308a2b01804f00676ece77270a358a2caee6df1358cf81ec0cd5" +dependencies = [ + "darling", + "parity-scale-codec", + "proc-macro-error2", + "quote", + "scale-typegen", + "subxt-codegen", + "subxt-metadata", + "subxt-utils-fetchmetadata", + "syn 2.0.115", +] [[package]] -name = "socket2" -version = "0.6.2" +name = "subxt-metadata" +version = "0.44.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +checksum = "bc80c07a71e180a42ba0f12727b1f9f39bf03746df6d546d24edbbc137f64fa1" dependencies = [ - "libc", - "windows-sys 0.60.2", + "frame-decode", + "frame-metadata", + "hashbrown 0.14.5", + "parity-scale-codec", + "scale-info", + "sp-crypto-hashing", + "thiserror 2.0.18", ] [[package]] -name = "spin" -version = "0.9.8" +name = "subxt-rpcs" +version = "0.44.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "3fe65228472ea5a6bd23d8f2cd12833706466d2425805b2a38ecedc258df141a" +dependencies = [ + "derive-where", + "frame-metadata", + "futures", + "hex", + "impl-serde", + "jsonrpsee", + "parity-scale-codec", + "primitive-types", + "serde", + "serde_json", + "subxt-core", + "subxt-lightclient", + "thiserror 2.0.18", + "tokio-util", + "tracing", + "url", +] [[package]] -name = "stable_deref_trait" -version = "1.2.1" +name = "subxt-utils-fetchmetadata" +version = "0.44.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +checksum = "a26ed947c63b4620429465c9f7e1f346433ddc21780c4bfcfade1e3a4dcdfab8" +dependencies = [ + "hex", + "parity-scale-codec", + "thiserror 2.0.18", +] [[package]] -name = "subtle" -version = "2.6.1" +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] name = "syn" @@ -1901,7 +5580,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.115", ] [[package]] @@ -1910,7 +5589,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ - "bitflags", + "bitflags 2.11.0", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -1925,6 +5604,12 @@ dependencies = [ "libc", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "tar" version = "0.4.44" @@ -1951,11 +5636,12 @@ dependencies = [ [[package]] name = "term-executor" -version = "1.1.0" +version = "1.2.0" dependencies = [ "anyhow", "axum", "base64", + "bittensor-rs", "bs58", "chrono", "dashmap", @@ -1963,13 +5649,13 @@ dependencies = [ "futures", "hex", "parking_lot", - "rand_core", + "rand_core 0.6.4", "reqwest", "schnorrkel", "serde", "serde_json", "serde_yaml", - "sha2", + "sha2 0.10.9", "tar", "tempfile", "thiserror 2.0.18", @@ -1984,6 +5670,15 @@ dependencies = [ "zip", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -2010,7 +5705,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.115", ] [[package]] @@ -2021,7 +5716,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.115", ] [[package]] @@ -2040,10 +5735,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", + "itoa", "num-conv", "powerfmt", "serde_core", "time-core", + "time-macros", ] [[package]] @@ -2052,6 +5749,25 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +[[package]] +name = "time-macros" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "tinystr" version = "0.8.2" @@ -2077,6 +5793,34 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tle" +version = "0.1.0" +source = "git+https://github.com/ideal-lab5/timelock?rev=5416406cfd32799e31e1795393d4916894de4468#5416406cfd32799e31e1795393d4916894de4468" +dependencies = [ + "aes-gcm", + "ark-bls12-377", + "ark-bls12-381 0.4.0", + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-poly 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "array-bytes", + "chacha20poly1305", + "generic-array", + "parity-scale-codec", + "rand_chacha 0.3.1", + "rand_core 0.6.4", + "scale-info", + "serde", + "serde_cbor", + "serde_json", + "sha2 0.10.9", + "sha3", + "w3f-bls 0.1.3", +] + [[package]] name = "tokio" version = "1.49.0" @@ -2102,7 +5846,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.115", ] [[package]] @@ -2115,6 +5859,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-retry" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f" +dependencies = [ + "pin-project", + "rand 0.8.5", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.26.4" @@ -2167,11 +5922,83 @@ checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ "bytes", "futures-core", + "futures-io", "futures-sink", "pin-project-lite", "tokio", ] +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime 0.6.11", + "toml_edit 0.22.27", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime 0.6.11", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.23.10+spec-1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +dependencies = [ + "indexmap", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.9+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + [[package]] name = "tower" version = "0.5.3" @@ -2180,9 +6007,13 @@ checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", + "hdrhistogram", + "indexmap", "pin-project-lite", + "slab", "sync_wrapper", "tokio", + "tokio-util", "tower-layer", "tower-service", "tracing", @@ -2194,13 +6025,14 @@ version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ - "bitflags", + "bitflags 2.11.0", "bytes", "futures-util", "http", "http-body", "iri-string", "pin-project-lite", + "tokio", "tower", "tower-layer", "tower-service", @@ -2231,6 +6063,18 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-appender" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" +dependencies = [ + "crossbeam-channel", + "thiserror 2.0.18", + "time", + "tracing-subscriber", +] + [[package]] name = "tracing-attributes" version = "0.1.31" @@ -2239,7 +6083,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.115", ] [[package]] @@ -2263,6 +6107,16 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-serde" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" +dependencies = [ + "serde", + "tracing-core", +] + [[package]] name = "tracing-subscriber" version = "0.3.22" @@ -2273,12 +6127,37 @@ dependencies = [ "nu-ansi-term", "once_cell", "regex-automata", + "serde", + "serde_json", "sharded-slab", "smallvec", "thread_local", + "time", "tracing", "tracing-core", "tracing-log", + "tracing-serde", +] + +[[package]] +name = "trie-db" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c0670ab45a6b7002c7df369fee950a27cf29ae0474343fd3a15aa15f691e7a6" +dependencies = [ + "hash-db", + "log", + "rustc-hex", + "smallvec", +] + +[[package]] +name = "trie-root" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4ed310ef5ab98f5fa467900ed906cb9232dd5376597e00fd4cba2a449d06c0b" +dependencies = [ + "hash-db", ] [[package]] @@ -2299,30 +6178,97 @@ dependencies = [ "http", "httparse", "log", - "rand", + "rand 0.8.5", "sha1", "thiserror 1.0.69", "utf-8", ] +[[package]] +name = "tuplex" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "676ac81d5454c4dcf37955d34fa8626ede3490f744b86ca14a7b90168d2a08aa" + +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "digest 0.10.7", + "rand 0.8.5", + "static_assertions", +] + +[[package]] +name = "twox-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" + [[package]] name = "typenum" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +[[package]] +name = "uint" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "909988d098b2f738727b161a106cfc7cab00c539c2687a8836f8e565976fb53e" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + [[package]] name = "unicode-ident" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + [[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 = "unsafe-libyaml" version = "0.2.11" @@ -2359,6 +6305,12 @@ 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.21.0" @@ -2388,6 +6340,105 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "w3f-bls" +version = "0.1.3" +source = "git+https://github.com/opentensor/bls?branch=fix-no-std#4ac443d11a6c9fdebe329d113702ad7387ba1688" +dependencies = [ + "ark-bls12-377", + "ark-bls12-381 0.4.0", + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-serialize-derive 0.4.2", + "arrayref", + "digest 0.10.7", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_core 0.6.4", + "sha2 0.10.9", + "sha3", + "zeroize", +] + +[[package]] +name = "w3f-bls" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6bfb937b3d12077654a9e43e32a4e9c20177dd9fea0f3aba673e7840bb54f32" +dependencies = [ + "ark-bls12-377", + "ark-bls12-381 0.4.0", + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-serialize-derive 0.4.2", + "arrayref", + "digest 0.10.7", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_core 0.6.4", + "sha2 0.10.9", + "sha3", + "zeroize", +] + +[[package]] +name = "w3f-pcs" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbe7a8d5c914b69392ab3b267f679a2e546fe29afaddce47981772ac71bd02e1" +dependencies = [ + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-poly 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "merlin", +] + +[[package]] +name = "w3f-plonk-common" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aca389e494fe08c5c108b512e2328309036ee1c0bc7bdfdb743fef54d448c8c" +dependencies = [ + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-poly 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "getrandom_or_panic", + "rand_core 0.6.4", + "w3f-pcs", +] + +[[package]] +name = "w3f-ring-proof" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a639379402ad51504575dbd258740383291ac8147d3b15859bdf1ea48c677de" +dependencies = [ + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-poly 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "ark-transcript", + "w3f-pcs", + "w3f-plonk-common", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -2467,7 +6518,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.115", "wasm-bindgen-shared", ] @@ -2487,7 +6538,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" dependencies = [ "leb128fmt", - "wasmparser", + "wasmparser 0.244.0", ] [[package]] @@ -2499,7 +6550,7 @@ dependencies = [ "anyhow", "indexmap", "wasm-encoder", - "wasmparser", + "wasmparser 0.244.0", ] [[package]] @@ -2515,13 +6566,63 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasmi" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19af97fcb96045dd1d6b4d23e2b4abdbbe81723dbc5c9f016eb52145b320063" +dependencies = [ + "arrayvec 0.7.6", + "multi-stash", + "smallvec", + "spin", + "wasmi_collections", + "wasmi_core", + "wasmi_ir", + "wasmparser 0.221.3", +] + +[[package]] +name = "wasmi_collections" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e80d6b275b1c922021939d561574bf376613493ae2b61c6963b15db0e8813562" + +[[package]] +name = "wasmi_core" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8c51482cc32d31c2c7ff211cd2bedd73c5bd057ba16a2ed0110e7a96097c33" +dependencies = [ + "downcast-rs", + "libm", +] + +[[package]] +name = "wasmi_ir" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e431a14c186db59212a88516788bd68ed51f87aa1e08d1df742522867b5289a" +dependencies = [ + "wasmi_core", +] + +[[package]] +name = "wasmparser" +version = "0.221.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d06bfa36ab3ac2be0dee563380147a5b81ba10dd8885d7fbbc9eb574be67d185" +dependencies = [ + "bitflags 2.11.0", +] + [[package]] name = "wasmparser" version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags", + "bitflags 2.11.0", "hashbrown 0.15.5", "indexmap", "semver", @@ -2537,6 +6638,65 @@ dependencies = [ "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-root-certs" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e" +dependencies = [ + "webpki-root-certs 1.0.6", +] + +[[package]] +name = "webpki-root-certs" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca" +dependencies = [ + "rustls-pki-types", +] + +[[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.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-core" version = "0.62.2" @@ -2558,7 +6718,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.115", ] [[package]] @@ -2569,7 +6729,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.115", ] [[package]] @@ -2607,6 +6767,24 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[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" @@ -2616,6 +6794,15 @@ 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-sys" version = "0.60.2" @@ -2634,6 +6821,36 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[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" @@ -2667,6 +6884,18 @@ dependencies = [ "windows_x86_64_msvc 0.53.1", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[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" @@ -2679,6 +6908,18 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[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" @@ -2691,6 +6932,18 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[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" @@ -2715,6 +6968,18 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[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" @@ -2727,6 +6992,18 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[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" @@ -2739,6 +7016,18 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[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" @@ -2751,6 +7040,18 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[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" @@ -2763,6 +7064,15 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" +[[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +dependencies = [ + "memchr", +] + [[package]] name = "wit-bindgen" version = "0.51.0" @@ -2793,7 +7103,7 @@ dependencies = [ "heck", "indexmap", "prettyplease", - "syn", + "syn 2.0.115", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -2809,7 +7119,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn", + "syn 2.0.115", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -2821,7 +7131,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags", + "bitflags 2.11.0", "indexmap", "log", "serde", @@ -2829,7 +7139,7 @@ dependencies = [ "serde_json", "wasm-encoder", "wasm-metadata", - "wasmparser", + "wasmparser 0.244.0", "wit-parser", ] @@ -2848,7 +7158,7 @@ dependencies = [ "serde_derive", "serde_json", "unicode-xid", - "wasmparser", + "wasmparser 0.244.0", ] [[package]] @@ -2857,6 +7167,27 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x25519-dalek" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +dependencies = [ + "curve25519-dalek", + "rand_core 0.6.4", + "serde", + "zeroize", +] + [[package]] name = "xattr" version = "1.6.1" @@ -2876,6 +7207,12 @@ dependencies = [ "lzma-sys", ] +[[package]] +name = "yap" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfe269e7b803a5e8e20cbd97860e136529cd83bf2c9c6d37b142467e7e1f051f" + [[package]] name = "yoke" version = "0.8.1" @@ -2895,7 +7232,7 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.115", "synstructure", ] @@ -2916,7 +7253,7 @@ checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.115", ] [[package]] @@ -2936,7 +7273,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.115", "synstructure", ] @@ -2957,7 +7294,7 @@ checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.115", ] [[package]] @@ -2990,7 +7327,7 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.115", ] [[package]] @@ -3002,14 +7339,14 @@ dependencies = [ "aes", "arbitrary", "bzip2", - "constant_time_eq", + "constant_time_eq 0.3.1", "crc32fast", "crossbeam-utils", "deflate64", "displaydoc", "flate2", "getrandom 0.3.4", - "hmac", + "hmac 0.12.1", "indexmap", "lzma-rs", "memchr", diff --git a/Cargo.toml b/Cargo.toml index 1549f6d..247a434 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,5 +62,11 @@ bs58 = "0.5" schnorrkel = "0.11" rand_core = { version = "0.6", features = ["getrandom"] } +# Bittensor substrate client +bittensor-rs = { git = "https://github.com/cortexlm/bittensor-rs", branch = "main" } + [dev-dependencies] tokio-test = "0.4" + +[patch.crates-io] +w3f-bls = { git = "https://github.com/opentensor/bls", branch = "fix-no-std" } diff --git a/Dockerfile b/Dockerfile index 8422996..6c88404 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,9 @@ # ── Build stage ── FROM rust:1.93-slim-bookworm AS builder RUN apt-get update -qq && apt-get install -y -qq --no-install-recommends \ - pkg-config libssl-dev && rm -rf /var/lib/apt/lists/* + pkg-config libssl-dev protobuf-compiler cmake clang mold && rm -rf /var/lib/apt/lists/* WORKDIR /build +COPY .cargo ./.cargo COPY Cargo.toml Cargo.lock ./ COPY src ./src RUN cargo build --release && strip target/release/term-executor diff --git a/src/AGENTS.md b/src/AGENTS.md index 5f33a8d..ce9ba65 100644 --- a/src/AGENTS.md +++ b/src/AGENTS.md @@ -6,11 +6,15 @@ This is a single-crate binary. All source files live in `src/` with no sub-modul ``` main.rs - ├── config.rs (Config::from_env, AUTHORIZED_HOTKEY) + ├── config.rs (Config::from_env, Bittensor/consensus settings) ├── auth.rs (NonceStore created in main, reaper_loop spawned from main) + ├── validator_whitelist.rs (ValidatorWhitelist created in main, refresh_loop spawned) + ├── consensus.rs (ConsensusManager created in main, reaper_loop spawned) ├── handlers.rs (Axum router + AppState) │ ├── auth.rs (extract_auth_headers + verify_request for /submit) - │ ├── executor.rs (spawned from submit handler) + │ ├── validator_whitelist.rs (whitelist check in verify_request) + │ ├── consensus.rs (record_vote + consensus check in /submit) + │ ├── executor.rs (spawned from submit handler on consensus reached) │ │ ├── task.rs (extract, parse, load tasks) │ │ ├── session.rs (BatchResult/TaskResult mutation) │ │ └── cleanup.rs (work dir removal) @@ -24,8 +28,8 @@ main.rs ## File-by-File Guide ### `main.rs` -- Entry point. Initializes tracing, config, session manager, metrics, executor. -- Creates `AppState`, builds Axum router, spawns background tasks (session reaper, nonce reaper, stale dir reaper). +- Entry point. Initializes tracing, config, session manager, metrics, executor, validator whitelist, consensus manager. +- Creates `AppState`, builds Axum router, spawns background tasks (session reaper, nonce reaper, stale dir reaper, validator whitelist refresh loop, consensus TTL reaper). - Binds to `0.0.0.0:{PORT}` with graceful shutdown on CTRL+C. - **Convention**: Background tasks are spawned with `tokio::spawn` and run indefinitely. @@ -33,26 +37,45 @@ main.rs - `Config` struct with all environment-driven settings. - `Config::from_env()` reads env vars with `env_parse()` helper (returns default on missing/invalid). - `Config::print_banner()` logs a formatted startup banner. -- `AUTHORIZED_HOTKEY` — hardcoded SS58 hotkey constant for authentication. +- Includes Bittensor settings: `bittensor_netuid`, `min_validator_stake_tao`, `validator_refresh_secs`. +- Includes consensus settings: `consensus_threshold`, `consensus_ttl_secs`. - **Convention**: Add new config fields here, with a `DEFAULT_*` constant and an env var name. Always provide a sensible default. +### `validator_whitelist.rs` +- `ValidatorWhitelist` — stores `parking_lot::RwLock>` of SS58 hotkey strings. +- `new()` → returns `Arc` with empty whitelist. +- `is_whitelisted(ss58_hotkey)` → checks if hotkey is in the whitelist. +- `validator_count()` → returns number of whitelisted validators. +- `refresh_loop(netuid, min_stake_tao, refresh_secs)` → background task that refreshes every N seconds. +- `refresh_once()` → retries up to 3 times with exponential backoff; on failure, keeps cached whitelist. +- `try_refresh()` → connects via `BittensorClient::with_failover()`, syncs metagraph, filters validators by permit + active + stake, atomically replaces whitelist. +- **Convention**: The whitelist starts empty and is populated by the first successful refresh. If the whitelist is empty, all POST /submit requests are rejected with 503. + +### `consensus.rs` +- `ConsensusManager` — `DashMap` keyed by SHA-256 hex hash of archive bytes. +- `PendingConsensus` — holds archive data, voter set, creation time, concurrent_tasks setting. +- `record_vote()` — adds a validator's vote for an archive hash; returns `ConsensusStatus` (Pending, Reached, AlreadyVoted). +- `is_at_capacity()` — checks if max pending entries reached (prevents memory exhaustion). +- `reaper_loop(ttl_secs)` — background task that removes expired entries every 30 seconds. +- **Convention**: Consensus entries have a 60-second TTL. Max 100 pending entries. Duplicate votes from the same validator are silently acknowledged. + ### `handlers.rs` -- Defines `AppState` struct (`config`, `sessions`, `metrics`, `executor`, `nonce_store`, `started_at`). +- Defines `AppState` struct (`config`, `sessions`, `metrics`, `executor`, `nonce_store`, `started_at`, `validator_whitelist`, `consensus_manager`). - `router()` builds the Axum `Router` with all routes and shared state. - Route handlers: `health`, `status`, `metrics`, `submit_batch`, `get_batch`, `get_batch_tasks`, `get_task`, `list_batches`. - Routes: `GET /health`, `GET /status`, `GET /metrics`, `POST /submit`, `GET /batch/{id}`, `GET /batch/{id}/tasks`, `GET /batch/{id}/task/{task_id}`, `GET /batches`, `GET /ws`. -- `submit_batch` handler does: auth header extraction → `verify_request` (hotkey + API key + nonce + signature) → busy check → multipart upload → archive extraction → batch creation → executor spawn. +- `submit_batch` handler does: auth header extraction → whitelist empty check (503) → `verify_request` (whitelist + nonce + signature) → multipart upload → SHA-256 hash → consensus vote → if pending: return 202 with vote count → if reached: archive extraction → batch creation → executor spawn. - **Convention**: Return `Result)>` from handlers that can fail. Use `Json(serde_json::json!({...}))` for responses. ### `auth.rs` - `NonceStore` — `DashMap`-backed nonce tracker with 5-minute TTL and background reaper loop for replay protection. -- `AuthHeaders` — struct holding `hotkey`, `nonce`, `signature`, `api_key` extracted from request headers. -- `extract_auth_headers(headers)` — reads `X-Hotkey`, `X-Nonce`, `X-Signature`, `X-Api-Key` headers from request. -- `verify_request(auth, nonce_store, expected_api_key)` — full auth pipeline: hotkey match → API key match → SS58 validation → nonce replay check → sr25519 signature verification. +- `AuthHeaders` — struct holding `hotkey`, `nonce`, `signature` extracted from request headers. +- `extract_auth_headers(headers)` — reads `X-Hotkey`, `X-Nonce`, `X-Signature` headers from request. +- `verify_request(auth, nonce_store, whitelist)` — full auth pipeline: whitelist check → SS58 validation → nonce replay check → sr25519 signature verification. - `validate_ss58(address)` — validates SS58 address format using `bs58`. - `verify_sr25519_signature(ss58_hotkey, message, signature_hex)` — verifies an sr25519 signature using `schnorrkel` with the Substrate signing context. -- `AuthError` — enum with `UnauthorizedHotkey`, `InvalidHotkey`, `InvalidApiKey`, `NonceReused`, `InvalidSignature` variants, each with `.code()` and `.message()` methods. -- **Convention**: Auth is mandatory — `POST /submit` requires all four headers (`X-Hotkey`, `X-Nonce`, `X-Signature`, `X-Api-Key`). The signed message is `hotkey + nonce`. +- `AuthError` — enum with `UnauthorizedHotkey`, `InvalidHotkey`, `NonceReused`, `InvalidSignature` variants, each with `.code()` and `.message()` methods. +- **Convention**: Auth is mandatory — `POST /submit` requires three headers (`X-Hotkey`, `X-Nonce`, `X-Signature`). The signed message is `hotkey + nonce`. ### `executor.rs` - `Executor::spawn_batch(batch, archive, concurrent_limit)` — spawns a tokio task that runs all tasks in the batch. diff --git a/src/auth.rs b/src/auth.rs index 26003ca..540d552 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -1,4 +1,4 @@ -use crate::config::AUTHORIZED_HOTKEY; +use crate::validator_whitelist::ValidatorWhitelist; use dashmap::DashMap; use schnorrkel::{PublicKey, Signature}; use std::sync::Arc; @@ -41,7 +41,6 @@ pub struct AuthHeaders { pub hotkey: String, pub nonce: String, pub signature: String, - pub api_key: String, } pub fn extract_auth_headers(headers: &axum::http::HeaderMap) -> Option { @@ -63,33 +62,22 @@ pub fn extract_auth_headers(headers: &axum::http::HeaderMap) -> Option Result<(), AuthError> { - if auth.hotkey != AUTHORIZED_HOTKEY { + if !whitelist.is_whitelisted(&auth.hotkey) { return Err(AuthError::UnauthorizedHotkey); } - if auth.api_key != expected_api_key { - return Err(AuthError::InvalidApiKey); - } - if !validate_ss58(&auth.hotkey) { return Err(AuthError::InvalidHotkey); } @@ -110,7 +98,6 @@ pub fn verify_request( pub enum AuthError { UnauthorizedHotkey, InvalidHotkey, - InvalidApiKey, NonceReused, InvalidSignature, } @@ -120,7 +107,6 @@ impl AuthError { match self { AuthError::UnauthorizedHotkey => "Hotkey is not authorized", AuthError::InvalidHotkey => "Invalid SS58 hotkey format", - AuthError::InvalidApiKey => "Invalid API key", AuthError::NonceReused => "Nonce has already been used", AuthError::InvalidSignature => "Signature verification failed", } @@ -130,7 +116,6 @@ impl AuthError { match self { AuthError::UnauthorizedHotkey => "unauthorized_hotkey", AuthError::InvalidHotkey => "invalid_hotkey", - AuthError::InvalidApiKey => "invalid_api_key", AuthError::NonceReused => "nonce_reused", AuthError::InvalidSignature => "invalid_signature", } @@ -217,9 +202,11 @@ fn sp_ss58_checksum(data: &[u8]) -> [u8; 64] { mod tests { use super::*; + const TEST_SS58: &str = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"; + #[test] fn test_validate_ss58_valid() { - assert!(validate_ss58(AUTHORIZED_HOTKEY)); + assert!(validate_ss58(TEST_SS58)); } #[test] @@ -231,7 +218,7 @@ mod tests { #[test] fn test_ss58_to_public_key_bytes() { - let bytes = ss58_to_public_key_bytes(AUTHORIZED_HOTKEY); + let bytes = ss58_to_public_key_bytes(TEST_SS58); assert!(bytes.is_some()); assert_eq!(bytes.unwrap().len(), 32); } @@ -247,17 +234,15 @@ mod tests { #[test] fn test_extract_auth_headers_present() { let mut headers = axum::http::HeaderMap::new(); - headers.insert("X-Hotkey", AUTHORIZED_HOTKEY.parse().unwrap()); + headers.insert("X-Hotkey", TEST_SS58.parse().unwrap()); headers.insert("X-Nonce", "test-nonce-123".parse().unwrap()); headers.insert("X-Signature", "0xdeadbeef".parse().unwrap()); - headers.insert("X-Api-Key", "my-secret-key".parse().unwrap()); let auth = extract_auth_headers(&headers); assert!(auth.is_some()); let auth = auth.unwrap(); - assert_eq!(auth.hotkey, AUTHORIZED_HOTKEY); + assert_eq!(auth.hotkey, TEST_SS58); assert_eq!(auth.nonce, "test-nonce-123"); assert_eq!(auth.signature, "0xdeadbeef"); - assert_eq!(auth.api_key, "my-secret-key"); } #[test] @@ -267,40 +252,18 @@ mod tests { } #[test] - fn test_verify_request_unauthorized_hotkey() { + fn test_verify_request_non_whitelisted() { let store = NonceStore::new(); + let wl = ValidatorWhitelist::new(); let auth = AuthHeaders { hotkey: "5InvalidHotkey".to_string(), nonce: "nonce-1".to_string(), signature: "0x00".to_string(), - api_key: "test-key".to_string(), }; - let err = verify_request(&auth, &store, "test-key").unwrap_err(); + let err = verify_request(&auth, &store, &wl).unwrap_err(); assert!(matches!(err, AuthError::UnauthorizedHotkey)); } - #[test] - fn test_verify_request_invalid_api_key() { - let store = NonceStore::new(); - let auth = AuthHeaders { - hotkey: AUTHORIZED_HOTKEY.to_string(), - nonce: "nonce-1".to_string(), - signature: "0x00".to_string(), - api_key: "wrong-key".to_string(), - }; - let err = verify_request(&auth, &store, "correct-key").unwrap_err(); - assert!(matches!(err, AuthError::InvalidApiKey)); - } - - #[test] - fn test_extract_auth_headers_missing_api_key() { - let mut headers = axum::http::HeaderMap::new(); - headers.insert("X-Hotkey", AUTHORIZED_HOTKEY.parse().unwrap()); - headers.insert("X-Nonce", "test-nonce-123".parse().unwrap()); - headers.insert("X-Signature", "0xdeadbeef".parse().unwrap()); - assert!(extract_auth_headers(&headers).is_none()); - } - #[test] fn test_verify_sr25519_roundtrip() { use schnorrkel::{Keypair, MiniSecretKey}; @@ -309,7 +272,6 @@ mod tests { let keypair: Keypair = mini_key.expand_to_keypair(schnorrkel::ExpansionMode::Ed25519); let pub_key = keypair.public; - // Encode as SS58 (prefix 42 = generic substrate) let mut raw = Vec::with_capacity(35); raw.push(42u8); raw.extend_from_slice(&pub_key.to_bytes()); diff --git a/src/config.rs b/src/config.rs index aec90af..6fa0a6d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -10,8 +10,11 @@ const DEFAULT_MAX_ARCHIVE_BYTES: usize = 500 * 1024 * 1024; #[allow(dead_code)] const DEFAULT_MAX_OUTPUT_BYTES: usize = 1024 * 1024; const DEFAULT_WORKSPACE_BASE: &str = "/tmp/sessions"; - -pub const AUTHORIZED_HOTKEY: &str = "5GziQCcRpN8NCJktX343brnfuVe3w6gUYieeStXPD1Dag2At"; +const DEFAULT_BITTENSOR_NETUID: u16 = 100; +const DEFAULT_MIN_VALIDATOR_STAKE_TAO: f64 = 10_000.0; +const DEFAULT_VALIDATOR_REFRESH_SECS: u64 = 300; +const DEFAULT_CONSENSUS_THRESHOLD: f64 = 0.5; +const DEFAULT_CONSENSUS_TTL_SECS: u64 = 60; #[derive(Debug, Clone)] pub struct Config { @@ -25,7 +28,11 @@ pub struct Config { #[allow(dead_code)] pub max_output_bytes: usize, pub workspace_base: PathBuf, - pub worker_api_key: String, + pub bittensor_netuid: u16, + pub min_validator_stake_tao: f64, + pub validator_refresh_secs: u64, + pub consensus_threshold: f64, + pub consensus_ttl_secs: u64, } impl Config { @@ -42,8 +49,17 @@ impl Config { workspace_base: PathBuf::from( std::env::var("WORKSPACE_BASE").unwrap_or_else(|_| DEFAULT_WORKSPACE_BASE.into()), ), - worker_api_key: std::env::var("WORKER_API_KEY") - .expect("WORKER_API_KEY environment variable must be set"), + bittensor_netuid: env_parse("BITTENSOR_NETUID", DEFAULT_BITTENSOR_NETUID), + min_validator_stake_tao: env_parse( + "MIN_VALIDATOR_STAKE_TAO", + DEFAULT_MIN_VALIDATOR_STAKE_TAO, + ), + validator_refresh_secs: env_parse( + "VALIDATOR_REFRESH_SECS", + DEFAULT_VALIDATOR_REFRESH_SECS, + ), + consensus_threshold: env_parse("CONSENSUS_THRESHOLD", DEFAULT_CONSENSUS_THRESHOLD), + consensus_ttl_secs: env_parse("CONSENSUS_TTL_SECS", DEFAULT_CONSENSUS_TTL_SECS), } } @@ -55,7 +71,17 @@ impl Config { ); tracing::info!("╠══════════════════════════════════════════════════╣"); tracing::info!("║ Port: {:<28}║", self.port); - tracing::info!("║ Authorized hotkey: {}...║", &AUTHORIZED_HOTKEY[..10]); + tracing::info!("║ Bittensor netuid: {:<28}║", self.bittensor_netuid); + tracing::info!( + "║ Min stake (TAO): {:<28}║", + self.min_validator_stake_tao + ); + tracing::info!( + "║ Whitelist refresh: {:<25}s ║", + self.validator_refresh_secs + ); + tracing::info!("║ Consensus thresh: {:<28}║", self.consensus_threshold); + tracing::info!("║ Consensus TTL: {:<25}s ║", self.consensus_ttl_secs); tracing::info!("║ Max concurrent: {:<28}║", self.max_concurrent_tasks); tracing::info!("║ Session TTL: {:<25}s ║", self.session_ttl_secs); tracing::info!("║ Clone timeout: {:<25}s ║", self.clone_timeout_secs); @@ -65,7 +91,6 @@ impl Config { "║ Workspace: {:<28}║", self.workspace_base.display() ); - tracing::info!("║ API key: {:<28}║", "configured"); tracing::info!("╚══════════════════════════════════════════════════╝"); } } @@ -83,21 +108,15 @@ mod tests { #[test] fn test_config_defaults() { - std::env::set_var("WORKER_API_KEY", "test-api-key-123"); let cfg = Config::from_env(); assert_eq!(cfg.port, DEFAULT_PORT); assert_eq!(cfg.max_concurrent_tasks, DEFAULT_MAX_CONCURRENT); - assert_eq!(cfg.worker_api_key, "test-api-key-123"); + assert_eq!(cfg.bittensor_netuid, 100); + assert!((cfg.consensus_threshold - 0.5).abs() < f64::EPSILON); } #[test] fn test_env_parse_fallback() { assert_eq!(env_parse::("NONEXISTENT_VAR_XYZ", 42), 42); } - - #[test] - fn test_authorized_hotkey_valid() { - assert!(AUTHORIZED_HOTKEY.starts_with("5G")); - assert_eq!(AUTHORIZED_HOTKEY.len(), 48); - } } diff --git a/src/consensus.rs b/src/consensus.rs new file mode 100644 index 0000000..1789241 --- /dev/null +++ b/src/consensus.rs @@ -0,0 +1,232 @@ +use dashmap::DashMap; +use std::collections::HashSet; +use std::sync::Arc; +use std::time::{Duration, Instant}; +use tracing::{debug, info}; + +struct PendingConsensus { + archive_data: Vec, + voters: HashSet, + created_at: Instant, + concurrent_tasks: Option, +} + +pub enum ConsensusStatus { + Pending { + votes: usize, + required: usize, + total_validators: usize, + }, + Reached { + archive_data: Vec, + concurrent_tasks: Option, + votes: usize, + required: usize, + }, + AlreadyVoted { + votes: usize, + required: usize, + total_validators: usize, + }, +} + +pub struct ConsensusManager { + pending: DashMap, + max_pending: usize, +} + +impl ConsensusManager { + pub fn new(max_pending: usize) -> Arc { + Arc::new(Self { + pending: DashMap::new(), + max_pending, + }) + } + + pub fn record_vote( + &self, + archive_hash: &str, + hotkey: &str, + archive_data: Vec, + concurrent_tasks: Option, + required: usize, + total_validators: usize, + ) -> ConsensusStatus { + let mut entry = self + .pending + .entry(archive_hash.to_string()) + .or_insert_with(|| { + info!(archive_hash, "New consensus entry created"); + PendingConsensus { + archive_data, + voters: HashSet::new(), + created_at: Instant::now(), + concurrent_tasks, + } + }); + + if entry.voters.contains(hotkey) { + return ConsensusStatus::AlreadyVoted { + votes: entry.voters.len(), + required, + total_validators, + }; + } + + entry.voters.insert(hotkey.to_string()); + let votes = entry.voters.len(); + + if votes >= required { + drop(entry); + if let Some((_, consensus)) = self.pending.remove(archive_hash) { + info!(archive_hash, votes, required, "Consensus reached"); + return ConsensusStatus::Reached { + archive_data: consensus.archive_data, + concurrent_tasks: consensus.concurrent_tasks, + votes, + required, + }; + } + } + + ConsensusStatus::Pending { + votes, + required, + total_validators, + } + } + + #[cfg(test)] + fn pending_count(&self) -> usize { + self.pending.len() + } + + pub fn is_at_capacity(&self) -> bool { + self.pending.len() >= self.max_pending + } + + pub async fn reaper_loop(self: Arc, ttl_secs: u64) { + let mut interval = tokio::time::interval(Duration::from_secs(30)); + loop { + interval.tick().await; + let cutoff = Instant::now() - Duration::from_secs(ttl_secs); + let before = self.pending.len(); + self.pending.retain(|hash, entry| { + let keep = entry.created_at > cutoff; + if !keep { + debug!(archive_hash = %hash, "Expired pending consensus entry"); + } + keep + }); + let removed = before.saturating_sub(self.pending.len()); + if removed > 0 { + info!( + removed, + remaining = self.pending.len(), + "Reaped expired consensus entries" + ); + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_single_vote_does_not_trigger() { + let mgr = ConsensusManager::new(100); + let status = mgr.record_vote("abc123", "hotkey1", vec![1, 2, 3], Some(8), 2, 3); + assert!(matches!( + status, + ConsensusStatus::Pending { + votes: 1, + required: 2, + .. + } + )); + } + + #[test] + fn test_reaching_threshold_triggers() { + let mgr = ConsensusManager::new(100); + mgr.record_vote("abc123", "hotkey1", vec![1, 2, 3], Some(8), 2, 3); + let status = mgr.record_vote("abc123", "hotkey2", vec![1, 2, 3], Some(8), 2, 3); + assert!(matches!(status, ConsensusStatus::Reached { votes: 2, .. })); + } + + #[test] + fn test_duplicate_votes_no_double_count() { + let mgr = ConsensusManager::new(100); + mgr.record_vote("abc123", "hotkey1", vec![1, 2, 3], Some(8), 3, 5); + let status = mgr.record_vote("abc123", "hotkey1", vec![1, 2, 3], Some(8), 3, 5); + assert!(matches!( + status, + ConsensusStatus::AlreadyVoted { votes: 1, .. } + )); + } + + #[test] + fn test_different_hashes_independent() { + let mgr = ConsensusManager::new(100); + mgr.record_vote("hash1", "hotkey1", vec![1], Some(8), 2, 3); + mgr.record_vote("hash2", "hotkey1", vec![2], Some(8), 2, 3); + assert_eq!(mgr.pending_count(), 2); + } + + #[test] + fn test_ttl_expiration() { + let mgr = ConsensusManager::new(100); + mgr.pending.insert( + "old_hash".to_string(), + PendingConsensus { + archive_data: vec![1], + voters: HashSet::from(["hotkey1".to_string()]), + created_at: Instant::now() - Duration::from_secs(120), + concurrent_tasks: None, + }, + ); + mgr.pending.insert( + "new_hash".to_string(), + PendingConsensus { + archive_data: vec![2], + voters: HashSet::from(["hotkey2".to_string()]), + created_at: Instant::now(), + concurrent_tasks: None, + }, + ); + + let cutoff = Instant::now() - Duration::from_secs(60); + mgr.pending.retain(|_, entry| entry.created_at > cutoff); + + assert_eq!(mgr.pending_count(), 1); + assert!(mgr.pending.contains_key("new_hash")); + assert!(!mgr.pending.contains_key("old_hash")); + } + + #[test] + fn test_capacity_check() { + let mgr = ConsensusManager::new(2); + assert!(!mgr.is_at_capacity()); + mgr.pending.insert( + "h1".to_string(), + PendingConsensus { + archive_data: vec![], + voters: HashSet::new(), + created_at: Instant::now(), + concurrent_tasks: None, + }, + ); + mgr.pending.insert( + "h2".to_string(), + PendingConsensus { + archive_data: vec![], + voters: HashSet::new(), + created_at: Instant::now(), + concurrent_tasks: None, + }, + ); + assert!(mgr.is_at_capacity()); + } +} diff --git a/src/handlers.rs b/src/handlers.rs index bcf45a3..2bb9730 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -17,6 +17,10 @@ use crate::metrics::Metrics; use crate::session::SessionManager; use crate::ws; +use crate::consensus::{ConsensusManager, ConsensusStatus}; +use crate::validator_whitelist::ValidatorWhitelist; +use sha2::{Digest, Sha256}; + pub struct AppState { pub config: Arc, pub sessions: Arc, @@ -24,6 +28,8 @@ pub struct AppState { pub executor: Arc, pub nonce_store: Arc, pub started_at: chrono::DateTime, + pub validator_whitelist: Arc, + pub consensus_manager: Arc, } pub fn router(state: Arc) -> Router { @@ -103,15 +109,25 @@ async fn submit_batch( StatusCode::UNAUTHORIZED, Json(serde_json::json!({ "error": "missing_auth", - "message": "Missing required headers: X-Hotkey, X-Nonce, X-Signature, X-Api-Key" + "message": "Missing required headers: X-Hotkey, X-Nonce, X-Signature" })), ) })?; + if state.validator_whitelist.validator_count() == 0 { + return Err(( + StatusCode::SERVICE_UNAVAILABLE, + Json(serde_json::json!({ + "error": "whitelist_not_ready", + "message": "Validator whitelist not yet initialized. Please retry shortly." + })), + )); + } + if let Err(e) = auth::verify_request( &auth_headers, &state.nonce_store, - &state.config.worker_api_key, + &state.validator_whitelist, ) { return Err(( StatusCode::UNAUTHORIZED, @@ -122,16 +138,6 @@ async fn submit_batch( )); } - if state.sessions.has_active_batch() { - return Err(( - StatusCode::SERVICE_UNAVAILABLE, - Json(serde_json::json!({ - "error": "busy", - "message": "A batch is already running. Wait for it to complete." - })), - )); - } - let mut archive_data: Option> = None; while let Ok(Some(field)) = multipart.next_field().await { @@ -170,43 +176,129 @@ async fn submit_batch( )); } - let extract_dir = state.config.workspace_base.join("_extract_tmp"); - let _ = tokio::fs::remove_dir_all(&extract_dir).await; + if state.consensus_manager.is_at_capacity() { + return Err(( + StatusCode::SERVICE_UNAVAILABLE, + Json(serde_json::json!({ + "error": "too_many_pending", + "message": "Too many pending consensus entries. Please retry later." + })), + )); + } - let extracted = crate::task::extract_uploaded_archive(&archive_bytes, &extract_dir) - .await - .map_err(|e| { - ( - StatusCode::BAD_REQUEST, - Json(serde_json::json!({ - "error": "extraction_failed", - "message": format!("Failed to extract archive: {}", e) - })), - ) - })?; + let archive_hash = { + let mut hasher = Sha256::new(); + hasher.update(&archive_bytes); + hex::encode(hasher.finalize()) + }; - let _ = tokio::fs::remove_dir_all(&extract_dir).await; + let total_validators = state.validator_whitelist.validator_count(); + let required = + ((total_validators as f64 * state.config.consensus_threshold).ceil() as usize).max(1); - let total_tasks = extracted.tasks.len(); let concurrent = query .concurrent_tasks .unwrap_or(state.config.max_concurrent_tasks) .min(state.config.max_concurrent_tasks); - let batch = state.sessions.create_batch(total_tasks); - let batch_id = batch.id.clone(); - - state.executor.spawn_batch(batch, extracted, concurrent); - - Ok(( - StatusCode::ACCEPTED, - Json(serde_json::json!({ - "batch_id": batch_id, - "total_tasks": total_tasks, - "concurrent_tasks": concurrent, - "ws_url": format!("/ws?batch_id={}", batch_id), - })), - )) + let status = state.consensus_manager.record_vote( + &archive_hash, + &auth_headers.hotkey, + archive_bytes, + Some(concurrent), + required, + total_validators, + ); + + match status { + ConsensusStatus::Pending { + votes, + required, + total_validators, + } => Ok(( + StatusCode::ACCEPTED, + Json(serde_json::json!({ + "status": "pending_consensus", + "archive_hash": archive_hash, + "votes": votes, + "required": required, + "total_validators": total_validators, + })), + )), + ConsensusStatus::AlreadyVoted { + votes, + required, + total_validators, + } => Ok(( + StatusCode::ACCEPTED, + Json(serde_json::json!({ + "status": "pending_consensus", + "archive_hash": archive_hash, + "votes": votes, + "required": required, + "total_validators": total_validators, + "note": "Your vote was already recorded", + })), + )), + ConsensusStatus::Reached { + archive_data, + concurrent_tasks, + votes, + required, + } => { + let effective_concurrent = concurrent_tasks + .unwrap_or(state.config.max_concurrent_tasks) + .min(state.config.max_concurrent_tasks); + + if state.sessions.has_active_batch() { + return Err(( + StatusCode::SERVICE_UNAVAILABLE, + Json(serde_json::json!({ + "error": "busy", + "message": "A batch is already running. Wait for it to complete." + })), + )); + } + + let extract_dir = state.config.workspace_base.join("_extract_tmp"); + let _ = tokio::fs::remove_dir_all(&extract_dir).await; + + let extracted = crate::task::extract_uploaded_archive(&archive_data, &extract_dir) + .await + .map_err(|e| { + ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!({ + "error": "extraction_failed", + "message": format!("Failed to extract archive: {}", e) + })), + ) + })?; + + let _ = tokio::fs::remove_dir_all(&extract_dir).await; + + let total_tasks = extracted.tasks.len(); + let batch = state.sessions.create_batch(total_tasks); + let batch_id = batch.id.clone(); + + state + .executor + .spawn_batch(batch, extracted, effective_concurrent); + + Ok(( + StatusCode::ACCEPTED, + Json(serde_json::json!({ + "batch_id": batch_id, + "total_tasks": total_tasks, + "concurrent_tasks": effective_concurrent, + "ws_url": format!("/ws?batch_id={}", batch_id), + "consensus_reached": true, + "votes": votes, + "required": required, + })), + )) + } + } } async fn get_batch( diff --git a/src/main.rs b/src/main.rs index 749dcb3..9327dd2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,13 @@ mod auth; mod cleanup; mod config; +mod consensus; mod executor; mod handlers; mod metrics; mod session; mod task; +mod validator_whitelist; mod ws; use std::sync::Arc; @@ -36,6 +38,9 @@ async fn main() { metrics_store.clone(), )); + let validator_whitelist = validator_whitelist::ValidatorWhitelist::new(); + let consensus_manager = consensus::ConsensusManager::new(100); + let state = Arc::new(handlers::AppState { config: config.clone(), sessions: sessions.clone(), @@ -43,6 +48,8 @@ async fn main() { executor, nonce_store: nonce_store.clone(), started_at: chrono::Utc::now(), + validator_whitelist: validator_whitelist.clone(), + consensus_manager: consensus_manager.clone(), }); let app = handlers::router(state); @@ -68,6 +75,20 @@ async fn main() { } }); + let wl = validator_whitelist.clone(); + let netuid = config.bittensor_netuid; + let min_stake = config.min_validator_stake_tao; + let refresh_secs = config.validator_refresh_secs; + tokio::spawn(async move { + wl.refresh_loop(netuid, min_stake, refresh_secs).await; + }); + + let cm = consensus_manager.clone(); + let consensus_ttl = config.consensus_ttl_secs; + tokio::spawn(async move { + cm.reaper_loop(consensus_ttl).await; + }); + info!("Listening on {}", addr); let listener = tokio::net::TcpListener::bind(&addr).await.unwrap(); diff --git a/src/validator_whitelist.rs b/src/validator_whitelist.rs new file mode 100644 index 0000000..d1d27a3 --- /dev/null +++ b/src/validator_whitelist.rs @@ -0,0 +1,121 @@ +use parking_lot::RwLock; +use std::collections::HashSet; +use std::sync::Arc; +use std::time::Duration; +use tracing::{info, warn}; + +pub struct ValidatorWhitelist { + hotkeys: RwLock>, +} + +impl ValidatorWhitelist { + pub fn new() -> Arc { + Arc::new(Self { + hotkeys: RwLock::new(HashSet::new()), + }) + } + + pub fn is_whitelisted(&self, ss58_hotkey: &str) -> bool { + self.hotkeys.read().contains(ss58_hotkey) + } + + pub fn validator_count(&self) -> usize { + self.hotkeys.read().len() + } + + pub async fn refresh_loop(self: Arc, netuid: u16, min_stake_tao: f64, refresh_secs: u64) { + let mut interval = tokio::time::interval(Duration::from_secs(refresh_secs)); + loop { + interval.tick().await; + self.refresh_once(netuid, min_stake_tao).await; + } + } + + async fn refresh_once(&self, netuid: u16, min_stake_tao: f64) { + let mut last_err = None; + for attempt in 0..3u32 { + if attempt > 0 { + let delay = Duration::from_secs(2u64.pow(attempt)); + tokio::time::sleep(delay).await; + } + match self.try_refresh(netuid, min_stake_tao).await { + Ok(count) => { + info!(count, netuid, "Validator whitelist refreshed successfully"); + return; + } + Err(e) => { + warn!( + attempt = attempt + 1, + error = %e, + "Failed to refresh validator whitelist" + ); + last_err = Some(e); + } + } + } + warn!( + error = %last_err.unwrap_or_else(|| anyhow::anyhow!("unknown")), + "All retry attempts failed for validator whitelist refresh, keeping cached whitelist" + ); + } + + async fn try_refresh(&self, netuid: u16, min_stake_tao: f64) -> anyhow::Result { + use bittensor_rs::ss58::encode_ss58; + + let client = bittensor_rs::BittensorClient::with_failover() + .await + .map_err(|e| anyhow::anyhow!("Failed to connect to subtensor: {}", e))?; + + let metagraph = bittensor_rs::sync_metagraph(&client, netuid) + .await + .map_err(|e| anyhow::anyhow!("Failed to sync metagraph: {}", e))?; + + let mut new_hotkeys = HashSet::new(); + for neuron in metagraph.neurons.values() { + if neuron.validator_permit && neuron.active && neuron.stake.as_tao() >= min_stake_tao { + new_hotkeys.insert(encode_ss58(&neuron.hotkey)); + } + } + + let count = new_hotkeys.len(); + *self.hotkeys.write() = new_hotkeys; + Ok(count) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_starts_empty() { + let wl = ValidatorWhitelist::new(); + assert_eq!(wl.validator_count(), 0); + } + + #[test] + fn test_is_whitelisted() { + let wl = ValidatorWhitelist::new(); + let hotkey = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"; + assert!(!wl.is_whitelisted(hotkey)); + + wl.hotkeys.write().insert(hotkey.to_string()); + assert!(wl.is_whitelisted(hotkey)); + } + + #[test] + fn test_validator_count() { + let wl = ValidatorWhitelist::new(); + assert_eq!(wl.validator_count(), 0); + + wl.hotkeys + .write() + .insert("5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY".to_string()); + assert_eq!(wl.validator_count(), 1); + + wl.hotkeys + .write() + .insert("5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty".to_string()); + assert_eq!(wl.validator_count(), 2); + } +} From c3b06f2fe346a4f5d93a53413cfa9621298c52a1 Mon Sep 17 00:00:00 2001 From: echobt Date: Wed, 18 Feb 2026 16:01:31 +0000 Subject: [PATCH 02/12] ci: trigger CI run From e7ee7f3465743e5ac2866ad35c670979f18d5bad Mon Sep 17 00:00:00 2001 From: echobt Date: Wed, 18 Feb 2026 16:06:26 +0000 Subject: [PATCH 03/12] fix(security): address auth bypass, input validation, and config issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Move nonce consumption AFTER signature verification in verify_request() to prevent attackers from burning legitimate nonces via invalid signatures - Fix TOCTOU race in NonceStore::check_and_insert() using atomic DashMap entry API instead of separate contains_key + insert - Add input length limits for auth headers (hotkey 128B, nonce 256B, signature 256B) to prevent memory exhaustion via oversized values - Add consensus_threshold validation in Config::from_env() — must be in range (0.0, 1.0], panics at startup if invalid - Add saturating conversion for consensus required calculation to prevent integer overflow on f64→usize cast - Add tests for all security fixes --- src/auth.rs | 66 +++++++++++++++++++++++++++++++++----- src/config.rs | 27 +++++++++++++++- src/handlers.rs | 4 +-- src/validator_whitelist.rs | 5 +++ 4 files changed, 91 insertions(+), 11 deletions(-) diff --git a/src/auth.rs b/src/auth.rs index 540d552..6f7ca03 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -8,6 +8,10 @@ use tracing::warn; const NONCE_TTL: Duration = Duration::from_secs(300); const NONCE_REAP_INTERVAL: Duration = Duration::from_secs(60); +const MAX_HOTKEY_LEN: usize = 128; +const MAX_NONCE_LEN: usize = 256; +const MAX_SIGNATURE_LEN: usize = 256; + pub struct NonceStore { seen: DashMap, } @@ -20,11 +24,14 @@ impl NonceStore { } pub fn check_and_insert(&self, nonce: &str) -> bool { - if self.seen.contains_key(nonce) { - return false; + use dashmap::mapref::entry::Entry; + match self.seen.entry(nonce.to_string()) { + Entry::Occupied(_) => false, + Entry::Vacant(v) => { + v.insert(Instant::now()); + true + } } - self.seen.insert(nonce.to_string(), Instant::now()); - true } pub async fn reaper_loop(self: Arc) { @@ -48,18 +55,21 @@ pub fn extract_auth_headers(headers: &axum::http::HeaderMap) -> Option Self { + let consensus_threshold: f64 = + env_parse("CONSENSUS_THRESHOLD", DEFAULT_CONSENSUS_THRESHOLD); + + assert!( + consensus_threshold > 0.0 && consensus_threshold <= 1.0, + "CONSENSUS_THRESHOLD must be in range (0.0, 1.0], got {}", + consensus_threshold + ); + Self { port: env_parse("PORT", DEFAULT_PORT), session_ttl_secs: env_parse("SESSION_TTL_SECS", DEFAULT_SESSION_TTL), @@ -58,7 +67,7 @@ impl Config { "VALIDATOR_REFRESH_SECS", DEFAULT_VALIDATOR_REFRESH_SECS, ), - consensus_threshold: env_parse("CONSENSUS_THRESHOLD", DEFAULT_CONSENSUS_THRESHOLD), + consensus_threshold, consensus_ttl_secs: env_parse("CONSENSUS_TTL_SECS", DEFAULT_CONSENSUS_TTL_SECS), } } @@ -119,4 +128,20 @@ mod tests { fn test_env_parse_fallback() { assert_eq!(env_parse::("NONEXISTENT_VAR_XYZ", 42), 42); } + + #[test] + #[should_panic(expected = "CONSENSUS_THRESHOLD must be in range")] + fn test_config_rejects_zero_threshold() { + std::env::set_var("CONSENSUS_THRESHOLD", "0.0"); + let _cfg = Config::from_env(); + std::env::remove_var("CONSENSUS_THRESHOLD"); + } + + #[test] + #[should_panic(expected = "CONSENSUS_THRESHOLD must be in range")] + fn test_config_rejects_threshold_above_one() { + std::env::set_var("CONSENSUS_THRESHOLD", "1.5"); + let _cfg = Config::from_env(); + std::env::remove_var("CONSENSUS_THRESHOLD"); + } } diff --git a/src/handlers.rs b/src/handlers.rs index 2bb9730..eed5a99 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -193,8 +193,8 @@ async fn submit_batch( }; let total_validators = state.validator_whitelist.validator_count(); - let required = - ((total_validators as f64 * state.config.consensus_threshold).ceil() as usize).max(1); + let required_f = (total_validators as f64 * state.config.consensus_threshold).ceil(); + let required = (required_f.min(usize::MAX as f64) as usize).max(1); let concurrent = query .concurrent_tasks diff --git a/src/validator_whitelist.rs b/src/validator_whitelist.rs index d1d27a3..06a33c2 100644 --- a/src/validator_whitelist.rs +++ b/src/validator_whitelist.rs @@ -23,6 +23,11 @@ impl ValidatorWhitelist { self.hotkeys.read().len() } + #[cfg(test)] + pub fn insert_for_test(&self, hotkey: &str) { + self.hotkeys.write().insert(hotkey.to_string()); + } + pub async fn refresh_loop(self: Arc, netuid: u16, min_stake_tao: f64, refresh_secs: u64) { let mut interval = tokio::time::interval(Duration::from_secs(refresh_secs)); loop { From 0d7618810ecc5fd2545adc54354e4f6871939e59 Mon Sep 17 00:00:00 2001 From: echobt Date: Wed, 18 Feb 2026 16:09:11 +0000 Subject: [PATCH 04/12] fix(dead-code): remove orphaned default_concurrent fn and unnecessary allow(dead_code) --- src/config.rs | 1 - src/handlers.rs | 6 +----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/config.rs b/src/config.rs index 99b06ac..12593cf 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,7 +7,6 @@ const DEFAULT_CLONE_TIMEOUT: u64 = 180; const DEFAULT_AGENT_TIMEOUT: u64 = 600; const DEFAULT_TEST_TIMEOUT: u64 = 300; const DEFAULT_MAX_ARCHIVE_BYTES: usize = 500 * 1024 * 1024; -#[allow(dead_code)] const DEFAULT_MAX_OUTPUT_BYTES: usize = 1024 * 1024; const DEFAULT_WORKSPACE_BASE: &str = "/tmp/sessions"; const DEFAULT_BITTENSOR_NETUID: u16 = 100; diff --git a/src/handlers.rs b/src/handlers.rs index eed5a99..cd7b520 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -90,14 +90,10 @@ async fn metrics(State(state): State>) -> Response { #[derive(serde::Deserialize)] struct SubmitQuery { - #[serde(default = "default_concurrent")] + #[serde(default)] concurrent_tasks: Option, } -fn default_concurrent() -> Option { - None -} - async fn submit_batch( State(state): State>, headers: axum::http::HeaderMap, From ca88d5a4c67eb39265f8dddaaeb076d9defbcd0b Mon Sep 17 00:00:00 2001 From: echobt Date: Wed, 18 Feb 2026 16:14:13 +0000 Subject: [PATCH 05/12] fix: code quality issues in bittensor validator consensus - Extract magic number 100 to configurable MAX_PENDING_CONSENSUS - Restore #[allow(dead_code)] on DEFAULT_MAX_OUTPUT_BYTES constant - Use anyhow::Context instead of map_err(anyhow::anyhow!) in validator_whitelist --- src/config.rs | 7 +++++++ src/main.rs | 2 +- src/validator_whitelist.rs | 5 +++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/config.rs b/src/config.rs index 12593cf..db52d30 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,8 +7,10 @@ const DEFAULT_CLONE_TIMEOUT: u64 = 180; const DEFAULT_AGENT_TIMEOUT: u64 = 600; const DEFAULT_TEST_TIMEOUT: u64 = 300; const DEFAULT_MAX_ARCHIVE_BYTES: usize = 500 * 1024 * 1024; +#[allow(dead_code)] const DEFAULT_MAX_OUTPUT_BYTES: usize = 1024 * 1024; const DEFAULT_WORKSPACE_BASE: &str = "/tmp/sessions"; +const DEFAULT_MAX_PENDING_CONSENSUS: usize = 100; const DEFAULT_BITTENSOR_NETUID: u16 = 100; const DEFAULT_MIN_VALIDATOR_STAKE_TAO: f64 = 10_000.0; const DEFAULT_VALIDATOR_REFRESH_SECS: u64 = 300; @@ -32,6 +34,7 @@ pub struct Config { pub validator_refresh_secs: u64, pub consensus_threshold: f64, pub consensus_ttl_secs: u64, + pub max_pending_consensus: usize, } impl Config { @@ -68,6 +71,10 @@ impl Config { ), consensus_threshold, consensus_ttl_secs: env_parse("CONSENSUS_TTL_SECS", DEFAULT_CONSENSUS_TTL_SECS), + max_pending_consensus: env_parse( + "MAX_PENDING_CONSENSUS", + DEFAULT_MAX_PENDING_CONSENSUS, + ), } } diff --git a/src/main.rs b/src/main.rs index 9327dd2..9a5ef90 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,7 +39,7 @@ async fn main() { )); let validator_whitelist = validator_whitelist::ValidatorWhitelist::new(); - let consensus_manager = consensus::ConsensusManager::new(100); + let consensus_manager = consensus::ConsensusManager::new(config.max_pending_consensus); let state = Arc::new(handlers::AppState { config: config.clone(), diff --git a/src/validator_whitelist.rs b/src/validator_whitelist.rs index 06a33c2..8bb0cca 100644 --- a/src/validator_whitelist.rs +++ b/src/validator_whitelist.rs @@ -1,3 +1,4 @@ +use anyhow::Context; use parking_lot::RwLock; use std::collections::HashSet; use std::sync::Arc; @@ -69,11 +70,11 @@ impl ValidatorWhitelist { let client = bittensor_rs::BittensorClient::with_failover() .await - .map_err(|e| anyhow::anyhow!("Failed to connect to subtensor: {}", e))?; + .context("Failed to connect to subtensor")?; let metagraph = bittensor_rs::sync_metagraph(&client, netuid) .await - .map_err(|e| anyhow::anyhow!("Failed to sync metagraph: {}", e))?; + .context("Failed to sync metagraph")?; let mut new_hotkeys = HashSet::new(); for neuron in metagraph.neurons.values() { From d35561d7ea6a70236eb6ad101c766c72d0f048c0 Mon Sep 17 00:00:00 2001 From: echobt Date: Wed, 18 Feb 2026 16:28:02 +0000 Subject: [PATCH 06/12] fix(security): address race condition, config panic, SS58 checksum, and container security - consensus.rs: Fix TOCTOU race condition in record_vote by using DashMap entry API (remove_entry) to atomically check votes and remove entry while holding the shard lock, preventing concurrent threads from inserting votes between drop and remove - config.rs: Replace assert! with proper Result return from Config::from_env() to avoid panicking in production on invalid CONSENSUS_THRESHOLD values - main.rs: Update Config::from_env() call to handle Result with expect - auth.rs: Add SS58 checksum verification using Blake2b-512 (correct Substrate algorithm) in ss58_to_public_key_bytes to reject addresses with corrupted checksums; previously only decoded base58 without validating the 2-byte checksum suffix - Dockerfile: Add non-root executor user for container runtime security --- Cargo.lock | 1 + Cargo.toml | 1 + Dockerfile | 4 +- src/auth.rs | 59 ++++++++++++++++---------- src/config.rs | 33 +++++++++------ src/consensus.rs | 108 +++++++++++++++++++++++++++++++---------------- src/main.rs | 2 +- 7 files changed, 134 insertions(+), 74 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 787c7a2..d121c07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5642,6 +5642,7 @@ dependencies = [ "axum", "base64", "bittensor-rs", + "blake2", "bs58", "chrono", "dashmap", diff --git a/Cargo.toml b/Cargo.toml index 247a434..931dc2a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,6 +64,7 @@ rand_core = { version = "0.6", features = ["getrandom"] } # Bittensor substrate client bittensor-rs = { git = "https://github.com/cortexlm/bittensor-rs", branch = "main" } +blake2 = "0.10" [dev-dependencies] tokio-test = "0.4" diff --git a/Dockerfile b/Dockerfile index 6c88404..dfd9f1d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,7 +16,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ && rm -rf /var/lib/apt/lists/* COPY --from=builder /build/target/release/term-executor /usr/local/bin/ -RUN mkdir -p /tmp/sessions +RUN groupadd --system executor && useradd --system --gid executor --create-home executor \ + && mkdir -p /tmp/sessions && chown executor:executor /tmp/sessions +USER executor EXPOSE 8080 HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ CMD curl -f http://localhost:8080/health || exit 1 diff --git a/src/auth.rs b/src/auth.rs index 6f7ca03..7afb764 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -171,22 +171,38 @@ fn verify_sr25519_signature(ss58_hotkey: &str, message: &str, signature_hex: &st .is_ok() } +fn ss58_checksum(data: &[u8]) -> [u8; 2] { + use blake2::{digest::consts::U64, Blake2b, Digest}; + let mut hasher = Blake2b::::new(); + hasher.update(b"SS58PRE"); + hasher.update(data); + let result = hasher.finalize(); + [result[0], result[1]] +} + fn ss58_to_public_key_bytes(address: &str) -> Option<[u8; 32]> { let decoded = bs58::decode(address).into_vec().ok()?; // SS58 format: [prefix(1-2 bytes)][public_key(32 bytes)][checksum(2 bytes)] // For substrate generic (prefix 42), total = 35 bytes (1 + 32 + 2) - if decoded.len() == 35 { - let mut key = [0u8; 32]; - key.copy_from_slice(&decoded[1..33]); - Some(key) + let (prefix_len, key_start) = if decoded.len() == 35 { + (1, 1) } else if decoded.len() == 36 { - // Two-byte prefix - let mut key = [0u8; 32]; - key.copy_from_slice(&decoded[2..34]); - Some(key) + (2, 2) } else { - None + return None; + }; + + let payload = &decoded[..prefix_len + 32]; + let expected_checksum = &decoded[prefix_len + 32..]; + let actual_checksum = ss58_checksum(payload); + + if expected_checksum != actual_checksum { + return None; } + + let mut key = [0u8; 32]; + key.copy_from_slice(&decoded[key_start..key_start + 32]); + Some(key) } pub fn validate_ss58(address: &str) -> bool { @@ -196,18 +212,6 @@ pub fn validate_ss58(address: &str) -> bool { ss58_to_public_key_bytes(address).is_some() } -#[cfg(test)] -fn sp_ss58_checksum(data: &[u8]) -> [u8; 64] { - use sha2::{Digest, Sha512}; - let mut hasher = Sha512::new(); - hasher.update(b"SS58PRE"); - hasher.update(data); - let result = hasher.finalize(); - let mut out = [0u8; 64]; - out.copy_from_slice(&result); - out -} - #[cfg(test)] mod tests { use super::*; @@ -325,8 +329,8 @@ mod tests { let mut raw = Vec::with_capacity(35); raw.push(42u8); raw.extend_from_slice(&pub_key.to_bytes()); - let hash = sp_ss58_checksum(&raw); - raw.extend_from_slice(&hash[..2]); + let checksum = ss58_checksum(&raw); + raw.extend_from_slice(&checksum); let ss58 = bs58::encode(&raw).into_string(); let nonce = "test-nonce-42"; @@ -339,4 +343,13 @@ mod tests { assert!(verify_sr25519_signature(&ss58, &message, &sig_hex)); assert!(!verify_sr25519_signature(&ss58, "wrong-message", &sig_hex)); } + + #[test] + fn test_ss58_rejects_bad_checksum() { + let mut decoded = bs58::decode(TEST_SS58).into_vec().unwrap(); + let last = decoded.len() - 1; + decoded[last] ^= 0xFF; + let bad_ss58 = bs58::encode(&decoded).into_string(); + assert!(ss58_to_public_key_bytes(&bad_ss58).is_none()); + } } diff --git a/src/config.rs b/src/config.rs index db52d30..8cc9cd6 100644 --- a/src/config.rs +++ b/src/config.rs @@ -38,17 +38,18 @@ pub struct Config { } impl Config { - pub fn from_env() -> Self { + pub fn from_env() -> Result { let consensus_threshold: f64 = env_parse("CONSENSUS_THRESHOLD", DEFAULT_CONSENSUS_THRESHOLD); - assert!( - consensus_threshold > 0.0 && consensus_threshold <= 1.0, - "CONSENSUS_THRESHOLD must be in range (0.0, 1.0], got {}", - consensus_threshold - ); + if consensus_threshold <= 0.0 || consensus_threshold > 1.0 { + return Err(format!( + "CONSENSUS_THRESHOLD must be in range (0.0, 1.0], got {}", + consensus_threshold + )); + } - Self { + Ok(Self { port: env_parse("PORT", DEFAULT_PORT), session_ttl_secs: env_parse("SESSION_TTL_SECS", DEFAULT_SESSION_TTL), max_concurrent_tasks: env_parse("MAX_CONCURRENT_TASKS", DEFAULT_MAX_CONCURRENT), @@ -75,7 +76,7 @@ impl Config { "MAX_PENDING_CONSENSUS", DEFAULT_MAX_PENDING_CONSENSUS, ), - } + }) } pub fn print_banner(&self) { @@ -123,7 +124,7 @@ mod tests { #[test] fn test_config_defaults() { - let cfg = Config::from_env(); + let cfg = Config::from_env().expect("default config should be valid"); assert_eq!(cfg.port, DEFAULT_PORT); assert_eq!(cfg.max_concurrent_tasks, DEFAULT_MAX_CONCURRENT); assert_eq!(cfg.bittensor_netuid, 100); @@ -136,18 +137,24 @@ mod tests { } #[test] - #[should_panic(expected = "CONSENSUS_THRESHOLD must be in range")] fn test_config_rejects_zero_threshold() { std::env::set_var("CONSENSUS_THRESHOLD", "0.0"); - let _cfg = Config::from_env(); + let result = Config::from_env(); std::env::remove_var("CONSENSUS_THRESHOLD"); + assert!(result.is_err()); + assert!(result + .unwrap_err() + .contains("CONSENSUS_THRESHOLD must be in range")); } #[test] - #[should_panic(expected = "CONSENSUS_THRESHOLD must be in range")] fn test_config_rejects_threshold_above_one() { std::env::set_var("CONSENSUS_THRESHOLD", "1.5"); - let _cfg = Config::from_env(); + let result = Config::from_env(); std::env::remove_var("CONSENSUS_THRESHOLD"); + assert!(result.is_err()); + assert!(result + .unwrap_err() + .contains("CONSENSUS_THRESHOLD must be in range")); } } diff --git a/src/consensus.rs b/src/consensus.rs index 1789241..53d2e48 100644 --- a/src/consensus.rs +++ b/src/consensus.rs @@ -1,3 +1,4 @@ +use dashmap::mapref::entry::Entry; use dashmap::DashMap; use std::collections::HashSet; use std::sync::Arc; @@ -52,47 +53,66 @@ impl ConsensusManager { required: usize, total_validators: usize, ) -> ConsensusStatus { - let mut entry = self - .pending - .entry(archive_hash.to_string()) - .or_insert_with(|| { - info!(archive_hash, "New consensus entry created"); - PendingConsensus { - archive_data, - voters: HashSet::new(), - created_at: Instant::now(), - concurrent_tasks, + match self.pending.entry(archive_hash.to_string()) { + Entry::Occupied(mut entry) => { + let pending = entry.get_mut(); + + if pending.voters.contains(hotkey) { + return ConsensusStatus::AlreadyVoted { + votes: pending.voters.len(), + required, + total_validators, + }; } - }); - if entry.voters.contains(hotkey) { - return ConsensusStatus::AlreadyVoted { - votes: entry.voters.len(), - required, - total_validators, - }; - } + pending.voters.insert(hotkey.to_string()); + let votes = pending.voters.len(); - entry.voters.insert(hotkey.to_string()); - let votes = entry.voters.len(); - - if votes >= required { - drop(entry); - if let Some((_, consensus)) = self.pending.remove(archive_hash) { - info!(archive_hash, votes, required, "Consensus reached"); - return ConsensusStatus::Reached { - archive_data: consensus.archive_data, - concurrent_tasks: consensus.concurrent_tasks, - votes, - required, - }; + if votes >= required { + let (_, consensus) = entry.remove_entry(); + info!(archive_hash, votes, required, "Consensus reached"); + ConsensusStatus::Reached { + archive_data: consensus.archive_data, + concurrent_tasks: consensus.concurrent_tasks, + votes, + required, + } + } else { + ConsensusStatus::Pending { + votes, + required, + total_validators, + } + } } - } + Entry::Vacant(entry) => { + info!(archive_hash, "New consensus entry created"); + let mut voters = HashSet::new(); + voters.insert(hotkey.to_string()); + let votes = 1; - ConsensusStatus::Pending { - votes, - required, - total_validators, + if votes >= required { + info!(archive_hash, votes, required, "Consensus reached"); + ConsensusStatus::Reached { + archive_data, + concurrent_tasks, + votes, + required, + } + } else { + entry.insert(PendingConsensus { + archive_data, + voters, + created_at: Instant::now(), + concurrent_tasks, + }); + ConsensusStatus::Pending { + votes, + required, + total_validators, + } + } + } } } @@ -229,4 +249,20 @@ mod tests { ); assert!(mgr.is_at_capacity()); } + + #[test] + fn test_single_validator_consensus() { + let mgr = ConsensusManager::new(100); + let status = mgr.record_vote("hash1", "hotkey1", vec![1, 2, 3], Some(4), 1, 1); + assert!(matches!(status, ConsensusStatus::Reached { votes: 1, .. })); + assert_eq!(mgr.pending_count(), 0); + } + + #[test] + fn test_entry_removed_after_consensus() { + let mgr = ConsensusManager::new(100); + mgr.record_vote("hash1", "hotkey1", vec![1], Some(8), 2, 3); + mgr.record_vote("hash1", "hotkey2", vec![1], Some(8), 2, 3); + assert_eq!(mgr.pending_count(), 0); + } } diff --git a/src/main.rs b/src/main.rs index 9a5ef90..5db0a76 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,7 +22,7 @@ async fn main() { ) .init(); - let config = Arc::new(config::Config::from_env()); + let config = Arc::new(config::Config::from_env().expect("Invalid configuration")); config.print_banner(); tokio::fs::create_dir_all(&config.workspace_base) From bf41244712af326e57d5140288fe80bfd285ab48 Mon Sep 17 00:00:00 2001 From: echobt Date: Wed, 18 Feb 2026 16:32:07 +0000 Subject: [PATCH 07/12] fix(dead-code): remove unused max_output_bytes config field and constant Remove DEFAULT_MAX_OUTPUT_BYTES constant and max_output_bytes Config field that were defined and populated from env but never read anywhere outside config.rs. Both had #[allow(dead_code)] annotations suppressing warnings. --- src/config.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/config.rs b/src/config.rs index 8cc9cd6..52390a4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,8 +7,6 @@ const DEFAULT_CLONE_TIMEOUT: u64 = 180; const DEFAULT_AGENT_TIMEOUT: u64 = 600; const DEFAULT_TEST_TIMEOUT: u64 = 300; const DEFAULT_MAX_ARCHIVE_BYTES: usize = 500 * 1024 * 1024; -#[allow(dead_code)] -const DEFAULT_MAX_OUTPUT_BYTES: usize = 1024 * 1024; const DEFAULT_WORKSPACE_BASE: &str = "/tmp/sessions"; const DEFAULT_MAX_PENDING_CONSENSUS: usize = 100; const DEFAULT_BITTENSOR_NETUID: u16 = 100; @@ -26,8 +24,6 @@ pub struct Config { pub agent_timeout_secs: u64, pub test_timeout_secs: u64, pub max_archive_bytes: usize, - #[allow(dead_code)] - pub max_output_bytes: usize, pub workspace_base: PathBuf, pub bittensor_netuid: u16, pub min_validator_stake_tao: f64, @@ -57,7 +53,6 @@ impl Config { agent_timeout_secs: env_parse("AGENT_TIMEOUT_SECS", DEFAULT_AGENT_TIMEOUT), test_timeout_secs: env_parse("TEST_TIMEOUT_SECS", DEFAULT_TEST_TIMEOUT), max_archive_bytes: env_parse("MAX_ARCHIVE_BYTES", DEFAULT_MAX_ARCHIVE_BYTES), - max_output_bytes: env_parse("MAX_OUTPUT_BYTES", DEFAULT_MAX_OUTPUT_BYTES), workspace_base: PathBuf::from( std::env::var("WORKSPACE_BASE").unwrap_or_else(|_| DEFAULT_WORKSPACE_BASE.into()), ), From 8fff6e2a92148d64406b19d428959c4a487449a7 Mon Sep 17 00:00:00 2001 From: echobt Date: Wed, 18 Feb 2026 16:40:08 +0000 Subject: [PATCH 08/12] fix(quality): replace expect/unwrap with proper error handling, extract magic numbers to constants - main.rs: Replace .expect() on Config::from_env() with match + tracing::error! + process::exit(1) - validator_whitelist.rs: Extract retry count (3) and backoff base (2) to named constants - validator_whitelist.rs: Replace unwrap_or_else on Option with if-let pattern - consensus.rs: Extract reaper interval (30s) to REAPER_INTERVAL_SECS constant --- src/consensus.rs | 4 +++- src/main.rs | 10 ++++++++-- src/validator_whitelist.rs | 17 +++++++++++------ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/consensus.rs b/src/consensus.rs index 53d2e48..2f7527a 100644 --- a/src/consensus.rs +++ b/src/consensus.rs @@ -5,6 +5,8 @@ use std::sync::Arc; use std::time::{Duration, Instant}; use tracing::{debug, info}; +const REAPER_INTERVAL_SECS: u64 = 30; + struct PendingConsensus { archive_data: Vec, voters: HashSet, @@ -126,7 +128,7 @@ impl ConsensusManager { } pub async fn reaper_loop(self: Arc, ttl_secs: u64) { - let mut interval = tokio::time::interval(Duration::from_secs(30)); + let mut interval = tokio::time::interval(Duration::from_secs(REAPER_INTERVAL_SECS)); loop { interval.tick().await; let cutoff = Instant::now() - Duration::from_secs(ttl_secs); diff --git a/src/main.rs b/src/main.rs index 5db0a76..585c6b5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,7 @@ mod validator_whitelist; mod ws; use std::sync::Arc; -use tracing::info; +use tracing::{error, info}; #[tokio::main] async fn main() { @@ -22,7 +22,13 @@ async fn main() { ) .init(); - let config = Arc::new(config::Config::from_env().expect("Invalid configuration")); + let config = match config::Config::from_env() { + Ok(c) => Arc::new(c), + Err(e) => { + error!("Invalid configuration: {}", e); + std::process::exit(1); + } + }; config.print_banner(); tokio::fs::create_dir_all(&config.workspace_base) diff --git a/src/validator_whitelist.rs b/src/validator_whitelist.rs index 8bb0cca..bc29783 100644 --- a/src/validator_whitelist.rs +++ b/src/validator_whitelist.rs @@ -5,6 +5,9 @@ use std::sync::Arc; use std::time::Duration; use tracing::{info, warn}; +const MAX_REFRESH_RETRIES: u32 = 3; +const BACKOFF_BASE_SECS: u64 = 2; + pub struct ValidatorWhitelist { hotkeys: RwLock>, } @@ -39,9 +42,9 @@ impl ValidatorWhitelist { async fn refresh_once(&self, netuid: u16, min_stake_tao: f64) { let mut last_err = None; - for attempt in 0..3u32 { + for attempt in 0..MAX_REFRESH_RETRIES { if attempt > 0 { - let delay = Duration::from_secs(2u64.pow(attempt)); + let delay = Duration::from_secs(BACKOFF_BASE_SECS.pow(attempt)); tokio::time::sleep(delay).await; } match self.try_refresh(netuid, min_stake_tao).await { @@ -59,10 +62,12 @@ impl ValidatorWhitelist { } } } - warn!( - error = %last_err.unwrap_or_else(|| anyhow::anyhow!("unknown")), - "All retry attempts failed for validator whitelist refresh, keeping cached whitelist" - ); + if let Some(err) = last_err { + warn!( + error = %err, + "All retry attempts failed for validator whitelist refresh, keeping cached whitelist" + ); + } } async fn try_refresh(&self, netuid: u16, min_stake_tao: f64) -> anyhow::Result { From a48922868042d0482b61e33294484c2df8dc5743 Mon Sep 17 00:00:00 2001 From: echobt Date: Wed, 18 Feb 2026 16:59:15 +0000 Subject: [PATCH 09/12] fix(security): address multiple security vulnerabilities in PR files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - consensus.rs: Remove archive_data storage from PendingConsensus to prevent memory exhaustion (up to 50GB with 100 pending × 500MB each). Callers now use their own archive bytes since all votes for the same hash have identical data. - handlers.rs: Stream multipart upload with per-chunk size enforcement instead of buffering entire archive before checking size limit. Sanitize error messages to not leak internal details (file paths, extraction errors) to clients; log details server-side instead. - auth.rs: Add nonce format validation requiring non-empty printable ASCII characters (defense-in-depth against log injection and empty nonce edge cases). - main.rs: Replace .unwrap() on TcpListener::bind and axum::serve with proper error logging and process::exit per AGENTS.md rules. - ws.rs: Replace .unwrap() on serde_json::to_string with unwrap_or_default() to comply with AGENTS.md no-unwrap rule. --- src/auth.rs | 28 +++++++++++++++++++++++++++- src/consensus.rs | 34 ++++++++++++---------------------- src/handlers.rs | 45 +++++++++++++++++++++++++++------------------ src/main.rs | 15 ++++++++++++--- src/ws.rs | 17 ++++++----------- 5 files changed, 84 insertions(+), 55 deletions(-) diff --git a/src/auth.rs b/src/auth.rs index 7afb764..fd5db84 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -9,9 +9,16 @@ const NONCE_TTL: Duration = Duration::from_secs(300); const NONCE_REAP_INTERVAL: Duration = Duration::from_secs(60); const MAX_HOTKEY_LEN: usize = 128; +const MIN_NONCE_LEN: usize = 1; const MAX_NONCE_LEN: usize = 256; const MAX_SIGNATURE_LEN: usize = 256; +fn is_valid_nonce(s: &str) -> bool { + s.len() >= MIN_NONCE_LEN + && s.len() <= MAX_NONCE_LEN + && s.bytes().all(|b| b.is_ascii_graphic() || b == b' ') +} + pub struct NonceStore { seen: DashMap, } @@ -62,7 +69,7 @@ pub fn extract_auth_headers(headers: &axum::http::HeaderMap) -> Option, voters: HashSet, created_at: Instant, concurrent_tasks: Option, @@ -21,7 +20,6 @@ pub enum ConsensusStatus { total_validators: usize, }, Reached { - archive_data: Vec, concurrent_tasks: Option, votes: usize, required: usize, @@ -50,7 +48,6 @@ impl ConsensusManager { &self, archive_hash: &str, hotkey: &str, - archive_data: Vec, concurrent_tasks: Option, required: usize, total_validators: usize, @@ -71,11 +68,10 @@ impl ConsensusManager { let votes = pending.voters.len(); if votes >= required { - let (_, consensus) = entry.remove_entry(); + let (_, _consensus) = entry.remove_entry(); info!(archive_hash, votes, required, "Consensus reached"); ConsensusStatus::Reached { - archive_data: consensus.archive_data, - concurrent_tasks: consensus.concurrent_tasks, + concurrent_tasks: _consensus.concurrent_tasks, votes, required, } @@ -96,14 +92,12 @@ impl ConsensusManager { if votes >= required { info!(archive_hash, votes, required, "Consensus reached"); ConsensusStatus::Reached { - archive_data, concurrent_tasks, votes, required, } } else { entry.insert(PendingConsensus { - archive_data, voters, created_at: Instant::now(), concurrent_tasks, @@ -159,7 +153,7 @@ mod tests { #[test] fn test_single_vote_does_not_trigger() { let mgr = ConsensusManager::new(100); - let status = mgr.record_vote("abc123", "hotkey1", vec![1, 2, 3], Some(8), 2, 3); + let status = mgr.record_vote("abc123", "hotkey1", Some(8), 2, 3); assert!(matches!( status, ConsensusStatus::Pending { @@ -173,16 +167,16 @@ mod tests { #[test] fn test_reaching_threshold_triggers() { let mgr = ConsensusManager::new(100); - mgr.record_vote("abc123", "hotkey1", vec![1, 2, 3], Some(8), 2, 3); - let status = mgr.record_vote("abc123", "hotkey2", vec![1, 2, 3], Some(8), 2, 3); + mgr.record_vote("abc123", "hotkey1", Some(8), 2, 3); + let status = mgr.record_vote("abc123", "hotkey2", Some(8), 2, 3); assert!(matches!(status, ConsensusStatus::Reached { votes: 2, .. })); } #[test] fn test_duplicate_votes_no_double_count() { let mgr = ConsensusManager::new(100); - mgr.record_vote("abc123", "hotkey1", vec![1, 2, 3], Some(8), 3, 5); - let status = mgr.record_vote("abc123", "hotkey1", vec![1, 2, 3], Some(8), 3, 5); + mgr.record_vote("abc123", "hotkey1", Some(8), 3, 5); + let status = mgr.record_vote("abc123", "hotkey1", Some(8), 3, 5); assert!(matches!( status, ConsensusStatus::AlreadyVoted { votes: 1, .. } @@ -192,8 +186,8 @@ mod tests { #[test] fn test_different_hashes_independent() { let mgr = ConsensusManager::new(100); - mgr.record_vote("hash1", "hotkey1", vec![1], Some(8), 2, 3); - mgr.record_vote("hash2", "hotkey1", vec![2], Some(8), 2, 3); + mgr.record_vote("hash1", "hotkey1", Some(8), 2, 3); + mgr.record_vote("hash2", "hotkey1", Some(8), 2, 3); assert_eq!(mgr.pending_count(), 2); } @@ -203,7 +197,6 @@ mod tests { mgr.pending.insert( "old_hash".to_string(), PendingConsensus { - archive_data: vec![1], voters: HashSet::from(["hotkey1".to_string()]), created_at: Instant::now() - Duration::from_secs(120), concurrent_tasks: None, @@ -212,7 +205,6 @@ mod tests { mgr.pending.insert( "new_hash".to_string(), PendingConsensus { - archive_data: vec![2], voters: HashSet::from(["hotkey2".to_string()]), created_at: Instant::now(), concurrent_tasks: None, @@ -234,7 +226,6 @@ mod tests { mgr.pending.insert( "h1".to_string(), PendingConsensus { - archive_data: vec![], voters: HashSet::new(), created_at: Instant::now(), concurrent_tasks: None, @@ -243,7 +234,6 @@ mod tests { mgr.pending.insert( "h2".to_string(), PendingConsensus { - archive_data: vec![], voters: HashSet::new(), created_at: Instant::now(), concurrent_tasks: None, @@ -255,7 +245,7 @@ mod tests { #[test] fn test_single_validator_consensus() { let mgr = ConsensusManager::new(100); - let status = mgr.record_vote("hash1", "hotkey1", vec![1, 2, 3], Some(4), 1, 1); + let status = mgr.record_vote("hash1", "hotkey1", Some(4), 1, 1); assert!(matches!(status, ConsensusStatus::Reached { votes: 1, .. })); assert_eq!(mgr.pending_count(), 0); } @@ -263,8 +253,8 @@ mod tests { #[test] fn test_entry_removed_after_consensus() { let mgr = ConsensusManager::new(100); - mgr.record_vote("hash1", "hotkey1", vec![1], Some(8), 2, 3); - mgr.record_vote("hash1", "hotkey2", vec![1], Some(8), 2, 3); + mgr.record_vote("hash1", "hotkey1", Some(8), 2, 3); + mgr.record_vote("hash1", "hotkey2", Some(8), 2, 3); assert_eq!(mgr.pending_count(), 0); } } diff --git a/src/handlers.rs b/src/handlers.rs index cd7b520..83b4af0 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -9,6 +9,7 @@ use chrono::Utc; use serde::Serialize; use std::sync::atomic::Ordering; use std::sync::Arc; +use tracing::warn; use crate::auth::{self, NonceStore}; use crate::config::Config; @@ -134,21 +135,40 @@ async fn submit_batch( )); } + let max_bytes = state.config.max_archive_bytes; let mut archive_data: Option> = None; while let Ok(Some(field)) = multipart.next_field().await { let name = field.name().unwrap_or("").to_string(); if name == "archive" || name == "file" { - let data = field.bytes().await.map_err(|e| { + let mut buf = Vec::new(); + let mut stream = field; + use futures::TryStreamExt; + while let Some(chunk) = stream.try_next().await.map_err(|e| { + warn!(error = %e, "Failed to read multipart chunk"); ( StatusCode::BAD_REQUEST, Json(serde_json::json!({ "error": "upload_failed", - "message": format!("Failed to read upload: {}", e) + "message": "Failed to read uploaded archive" })), ) - })?; - archive_data = Some(data.to_vec()); + })? { + if buf.len() + chunk.len() > max_bytes { + return Err(( + StatusCode::BAD_REQUEST, + Json(serde_json::json!({ + "error": "archive_too_large", + "message": format!( + "Archive exceeds maximum size of {} bytes", + max_bytes + ) + })), + )); + } + buf.extend_from_slice(&chunk); + } + archive_data = Some(buf); } } @@ -162,16 +182,6 @@ async fn submit_batch( ) })?; - if archive_bytes.len() > state.config.max_archive_bytes { - return Err(( - StatusCode::BAD_REQUEST, - Json(serde_json::json!({ - "error": "archive_too_large", - "message": format!("Archive is {} bytes, max is {}", archive_bytes.len(), state.config.max_archive_bytes) - })), - )); - } - if state.consensus_manager.is_at_capacity() { return Err(( StatusCode::SERVICE_UNAVAILABLE, @@ -200,7 +210,6 @@ async fn submit_batch( let status = state.consensus_manager.record_vote( &archive_hash, &auth_headers.hotkey, - archive_bytes, Some(concurrent), required, total_validators, @@ -237,7 +246,6 @@ async fn submit_batch( })), )), ConsensusStatus::Reached { - archive_data, concurrent_tasks, votes, required, @@ -259,14 +267,15 @@ async fn submit_batch( let extract_dir = state.config.workspace_base.join("_extract_tmp"); let _ = tokio::fs::remove_dir_all(&extract_dir).await; - let extracted = crate::task::extract_uploaded_archive(&archive_data, &extract_dir) + let extracted = crate::task::extract_uploaded_archive(&archive_bytes, &extract_dir) .await .map_err(|e| { + warn!(error = %e, "Failed to extract uploaded archive"); ( StatusCode::BAD_REQUEST, Json(serde_json::json!({ "error": "extraction_failed", - "message": format!("Failed to extract archive: {}", e) + "message": "Failed to extract archive. Ensure it is a valid zip or tar.gz." })), ) })?; diff --git a/src/main.rs b/src/main.rs index 585c6b5..14e4e89 100644 --- a/src/main.rs +++ b/src/main.rs @@ -96,7 +96,13 @@ async fn main() { }); info!("Listening on {}", addr); - let listener = tokio::net::TcpListener::bind(&addr).await.unwrap(); + let listener = match tokio::net::TcpListener::bind(&addr).await { + Ok(l) => l, + Err(e) => { + error!("Failed to bind to {}: {}", addr, e); + std::process::exit(1); + } + }; let shutdown = async { tokio::signal::ctrl_c() @@ -105,10 +111,13 @@ async fn main() { info!("Shutdown signal received, draining..."); }; - axum::serve(listener, app) + if let Err(e) = axum::serve(listener, app) .with_graceful_shutdown(shutdown) .await - .unwrap(); + { + error!("Server error: {}", e); + std::process::exit(1); + } info!("Shutdown complete"); } diff --git a/src/ws.rs b/src/ws.rs index 3f4dd91..a844610 100644 --- a/src/ws.rs +++ b/src/ws.rs @@ -37,9 +37,8 @@ async fn handle_ws(socket: WebSocket, state: Arc, batch_id: String) { "error": "batch_not_found", "batch_id": batch_id, }); - let _ = sender - .send(Message::Text(serde_json::to_string(&err).unwrap())) - .await; + let msg = serde_json::to_string(&err).unwrap_or_default(); + let _ = sender.send(Message::Text(msg)).await; return; } }; @@ -65,11 +64,8 @@ async fn handle_ws(socket: WebSocket, state: Arc, batch_id: String) { }); drop(current_state); - if sender - .send(Message::Text(serde_json::to_string(&snapshot).unwrap())) - .await - .is_err() - { + let snapshot_json = serde_json::to_string(&snapshot).unwrap_or_default(); + if sender.send(Message::Text(snapshot_json)).await.is_err() { return; } @@ -95,9 +91,8 @@ async fn handle_ws(socket: WebSocket, state: Arc, batch_id: String) { "event": "stream_closed", "batch_id": batch_id_send, }); - let _ = sender - .send(Message::Text(serde_json::to_string(&close_msg).unwrap())) - .await; + let close_json = serde_json::to_string(&close_msg).unwrap_or_default(); + let _ = sender.send(Message::Text(close_json)).await; break; } } From cec71507b46e4f0987bbf34716df0cc46db6017f Mon Sep 17 00:00:00 2001 From: echobt Date: Wed, 18 Feb 2026 17:03:35 +0000 Subject: [PATCH 10/12] fix(dead-code): rename misleading underscore-prefixed variable in consensus --- src/consensus.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/consensus.rs b/src/consensus.rs index 2757aad..5b0c8f0 100644 --- a/src/consensus.rs +++ b/src/consensus.rs @@ -68,10 +68,10 @@ impl ConsensusManager { let votes = pending.voters.len(); if votes >= required { - let (_, _consensus) = entry.remove_entry(); + let (_, consensus) = entry.remove_entry(); info!(archive_hash, votes, required, "Consensus reached"); ConsensusStatus::Reached { - concurrent_tasks: _consensus.concurrent_tasks, + concurrent_tasks: consensus.concurrent_tasks, votes, required, } From c78b24a5f1c280610d0eea867e9e0a8c46055e30 Mon Sep 17 00:00:00 2001 From: echobt Date: Wed, 18 Feb 2026 17:07:01 +0000 Subject: [PATCH 11/12] fix(quality): replace unwrap/expect with proper error handling in production code - main.rs:21: Replace .parse().unwrap() on tracing directive with unwrap_or_else fallback to INFO level directive - main.rs:36: Replace .expect() on workspace dir creation with error log + process::exit(1) pattern - main.rs:110: Replace .expect() on ctrl_c handler with if-let-Err that logs and returns gracefully - executor.rs:189: Replace semaphore.acquire().unwrap() with match that handles closed semaphore by creating a failed TaskResult All changes follow AGENTS.md rule: no .unwrap()/.expect() in production code paths. Test code is unchanged. --- src/executor.rs | 12 +++++++++++- src/main.rs | 21 +++++++++++++-------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/executor.rs b/src/executor.rs index 4335436..a4df60d 100644 --- a/src/executor.rs +++ b/src/executor.rs @@ -186,7 +186,17 @@ async fn run_batch( let cancel_rx = batch.cancel.subscribe(); let handle = tokio::spawn(async move { - let _permit = semaphore.acquire().await.unwrap(); + let _permit = match semaphore.acquire().await { + Ok(p) => p, + Err(_) => { + warn!(task_id = %task.id, "Semaphore closed, skipping task"); + let mut result = TaskResult::new(task.id.clone()); + result.status = TaskStatus::Failed; + result.error = Some("Semaphore closed".to_string()); + task_results.lock().await.push(result); + return; + } + }; let task_id = task.id.clone(); let _ = events_tx.send(crate::session::WsEvent { diff --git a/src/main.rs b/src/main.rs index 14e4e89..f3d86d3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,10 +15,13 @@ use tracing::{error, info}; #[tokio::main] async fn main() { + let default_directive = "term_executor=info" + .parse() + .unwrap_or_else(|_| tracing_subscriber::filter::Directive::from(tracing::Level::INFO)); + tracing_subscriber::fmt() .with_env_filter( - tracing_subscriber::EnvFilter::from_default_env() - .add_directive("term_executor=info".parse().unwrap()), + tracing_subscriber::EnvFilter::from_default_env().add_directive(default_directive), ) .init(); @@ -31,9 +34,10 @@ async fn main() { }; config.print_banner(); - tokio::fs::create_dir_all(&config.workspace_base) - .await - .expect("Failed to create workspace directory"); + if let Err(e) = tokio::fs::create_dir_all(&config.workspace_base).await { + error!("Failed to create workspace directory: {}", e); + std::process::exit(1); + } let sessions = Arc::new(session::SessionManager::new(config.session_ttl_secs)); let metrics_store = metrics::Metrics::new(); @@ -105,9 +109,10 @@ async fn main() { }; let shutdown = async { - tokio::signal::ctrl_c() - .await - .expect("Failed to install CTRL+C handler"); + if let Err(e) = tokio::signal::ctrl_c().await { + error!("Failed to install CTRL+C handler: {}", e); + return; + } info!("Shutdown signal received, draining..."); }; From 3ab0a73acf4794b1f8697f004e5c839b27412a6f Mon Sep 17 00:00:00 2001 From: echobt Date: Wed, 18 Feb 2026 17:19:35 +0000 Subject: [PATCH 12/12] docs: refresh AGENTS.md --- AGENTS.md | 8 ++++---- src/AGENTS.md | 23 +++++++++++++---------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 3fca2e8..9b448cf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -53,7 +53,7 @@ ConsensusManager reaper loop (every 30 seconds): | `src/main.rs` | Entry point — bootstraps config, session manager, executor, validator whitelist, consensus manager, Axum server, background tasks | | `src/config.rs` | `Config` struct loaded from environment variables with defaults; Bittensor and consensus configuration | | `src/handlers.rs` | Axum route handlers: `/health`, `/status`, `/metrics`, `/submit`, `/batch/{id}`, `/batch/{id}/tasks`, `/batch/{id}/task/{task_id}`, `/batches` | -| `src/auth.rs` | Authentication: `extract_auth_headers()`, `verify_request()` (whitelist-based), `validate_ss58()`, sr25519 signature verification via `verify_sr25519_signature()`, `NonceStore` for replay protection, `AuthHeaders`/`AuthError` types | +| `src/auth.rs` | Authentication: `extract_auth_headers()`, `verify_request()` (whitelist-based), `validate_ss58()`, sr25519 signature verification via `verify_sr25519_signature()`, SS58 checksum via `blake2`, `NonceStore` for replay protection, `AuthHeaders`/`AuthError` types | | `src/validator_whitelist.rs` | Dynamic validator whitelist — fetches validators from Bittensor netuid 100 every 5 minutes, filters by stake ≥10k TAO, stores SS58 hotkeys in `parking_lot::RwLock` | | `src/consensus.rs` | 50% consensus manager — tracks pending votes per archive hash in `DashMap`, triggers evaluation when ≥50% of whitelisted validators submit same payload, TTL reaper for expired entries | | `src/executor.rs` | Core evaluation engine — spawns batch tasks that clone repos, run agents, run tests concurrently | @@ -83,7 +83,7 @@ ConsensusManager reaper loop (every 30 seconds): - **Archive Handling**: `flate2` + `tar` (tar.gz), `zip` 2 (zip) - **Error Handling**: `anyhow` 1 + `thiserror` 2 - **Logging**: `tracing` + `tracing-subscriber` with env-filter -- **Crypto/Identity**: `sha2`, `hex`, `base64`, `bs58` (SS58 address validation), `schnorrkel` 0.11 (sr25519 signature verification), `rand_core` 0.6, `uuid` v4 +- **Crypto/Identity**: `sha2`, `hex`, `base64`, `bs58` (SS58 address validation), `schnorrkel` 0.11 (sr25519 signature verification), `blake2` 0.10 (SS58 checksum), `rand_core` 0.6, `uuid` v4 - **Blockchain**: `bittensor-rs` (git dependency) for Bittensor validator whitelisting via subtensor RPC - **Time**: `chrono` with serde support - **Build Tooling**: `mold` linker via `.cargo/config.toml`, `clang` as linker driver @@ -187,14 +187,14 @@ Both hooks are activated via `git config core.hooksPath .githooks`. | `AGENT_TIMEOUT_SECS` | `600` | Agent execution timeout | | `TEST_TIMEOUT_SECS` | `300` | Test suite timeout | | `MAX_ARCHIVE_BYTES` | `524288000` | Max uploaded archive size (500MB) | -| `MAX_OUTPUT_BYTES` | `1048576` | Max captured output per command (1MB) | | `WORKSPACE_BASE` | `/tmp/sessions` | Base directory for session workspaces | | `BITTENSOR_NETUID` | `100` | Bittensor subnet ID for validator lookup | | `MIN_VALIDATOR_STAKE_TAO` | `10000` | Minimum TAO stake for validator whitelisting | | `VALIDATOR_REFRESH_SECS` | `300` | Interval for refreshing validator whitelist (seconds) | | `CONSENSUS_THRESHOLD` | `0.5` | Fraction of validators required for consensus (0.0–1.0) | | `CONSENSUS_TTL_SECS` | `60` | TTL for pending consensus entries (seconds) | +| `MAX_PENDING_CONSENSUS` | `100` | Maximum number of pending consensus entries | ## Authentication -Authentication requires three HTTP headers: `X-Hotkey` (SS58 address), `X-Nonce` (unique per-request), and `X-Signature` (sr25519 hex signature of `hotkey + nonce`). The authorized hotkeys are dynamically loaded from the Bittensor blockchain — all validators on netuid 100 with ≥10,000 TAO stake and an active validator permit are whitelisted. The whitelist refreshes every 5 minutes. Verification steps: hotkey must be in the validator whitelist, SS58 format must be valid, nonce must not have been seen before (replay protection via `NonceStore` in `src/auth.rs` with 5-minute TTL), and the sr25519 signature must verify against the hotkey's public key using the Substrate signing context. Only requests passing all checks can submit batches via `POST /submit`. Evaluations are only triggered when ≥50% of whitelisted validators have submitted the same archive payload (identified by SHA-256 hash). All other endpoints are open. +Authentication requires three HTTP headers: `X-Hotkey` (SS58 address), `X-Nonce` (unique per-request), and `X-Signature` (sr25519 hex signature of `hotkey + nonce`). The authorized hotkeys are dynamically loaded from the Bittensor blockchain — all validators on netuid 100 with ≥10,000 TAO stake and an active validator permit are whitelisted. The whitelist refreshes every 5 minutes. Verification steps (in order): hotkey must be in the validator whitelist, SS58 format must be valid, sr25519 signature must verify against the hotkey's public key using the Substrate signing context, and finally the nonce must not have been seen before (replay protection via `NonceStore` in `src/auth.rs` with 5-minute TTL — nonce is only consumed after signature passes). Only requests passing all checks can submit batches via `POST /submit`. Evaluations are only triggered when ≥50% of whitelisted validators have submitted the same archive payload (identified by SHA-256 hash). All other endpoints are open. diff --git a/src/AGENTS.md b/src/AGENTS.md index ce9ba65..190b21c 100644 --- a/src/AGENTS.md +++ b/src/AGENTS.md @@ -35,10 +35,10 @@ main.rs ### `config.rs` - `Config` struct with all environment-driven settings. -- `Config::from_env()` reads env vars with `env_parse()` helper (returns default on missing/invalid). +- `Config::from_env()` reads env vars with `env_parse()` helper (returns default on missing/invalid). Returns `Result` — validates `consensus_threshold` is in `(0.0, 1.0]`. - `Config::print_banner()` logs a formatted startup banner. - Includes Bittensor settings: `bittensor_netuid`, `min_validator_stake_tao`, `validator_refresh_secs`. -- Includes consensus settings: `consensus_threshold`, `consensus_ttl_secs`. +- Includes consensus settings: `consensus_threshold`, `consensus_ttl_secs`, `max_pending_consensus`. - **Convention**: Add new config fields here, with a `DEFAULT_*` constant and an env var name. Always provide a sensible default. ### `validator_whitelist.rs` @@ -53,8 +53,8 @@ main.rs ### `consensus.rs` - `ConsensusManager` — `DashMap` keyed by SHA-256 hex hash of archive bytes. -- `PendingConsensus` — holds archive data, voter set, creation time, concurrent_tasks setting. -- `record_vote()` — adds a validator's vote for an archive hash; returns `ConsensusStatus` (Pending, Reached, AlreadyVoted). +- `PendingConsensus` — holds voter set (`HashSet`), creation time, concurrent_tasks setting. +- `record_vote(archive_hash, hotkey, concurrent_tasks, required, total_validators)` — adds a validator's vote for an archive hash; returns `ConsensusStatus` (Pending, Reached, AlreadyVoted). Removes entry from `DashMap` upon reaching consensus. - `is_at_capacity()` — checks if max pending entries reached (prevents memory exhaustion). - `reaper_loop(ttl_secs)` — background task that removes expired entries every 30 seconds. - **Convention**: Consensus entries have a 60-second TTL. Max 100 pending entries. Duplicate votes from the same validator are silently acknowledged. @@ -64,23 +64,26 @@ main.rs - `router()` builds the Axum `Router` with all routes and shared state. - Route handlers: `health`, `status`, `metrics`, `submit_batch`, `get_batch`, `get_batch_tasks`, `get_task`, `list_batches`. - Routes: `GET /health`, `GET /status`, `GET /metrics`, `POST /submit`, `GET /batch/{id}`, `GET /batch/{id}/tasks`, `GET /batch/{id}/task/{task_id}`, `GET /batches`, `GET /ws`. -- `submit_batch` handler does: auth header extraction → whitelist empty check (503) → `verify_request` (whitelist + nonce + signature) → multipart upload → SHA-256 hash → consensus vote → if pending: return 202 with vote count → if reached: archive extraction → batch creation → executor spawn. +- `submit_batch` handler does: auth header extraction → whitelist empty check (503) → `verify_request` (whitelist + SS58 + signature + nonce) → multipart upload → capacity check → SHA-256 hash → consensus vote → if pending: return 202 with vote count → if reached: active batch check → archive extraction → batch creation → executor spawn. - **Convention**: Return `Result)>` from handlers that can fail. Use `Json(serde_json::json!({...}))` for responses. ### `auth.rs` - `NonceStore` — `DashMap`-backed nonce tracker with 5-minute TTL and background reaper loop for replay protection. - `AuthHeaders` — struct holding `hotkey`, `nonce`, `signature` extracted from request headers. -- `extract_auth_headers(headers)` — reads `X-Hotkey`, `X-Nonce`, `X-Signature` headers from request. -- `verify_request(auth, nonce_store, whitelist)` — full auth pipeline: whitelist check → SS58 validation → nonce replay check → sr25519 signature verification. -- `validate_ss58(address)` — validates SS58 address format using `bs58`. +- `extract_auth_headers(headers)` — reads `X-Hotkey`, `X-Nonce`, `X-Signature` headers from request (case-insensitive). Validates length limits: hotkey ≤128, nonce 1–256 (ASCII graphic + space), signature ≤256. +- `verify_request(auth, nonce_store, whitelist)` — full auth pipeline: whitelist check → SS58 validation → sr25519 signature verification → nonce replay check (nonce is only consumed after signature passes). +- `validate_ss58(address)` — validates SS58 address format (must start with `5`) using `bs58` and checksum verification. - `verify_sr25519_signature(ss58_hotkey, message, signature_hex)` — verifies an sr25519 signature using `schnorrkel` with the Substrate signing context. +- `ss58_to_public_key_bytes(address)` — decodes SS58 address to 32-byte public key with `blake2` checksum verification. +- `ss58_checksum(data)` — computes SS58 checksum using `Blake2b` with `SS58PRE` prefix. - `AuthError` — enum with `UnauthorizedHotkey`, `InvalidHotkey`, `NonceReused`, `InvalidSignature` variants, each with `.code()` and `.message()` methods. - **Convention**: Auth is mandatory — `POST /submit` requires three headers (`X-Hotkey`, `X-Nonce`, `X-Signature`). The signed message is `hotkey + nonce`. ### `executor.rs` - `Executor::spawn_batch(batch, archive, concurrent_limit)` — spawns a tokio task that runs all tasks in the batch. - `run_batch(config, batch, archive, concurrent_limit)` — orchestrates concurrent task execution with a per-batch `Semaphore`. -- `run_single_task(config, task, agent_code, agent_language, cancel_rx)` — runs one task: clone → install → agent → tests → cleanup. +- `run_single_task(config, task, agent_code, agent_language, cancel_rx)` — runs one task: creates work dir → delegates to `run_task_pipeline` → cleanup. +- `run_task_pipeline(config, task, agent_code, agent_language, work_dir, cancel_rx)` — task execution pipeline: clone → checkout → install → agent → write test source files → tests. Checks `cancel_rx` between phases. - `run_cmd(argv, cwd, timeout, env)` / `run_shell(shell_cmd, cwd, timeout, env)` — process execution with timeout. - `truncate_output(raw)` — caps output at 1MB. - `agent_extension(language)` / `agent_runner(language, script_path)` — maps language strings to file extensions and runner commands. @@ -90,7 +93,7 @@ main.rs - `BatchStatus` (enum: Pending, Extracting, Running, Completed, Failed), `TaskStatus` (enum: Queued, CloningRepo, InstallingDeps, RunningAgent, RunningTests, Completed, Failed). - `TaskTestResult`, `TaskResult`, `BatchResult` — core result data types. - `WsEvent` — WebSocket event struct with `event`, `batch_id`, `task_id`, `data`. -- `Batch` — holds id, created_at, result (`Arc>`), events_tx (`broadcast::Sender`), cancel channel. +- `Batch` — holds id, created_at, result (`Arc>`), events_tx (`broadcast::Sender`), cancel (`tokio::sync::watch::Sender`). - `SessionStats` — atomic counters for created/active/completed/failed batches. - `BatchSummary` — lightweight struct for `list_batches()` output. - `SessionManager` — `DashMap`-backed batch store with `SessionStats`, create/get/list/has_active_batch/mark_completed/mark_failed operations.