diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index df716ab5..89b886c3 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -25,9 +25,11 @@ jobs: cache-on-failure: true - name: Build run: cargo build --workspace + # out of disk + # - name: Build with rustls + # run: cargo build --workspace --features reqwest-rustls-tls --no-default-features - name: Run tests - run: cargo test --workspace - + run: cargo test --workspace -j1 clippy: runs-on: ubuntu-latest timeout-minutes: 30 @@ -52,3 +54,86 @@ jobs: with: components: rustfmt - run: cargo fmt --all --check + + package: + name: Upload artifacts + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + # run on PRs (workflow already triggers on pull_request) + needs: [build] + strategy: + fail-fast: false + matrix: + include: + - os: macos-latest + arch: x86_64 + target: x86_64-apple-darwin + - os: macos-latest + arch: aarch64 + target: aarch64-apple-darwin + - os: ubuntu-latest + arch: x86_64 + target: x86_64-unknown-linux-gnu + # - os: ubuntu-latest + # arch: aarch64 + # target: aarch64-unknown-linux-gnu + - os: windows-latest + arch: x86_64 + target: x86_64-pc-windows-msvc + # - os: windows-latest + # arch: aarch64 + # target: aarch64-pc-windows-msvc + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + + - name: Install rust target + run: rustup target add ${{ matrix.target }} + + - name: Build CLI (release) + run: | + cargo build -p cryo_cli --release --target ${{ matrix.target }} + + - name: Package CLI (unix) + if: matrix.os != 'windows-latest' + run: | + mkdir -p dist/${{ matrix.os }}-${{ matrix.arch }} + echo "Packaging CLI for runner.os=${{ runner.os }} matrix.arch=${{ matrix.arch }}" + # Prefer the target-specific release path if it exists (cross/target builds) + if [ -f "target/${{ matrix.target }}/release/cryo" ]; then + cp -f "target/${{ matrix.target }}/release/cryo" dist/${{ matrix.os }}-${{ matrix.arch }}/ || true + else + cp -f target/release/cryo dist/${{ matrix.os }}-${{ matrix.arch }}/ || true + fi + tar -czf dist/cryo-cli-${{ matrix.os }}-${{ matrix.arch }}-${{ github.sha }}.tar.gz -C dist/${{ matrix.os }}-${{ matrix.arch }} . + + - name: Package CLI (windows) + if: matrix.os == 'windows-latest' + shell: pwsh + run: | + New-Item -ItemType Directory -Force -Path "dist\${{ matrix.os }}-${{ matrix.arch }}" | Out-Null + Write-Host "Packaging CLI on Windows runner for matrix.arch=${{ matrix.arch }}" + if (Test-Path -Path "target\${{ matrix.target }}\release\cryo.exe") { + Copy-Item -Path "target\${{ matrix.target }}\release\cryo.exe" -Destination "dist\${{ matrix.os }}-${{ matrix.arch }}\" -Force + } elseif (Test-Path -Path "target\release\cryo.exe") { + Copy-Item -Path "target\release\cryo.exe" -Destination "dist\${{ matrix.os }}-${{ matrix.arch }}\" -Force + } + Compress-Archive -Path "dist\${{ matrix.os }}-${{ matrix.arch }}\*" -DestinationPath "dist\cryo-cli-${{ matrix.os }}-${{ matrix.arch }}-${{ github.sha }}.zip" -Force + + - uses: PyO3/maturin-action@v1 + with: + command: build + working-directory: crates/python + args: --release --strip -o ../../dist/ + target: ${{ matrix.target }} + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: cryo-artifacts-${{ matrix.target }}-${{ github.run_id }} + path: | + dist/cryo-cli-${{ matrix.os }}-${{ matrix.arch }}-* + dist/*.whl diff --git a/.gitignore b/.gitignore index f20260e9..565c31ef 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ graveyard .idea flamegraph.svg test.sh +rethdata +jwt.hex diff --git a/Cargo.lock b/Cargo.lock index c48c4cdf..d818e741 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,27 +4,33 @@ version = 4 [[package]] name = "addr2line" -version = "0.24.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ "gimli", ] [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "adler32" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom", + "getrandom 0.3.3", "once_cell", "version_check", "zerocopy", @@ -56,15 +62,15 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b524b8c28a7145d1fe4950f84360b5de3e307601679ff0558ddc20ea229399" +checksum = "7f6cfe35f100bc496007c9a00f90b88bdf565f1421d4c707c9f07e0717e2aaad" dependencies = [ "alloy-consensus", "alloy-contract", @@ -83,13 +89,14 @@ dependencies = [ "alloy-transport-http", "alloy-transport-ipc", "alloy-transport-ws", + "alloy-trie", ] [[package]] name = "alloy-chains" -version = "0.1.47" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18c5c520273946ecf715c0010b4e3503d7eba9893cd9ce6b7fff5654c4a3c470" +checksum = "bf01dd83a1ca5e4807d0ca0223c9615e211ce5db0a9fd1443c2778cacf89b546" dependencies = [ "alloy-primitives", "num_enum", @@ -98,27 +105,51 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae09ffd7c29062431dd86061deefe4e3c6f07fa0d674930095f8dcedb0baf02c" +checksum = "59094911f05dbff1cf5b29046a00ef26452eccc8d47136d50a47c0cf22f00c85" dependencies = [ "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-serde", + "alloy-trie", + "alloy-tx-macros", "auto_impl", "c-kzg", "derive_more", + "either", "k256", + "once_cell", + "rand 0.8.5", + "secp256k1", + "serde", + "serde_json", + "serde_with", + "thiserror 2.0.17", +] + +[[package]] +name = "alloy-consensus-any" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "903cb8f728107ca27c816546f15be38c688df3c381d7bd1a4a9f215effc1ddb4" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", "serde", ] [[package]] name = "alloy-contract" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66430a72d5bf5edead101c8c2f0a24bada5ec9f3cf9909b3e08b6d6899b4803e" +checksum = "03df5cb3b428ac96b386ad64c11d5c6e87a5505682cf1fbd6f8f773e9eda04f6" dependencies = [ + "alloy-consensus", "alloy-dyn-abi", "alloy-json-abi", "alloy-network", @@ -131,14 +162,15 @@ dependencies = [ "alloy-transport", "futures", "futures-util", - "thiserror", + "serde_json", + "thiserror 2.0.17", ] [[package]] name = "alloy-core" -version = "0.8.13" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d22df68fa7d9744be0b1a9be3260e9aa089fbf41903ab182328333061ed186" +checksum = "575053cea24ea8cb7e775e39d5c53c33b19cfd0ca1cf6c0fd653f3d8c682095f" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -149,26 +181,38 @@ dependencies = [ [[package]] name = "alloy-dyn-abi" -version = "0.8.13" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cf633ae9a1f0c82fdb9e559ed2be1c8e415c3e48fc47e1feaf32c6078ec0cdd" +checksum = "a6c2905bafc2df7ccd32ca3af13f0b0d82f2e2ff9dfbeb12196c0d978d5c0deb" dependencies = [ "alloy-json-abi", "alloy-primitives", "alloy-sol-type-parser", "alloy-sol-types", - "const-hex", "itoa", "serde", "serde_json", "winnow", ] +[[package]] +name = "alloy-eip2124" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "741bdd7499908b3aa0b159bba11e71c8cddd009a2c2eb7a06e825f1ec87900a5" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "crc 3.3.0", + "serde", + "thiserror 2.0.17", +] + [[package]] name = "alloy-eip2930" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0069cf0642457f87a01a014f6dc29d5d893cd4fd8fddf0c3cdfad1bb3ebafc41" +checksum = "7b82752a889170df67bbb36d42ca63c531eb16274f0d7299ae2a680facba17bd" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -177,51 +221,58 @@ dependencies = [ [[package]] name = "alloy-eip7702" -version = "0.4.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6cee6a35793f3db8a5ffe60e86c695f321d081a567211245f503e8c498fce8" +checksum = "9d4769c6ffddca380b0070d71c8b7f30bed375543fe76bb2f74ec0acf4b7cd16" dependencies = [ "alloy-primitives", "alloy-rlp", - "derive_more", "k256", "serde", + "thiserror 2.0.17", ] [[package]] name = "alloy-eips" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b6aa3961694b30ba53d41006131a2fca3bdab22e4c344e46db2c639e7c2dfdd" +checksum = "ac7f1c9a1ccc7f3e03c36976455751a6166a4f0d2d2c530c3f87dfe7d0cdc836" dependencies = [ + "alloy-eip2124", "alloy-eip2930", "alloy-eip7702", "alloy-primitives", "alloy-rlp", "alloy-serde", + "auto_impl", "c-kzg", "derive_more", - "once_cell", + "either", "serde", + "serde_with", "sha2", + "thiserror 2.0.17", ] [[package]] name = "alloy-genesis" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53f7877ded3921d18a0a9556d55bedf84535567198c9edab2aa23106da91855" +checksum = "1421f6c9d15e5b86afbfe5865ca84dea3b9f77173a0963c1a2ee4e626320ada9" dependencies = [ + "alloy-eips", "alloy-primitives", "alloy-serde", + "alloy-trie", "serde", + "serde_with", ] [[package]] name = "alloy-json-abi" -version = "0.8.13" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a500037938085feed8a20dbfc8fce58c599db68c948cfae711147175dee392c" +checksum = "a2acb6637a9c0e1cdf8971e0ced8f3fa34c04c5e9dccf6bb184f6a64fe0e37d8" dependencies = [ "alloy-primitives", "alloy-sol-type-parser", @@ -231,46 +282,50 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3694b7e480728c0b3e228384f223937f14c10caef5a4c766021190fc8f283d35" +checksum = "65f763621707fa09cece30b73ecc607eb43fd7a72451fe3b46f645b905086926" dependencies = [ "alloy-primitives", "alloy-sol-types", + "http", "serde", "serde_json", - "thiserror", + "thiserror 2.0.17", "tracing", ] [[package]] name = "alloy-network" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea94b8ceb5c75d7df0a93ba0acc53b55a22b47b532b600a800a87ef04eb5b0b4" +checksum = "2f59a869fa4b4c3a7f08b1c8cb79aec61c29febe6e24a24fe0fcfded8a9b5703" dependencies = [ "alloy-consensus", + "alloy-consensus-any", "alloy-eips", "alloy-json-rpc", "alloy-network-primitives", "alloy-primitives", + "alloy-rpc-types-any", "alloy-rpc-types-eth", "alloy-serde", "alloy-signer", "alloy-sol-types", "async-trait", "auto_impl", + "derive_more", "futures-utils-wasm", "serde", "serde_json", - "thiserror", + "thiserror 2.0.17", ] [[package]] name = "alloy-network-primitives" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df9f3e281005943944d15ee8491534a1c7b3cbf7a7de26f8c433b842b93eb5f9" +checksum = "46e9374c667c95c41177602ebe6f6a2edd455193844f011d973d374b65501b38" dependencies = [ "alloy-consensus", "alloy-eips", @@ -281,25 +336,24 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.8.13" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3aeeb5825c2fc8c2662167058347cd0cafc3cb15bcb5cdb1758a63c2dca0409e" +checksum = "5b77f7d5e60ad8ae6bd2200b8097919712a07a6db622a4b201e7ead6166f02e5" dependencies = [ "alloy-rlp", "bytes", "cfg-if", "const-hex", "derive_more", - "foldhash", - "hashbrown 0.15.2", - "hex-literal", - "indexmap", + "foldhash 0.2.0", + "hashbrown 0.16.0", + "indexmap 2.11.4", "itoa", "k256", "keccak-asm", "paste", "proptest", - "rand", + "rand 0.9.2", "ruint", "rustc-hash", "serde", @@ -309,9 +363,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40c1f9eede27bf4c13c099e8e64d54efd7ce80ef6ea47478aa75d5d74e2dba3b" +checksum = "77818b7348bd5486491a5297579dbfe5f706a81f8e1f5976393025f1e22a7c7d" dependencies = [ "alloy-chains", "alloy-consensus", @@ -322,8 +376,13 @@ dependencies = [ "alloy-primitives", "alloy-pubsub", "alloy-rpc-client", + "alloy-rpc-types-anvil", + "alloy-rpc-types-debug", "alloy-rpc-types-eth", "alloy-rpc-types-trace", + "alloy-rpc-types-txpool", + "alloy-signer", + "alloy-sol-types", "alloy-transport", "alloy-transport-http", "alloy-transport-ipc", @@ -331,17 +390,17 @@ dependencies = [ "async-stream", "async-trait", "auto_impl", - "dashmap 6.1.0", + "dashmap", + "either", "futures", "futures-utils-wasm", "lru", "parking_lot", "pin-project", "reqwest", - "schnellru", "serde", "serde_json", - "thiserror", + "thiserror 2.0.17", "tokio", "tracing", "url", @@ -350,28 +409,31 @@ dependencies = [ [[package]] name = "alloy-pubsub" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f1f34232f77341076541c405482e4ae12f0ee7153d8f9969fc1691201b2247" +checksum = "249b45103a66c9ad60ad8176b076106d03a2399a37f0ee7b0e03692e6b354cb9" dependencies = [ "alloy-json-rpc", "alloy-primitives", "alloy-transport", + "auto_impl", "bimap", "futures", + "parking_lot", "serde", "serde_json", "tokio", "tokio-stream", "tower", "tracing", + "wasmtimer", ] [[package]] name = "alloy-rlp" -version = "0.3.9" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0822426598f95e45dd1ea32a738dac057529a709ee645fcc516ffa4cbde08f" +checksum = "5f70d83b765fdc080dbcd4f4db70d8d23fe4761f2f02ebfa9146b833900634b4" dependencies = [ "alloy-rlp-derive", "arrayvec", @@ -380,20 +442,20 @@ dependencies = [ [[package]] name = "alloy-rlp-derive" -version = "0.3.9" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b09cae092c27b6f1bde952653a22708691802e57bfef4a2973b80bea21efd3f" +checksum = "64b728d511962dda67c1bc7ea7c03736ec275ed2cf4c35d9585298ac9ccf3b73" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] name = "alloy-rpc-client" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374dbe0dc3abdc2c964f36b3d3edf9cdb3db29d16bda34aa123f03d810bec1dd" +checksum = "2430d5623e428dd012c6c2156ae40b7fe638d6fca255e3244e0fba51fa698e93" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -417,23 +479,61 @@ dependencies = [ [[package]] name = "alloy-rpc-types" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c74832aa474b670309c20fffc2a869fa141edab7c79ff7963fad0a08de60bae1" +checksum = "e9e131624d08a25cfc40557041e7dc42e1182fa1153e7592d120f769a1edce56" dependencies = [ "alloy-primitives", + "alloy-rpc-types-anvil", + "alloy-rpc-types-debug", "alloy-rpc-types-engine", "alloy-rpc-types-eth", "alloy-rpc-types-trace", + "alloy-rpc-types-txpool", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-rpc-types-anvil" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d65e3266095e6d8e8028aab5f439c6b8736c5147314f7e606c61597e014cb8a0" +dependencies = [ + "alloy-primitives", + "alloy-rpc-types-eth", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-rpc-types-any" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07429a1099cd17227abcddb91b5e38c960aaeb02a6967467f5bb561fbe716ac6" +dependencies = [ + "alloy-consensus-any", + "alloy-rpc-types-eth", "alloy-serde", +] + +[[package]] +name = "alloy-rpc-types-debug" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aeff305b7d10cc1c888456d023e7bb8a5ea82e9e42b951e37619b88cc1a1486d" +dependencies = [ + "alloy-primitives", + "derive_more", "serde", + "serde_with", ] [[package]] name = "alloy-rpc-types-engine" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56294dce86af23ad6ee8df46cf8b0d292eb5d1ff67dc88a0886051e32b1faf" +checksum = "222ecadcea6aac65e75e32b6735635ee98517aa63b111849ee01ae988a71d685" dependencies = [ "alloy-consensus", "alloy-eips", @@ -441,48 +541,64 @@ dependencies = [ "alloy-rlp", "alloy-serde", "derive_more", + "jsonwebtoken", + "rand 0.8.5", "serde", "strum", ] [[package]] name = "alloy-rpc-types-eth" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a477281940d82d29315846c7216db45b15e90bcd52309da9f54bcf7ad94a11" +checksum = "db46b0901ee16bbb68d986003c66dcb74a12f9d9b3c44f8e85d51974f2458f0f" dependencies = [ "alloy-consensus", + "alloy-consensus-any", "alloy-eips", "alloy-network-primitives", "alloy-primitives", "alloy-rlp", "alloy-serde", "alloy-sol-types", - "derive_more", - "itertools 0.13.0", + "itertools 0.14.0", "serde", "serde_json", + "serde_with", + "thiserror 2.0.17", ] [[package]] name = "alloy-rpc-types-trace" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd8b4877ef520c138af702097477cdd19504a8e1e4675ba37e92ba40f2d3c6f" +checksum = "36f10620724bd45f80c79668a8cdbacb6974f860686998abce28f6196ae79444" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", "alloy-serde", "serde", "serde_json", - "thiserror", + "thiserror 2.0.17", +] + +[[package]] +name = "alloy-rpc-types-txpool" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "864f41befa90102d4e02327679699a7e9510930e2924c529e31476086609fa89" +dependencies = [ + "alloy-primitives", + "alloy-rpc-types-eth", + "alloy-serde", + "serde", ] [[package]] name = "alloy-serde" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dfa4a7ccf15b2492bb68088692481fd6b2604ccbee1d0d6c44c21427ae4df83" +checksum = "5413814be7a22fbc81e0f04a2401fcc3eb25e56fd53b04683e8acecc6e1fe01b" dependencies = [ "alloy-primitives", "serde", @@ -491,23 +607,24 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e10aec39d60dc27edcac447302c7803d2371946fb737245320a05b78eb2fafd" +checksum = "53410a18a61916e2c073a6519499514e027b01e77eeaf96acd1df7cf96ef6bb2" dependencies = [ "alloy-primitives", "async-trait", "auto_impl", + "either", "elliptic-curve", "k256", - "thiserror", + "thiserror 2.0.17", ] [[package]] name = "alloy-signer-local" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8396f6dff60700bc1d215ee03d86ff56de268af96e2bf833a14d0bafcab9882" +checksum = "e6006c4cbfa5d08cadec1fcabea6cb56dc585a30a9fce40bcf81e307d6a71c8e" dependencies = [ "alloy-consensus", "alloy-network", @@ -515,65 +632,66 @@ dependencies = [ "alloy-signer", "async-trait", "k256", - "rand", - "thiserror", + "rand 0.8.5", + "thiserror 2.0.17", ] [[package]] name = "alloy-sol-macro" -version = "0.8.13" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c0279d09463a4695788a3622fd95443625f7be307422deba4b55dd491a9c7a1" +checksum = "78c84c3637bee9b5c4a4d2b93360ee16553d299c3b932712353caf1cea76d0e6" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] name = "alloy-sol-macro-expander" -version = "0.8.13" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4feea540fc8233df2ad1156efd744b2075372f43a8f942a68b3b19c8a00e2c12" +checksum = "a882aa4e1790063362434b9b40d358942b188477ac1c44cfb8a52816ffc0cc17" dependencies = [ "alloy-json-abi", "alloy-sol-macro-input", "const-hex", - "heck 0.5.0", - "indexmap", + "heck", + "indexmap 2.11.4", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", "syn-solidity", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "0.8.13" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0ad281f3d1b613af814b66977ee698e443d4644a1510962d0241f26e0e53ae" +checksum = "18e5772107f9bb265d8d8c86e0733937bb20d0857ea5425b1b6ddf51a9804042" dependencies = [ "alloy-json-abi", "const-hex", "dunce", - "heck 0.5.0", + "heck", + "macro-string", "proc-macro2", "quote", "serde_json", - "syn 2.0.89", + "syn 2.0.106", "syn-solidity", ] [[package]] name = "alloy-sol-type-parser" -version = "0.8.13" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96eff16c797438add6c37bb335839d015b186c5421ee5626f5559a7bfeb38ef5" +checksum = "e188b939aa4793edfaaa099cb1be4e620036a775b4bdf24fdc56f1cd6fd45890" dependencies = [ "serde", "winnow", @@ -581,30 +699,33 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.8.13" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff34e0682d6665da243a3e81da96f07a2dd50f7e64073e382b1a141f5a2a2f6" +checksum = "c3c8a9a909872097caffc05df134e5ef2253a1cdb56d3a9cf0052a042ac763f9" dependencies = [ "alloy-json-abi", "alloy-primitives", "alloy-sol-macro", - "const-hex", "serde", ] [[package]] name = "alloy-transport" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f99acddb34000d104961897dbb0240298e8b775a7efffb9fda2a1a3efedd65b3" +checksum = "d94ee404368a3d9910dfe61b203e888c6b0e151a50e147f95da8baff9f9c7763" dependencies = [ "alloy-json-rpc", - "base64 0.22.1", - "futures-util", + "alloy-primitives", + "auto_impl", + "base64", + "derive_more", + "futures", "futures-utils-wasm", + "parking_lot", "serde", "serde_json", - "thiserror", + "thiserror 2.0.17", "tokio", "tower", "tracing", @@ -614,12 +735,18 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dc013132e34eeadaa0add7e74164c1503988bfba8bae885b32e0918ba85a8a6" +checksum = "a2f8a6338d594f6c6481292215ee8f2fd7b986c80aba23f3f44e761a8658de78" dependencies = [ "alloy-json-rpc", + "alloy-rpc-types-engine", "alloy-transport", + "http-body-util", + "hyper", + "hyper-tls", + "hyper-util", + "jsonwebtoken", "reqwest", "serde_json", "tower", @@ -629,9 +756,9 @@ dependencies = [ [[package]] name = "alloy-transport-ipc" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063edc0660e81260653cc6a95777c29d54c2543a668aa5da2359fb450d25a1ba" +checksum = "17a37a8ca18006fa0a58c7489645619ff58cfa073f2b29c4e052c9bd114b123a" dependencies = [ "alloy-json-rpc", "alloy-pubsub", @@ -650,9 +777,9 @@ dependencies = [ [[package]] name = "alloy-transport-ws" -version = "0.6.4" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abd170e600801116d5efe64f74a4fc073dbbb35c807013a7d0a388742aeebba0" +checksum = "679b0122b7bca9d4dc5eb2c0549677a3c53153f6e232f23f4b3ba5575f74ebde" dependencies = [ "alloy-pubsub", "alloy-transport", @@ -667,10 +794,33 @@ dependencies = [ ] [[package]] -name = "android-tzdata" -version = "0.1.1" +name = "alloy-trie" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3412d52bb97c6c6cc27ccc28d4e6e8cf605469101193b50b0bd5813b1f990b5" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "arrayvec", + "derive_more", + "nybbles", + "serde", + "smallvec", + "tracing", +] + +[[package]] +name = "alloy-tx-macros" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" +checksum = "e64c09ec565a90ed8390d82aa08cd3b22e492321b96cb4a3d4f58414683c9e2f" +dependencies = [ + "alloy-primitives", + "darling", + "proc-macro2", + "quote", + "syn 2.0.106", +] [[package]] name = "android_system_properties" @@ -683,58 +833,76 @@ dependencies = [ [[package]] name = "anstream" -version = "0.3.2" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is-terminal", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "anstyle-wincon" -version = "1.0.2" +version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c677ab05e09154296dd37acecd46420c17b9713e8366facafa8fc0885167cf4c" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "once_cell_polyfill", + "windows-sys 0.60.2", +] + +[[package]] +name = "arboard" +version = "3.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0348a1c054491f4bfe6ab86a7b6ab1e44e45d899005de92f58b3df180b36ddaf" +dependencies = [ + "clipboard-win", + "log", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "parking_lot", + "percent-encoding", + "windows-sys 0.60.2", + "x11rb", ] [[package]] name = "argminmax" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52424b59d69d69d5056d508b260553afd91c57e21849579cd1f50ee8b8b88eaa" +checksum = "70f13d10a41ac8d2ec79ee34178d61e6f47a29c2edfe7ef1721c7383b0359e65" dependencies = [ "num-traits", ] @@ -777,6 +945,26 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ark-ff" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +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", + "digest 0.10.7", + "educe", + "itertools 0.13.0", + "num-bigint", + "num-traits", + "paste", + "zeroize", +] + [[package]] name = "ark-ff-asm" version = "0.3.0" @@ -797,6 +985,16 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ark-ff-asm" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" +dependencies = [ + "quote", + "syn 2.0.106", +] + [[package]] name = "ark-ff-macros" version = "0.3.0" @@ -822,6 +1020,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ark-ff-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "ark-serialize" version = "0.3.0" @@ -843,6 +1054,18 @@ dependencies = [ "num-bigint", ] +[[package]] +name = "ark-serialize" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" +dependencies = [ + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "num-bigint", +] + [[package]] name = "ark-std" version = "0.3.0" @@ -850,7 +1073,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" dependencies = [ "num-traits", - "rand", + "rand 0.8.5", ] [[package]] @@ -860,52 +1083,83 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ "num-traits", - "rand", + "rand 0.8.5", +] + +[[package]] +name = "ark-std" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" +dependencies = [ + "num-traits", + "rand 0.8.5", ] [[package]] name = "array-init-cursor" -version = "0.2.0" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed51fe0f224d1d4ea768be38c51f9f831dee9d05c163c11fba0b8c44387b1fc3" + +[[package]] +name = "arrayref" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7d0a018de4f6aa429b9d33d69edf69072b1c5b1cb8d3e4a5f7ef898fc3eb76" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +dependencies = [ + "serde", +] [[package]] -name = "async-stream" -version = "0.3.6" +name = "async-channel" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" dependencies = [ - "async-stream-impl", + "concurrent-queue", + "event-listener-strategy", "futures-core", "pin-project-lite", ] [[package]] -name = "async-stream-impl" +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] name = "async-trait" -version = "0.1.83" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] @@ -920,42 +1174,56 @@ dependencies = [ ] [[package]] -name = "atoi" -version = "2.0.0" +name = "atoi_simd" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +checksum = "c2a49e05797ca52e312a0c658938b7d00693ef037799ef7187678f212d7684cf" dependencies = [ - "num-traits", + "debug_unsafe", ] [[package]] -name = "atoi_simd" -version = "0.15.6" +name = "atomic-waker" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ae037714f313c1353189ead58ef9eec30a8e8dc101b2622d461418fd59e28a9" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "auto_impl" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" +checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "avro-schema" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "b5281855b39aba9684d2f47bf96983fbfd8f1725f12fabb0513a8ab879647bbd" +dependencies = [ + "crc 2.1.0", + "fallible-streaming-iterator", + "libflate", + "serde", + "serde_json", + "snap", +] [[package]] name = "backtrace" -version = "0.3.74" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ "addr2line", "cfg-if", @@ -963,7 +1231,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-link 0.2.0", ] [[package]] @@ -972,12 +1240,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "base64" version = "0.22.1" @@ -986,9 +1248,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "bimap" @@ -996,26 +1258,65 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "230c5f1ca6a325a32553f8640d31ac9b49f2411e901e427570154868b46da4f7" +[[package]] +name = "bincode" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740" +dependencies = [ + "bincode_derive", + "serde", + "unty", +] + +[[package]] +name = "bincode_derive" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf95709a440f45e986983918d0e8a1f30a9b1df04918fc828670606804ac3c09" +dependencies = [ + "virtue", +] + [[package]] name = "bit-set" -version = "0.5.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ "bit-vec", ] [[package]] name = "bit-vec" -version = "0.6.3" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitcoin-io" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b47c4ab7a93edb0c7198c5535ed9b52b63095f4e9b45279c6736cec4b856baf" + +[[package]] +name = "bitcoin_hashes" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" +dependencies = [ + "bitcoin-io", + "hex-conservative", +] [[package]] name = "bitflags" -version = "2.6.0" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +dependencies = [ + "serde", +] [[package]] name = "bitvec" @@ -1029,6 +1330,19 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -1040,9 +1354,9 @@ dependencies = [ [[package]] name = "blst" -version = "0.3.13" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4378725facc195f1a538864863f6de233b500a8862747e7f165078a419d5e874" +checksum = "dcdb4c7013139a150f9fc55d123186dbfaba0d912817466282c73ac49e71fb45" dependencies = [ "cc", "glob", @@ -1050,11 +1364,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "boxcar" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f64beae40a84da1b4b26ff2761a5b895c12adc41dc25aaee1c4f2bbfe97a6e" + [[package]] name = "brotli" -version = "3.5.0" +version = "8.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" +checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -1063,9 +1383,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.5.1" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -1073,34 +1393,34 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "byte-slice-cast" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" +checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" [[package]] name = "bytemuck" -version = "1.20.0" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.8.0" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] @@ -1111,18 +1431,18 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.8.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" dependencies = [ "serde", ] [[package]] name = "c-kzg" -version = "1.0.3" +version = "2.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0307f72feab3300336fb803a57134159f6e20139af1357f36c54cb90d8e8928" +checksum = "e00bf4b112b07b505472dbefd19e37e53307e2bfed5a79e0cc161d58ccd0e687" dependencies = [ "blst", "cc", @@ -1133,12 +1453,22 @@ dependencies = [ "serde", ] +[[package]] +name = "castaway" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" +dependencies = [ + "rustversion", +] + [[package]] name = "cc" -version = "1.2.1" +version = "1.2.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" +checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", @@ -1146,87 +1476,88 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.6", + "windows-link 0.2.0", ] [[package]] name = "chrono-tz" -version = "0.8.6" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59ae0466b83e838b81a54256c39d5d7c20b9d7daa10510a242d9b75abd5936e" +checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3" dependencies = [ "chrono", - "chrono-tz-build", "phf", ] [[package]] -name = "chrono-tz-build" -version = "0.2.1" +name = "clap" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433e39f13c9a060046954e0592a8d0a4bcb1040125cbf91cb8ee58964cfb350f" +checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" dependencies = [ - "parse-zoneinfo", - "phf", - "phf_codegen", + "clap_builder", + "clap_derive", ] [[package]] -name = "clap_builder_cryo" -version = "4.3.21-cryo" +name = "clap_builder" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9e3a8989ce9e79041f7681f82e669c1a06724975fb8f5b7bd60e359e572da76" +checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" dependencies = [ "anstream", "anstyle", - "clap_lex_cryo", + "clap_lex", "strsim", ] [[package]] -name = "clap_cryo" -version = "4.3.21-cryo" +name = "clap_derive" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053a8216426fdf2f5ce7fa46197e3517adf8b1c0ab96d3dbf73469bc15f34ad6" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" dependencies = [ - "clap_builder_cryo", - "clap_derive_cryo", - "once_cell", + "heck", + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] -name = "clap_derive_cryo" -version = "4.3.12" +name = "clap_lex" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd1cd2cebdb1ec98182edb745382a2b65d6bc254782de26316e4366d83d39988" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "syn 2.0.89", -] +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] -name = "clap_lex_cryo" -version = "0.5.0" +name = "clipboard-win" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98979652585ac7c8d6267e363229b6a26bc4bf469c69e96442f85830ebc89f45" +checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4" +dependencies = [ + "error-code", +] [[package]] name = "color-print" @@ -1246,61 +1577,82 @@ dependencies = [ "nom", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "colored" -version = "2.1.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" dependencies = [ - "lazy_static", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] name = "comfy-table" -version = "7.1.3" +version = "7.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24f165e7b643266ea80cb858aed492ad9280e3e05ce24d4a99d7d7b889b6a4d9" +checksum = "b03b7db8e0b4b2fdad6c551e634134e99ec000e5c8c3b6856c65e8bbaded7a3b" dependencies = [ "crossterm", - "strum", - "strum_macros 0.26.4", - "unicode-width 0.2.0", + "unicode-segmentation", + "unicode-width", +] + +[[package]] +name = "compact_str" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "rustversion", + "ryu", + "serde", + "static_assertions", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", ] [[package]] name = "console" -version = "0.15.8" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +checksum = "b430743a6eb14e9764d4260d4c0d8123087d504eeb9c48f2b2a5e810dd369df4" dependencies = [ "encode_unicode", - "lazy_static", "libc", - "unicode-width 0.1.14", - "windows-sys 0.52.0", + "once_cell", + "unicode-width", + "windows-sys 0.61.1", ] [[package]] name = "const-hex" -version = "1.13.2" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487981fa1af147182687064d0a2c336586d337a606595ced9ffb0c685c250c73" +checksum = "b6407bff74dea37e0fa3dc1c1c974e5d46405f0c987bf9997a0762adce71eda6" dependencies = [ "cfg-if", "cpufeatures", - "hex", "proptest", - "serde", + "serde_core", ] [[package]] @@ -1309,6 +1661,32 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const_format" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" +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.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + [[package]] name = "core-foundation" version = "0.9.4" @@ -1319,6 +1697,16 @@ dependencies = [ "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" @@ -1327,36 +1715,66 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49fc9a695bca7f35f5f4c15cddc84415f66a74ea78eef08e90c5024f2b540e23" +dependencies = [ + "crc-catalog 1.1.1", +] + +[[package]] +name = "crc" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" +dependencies = [ + "crc-catalog 2.4.0", +] + +[[package]] +name = "crc-catalog" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403" + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.13" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -1373,27 +1791,28 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crossterm" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" dependencies = [ "bitflags", "crossterm_winapi", + "document-features", "parking_lot", "rustix", "winapi", @@ -1410,9 +1829,9 @@ dependencies = [ [[package]] name = "crunchy" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "cryo_cli" @@ -1420,7 +1839,7 @@ version = "0.3.2" dependencies = [ "alloy", "anstyle", - "clap_cryo", + "clap", "color-print", "colored", "cryo_freeze", @@ -1429,10 +1848,12 @@ dependencies = [ "hex", "mesc", "polars", - "rand", + "rand 0.9.2", "serde", "serde_json", "tokio", + "tracing", + "tracing-subscriber", ] [[package]] @@ -1440,24 +1861,27 @@ name = "cryo_freeze" version = "0.3.2" dependencies = [ "alloy", + "alloy-transport-http", "async-trait", "chrono", "colored", "cryo_to_df", "futures", "governor", - "heck 0.4.1", - "indexmap", + "heck", + "http-body-util", + "indexmap 2.11.4", "indicatif", "mesc", "polars", - "prefix-hex", "regex", "serde", "serde_json", - "thiserror", + "thiserror 2.0.17", "thousands", "tokio", + "tower", + "tracing", "url", ] @@ -1468,8 +1892,9 @@ dependencies = [ "cryo_cli", "cryo_freeze", "polars", + "polars-python", "pyo3", - "pyo3-asyncio", + "pyo3-async-runtimes", "pyo3-build-config", "pyo3-polars", "tokio", @@ -1479,10 +1904,10 @@ dependencies = [ name = "cryo_to_df" version = "0.3.2" dependencies = [ - "indexmap", + "indexmap 2.11.4", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.106", ] [[package]] @@ -1492,7 +1917,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -1508,16 +1933,39 @@ dependencies = [ ] [[package]] -name = "dashmap" -version = "5.5.3" +name = "darling" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" dependencies = [ - "cfg-if", - "hashbrown 0.14.5", - "lock_api", - "once_cell", - "parking_lot_core", + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "serde", + "strsim", + "syn 2.0.106", +] + +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.106", ] [[package]] @@ -1536,20 +1984,36 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.6.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + +[[package]] +name = "debug_unsafe" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85d3cef41d236720ed453e102153a53e4cc3d2fde848c0078a50cf249e8e3e5b" [[package]] name = "der" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ "const-oid", "zeroize", ] +[[package]] +name = "deranged" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071" +dependencies = [ + "powerfmt", + "serde_core", +] + [[package]] name = "derivative" version = "2.2.0" @@ -1563,22 +2027,22 @@ dependencies = [ [[package]] name = "derive_more" -version = "1.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" dependencies = [ "derive_more-impl", ] [[package]] name = "derive_more-impl" -version = "1.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", "unicode-xid", ] @@ -1603,6 +2067,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "dispatch2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags", + "objc2", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -1611,7 +2085,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] @@ -1620,6 +2094,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aac81fa3e28d21450aa4d2ac065992ba96a1d7303efbce51a95f4fd175b67562" +[[package]] +name = "document-features" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +dependencies = [ + "litrs", +] + [[package]] name = "dunce" version = "1.0.5" @@ -1628,9 +2111,9 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "dyn-clone" -version = "1.0.17" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "ecdsa" @@ -1642,18 +2125,34 @@ dependencies = [ "digest 0.10.7", "elliptic-curve", "rfc6979", + "serdect", "signature", "spki", ] [[package]] -name = "either" -version = "1.13.0" +name = "educe" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "elliptic-curve" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +dependencies = [ + "serde", +] + +[[package]] +name = "elliptic-curve" version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" @@ -1665,51 +2164,87 @@ dependencies = [ "generic-array", "group", "pkcs8", - "rand_core", + "rand_core 0.6.4", "sec1", + "serdect", "subtle", "zeroize", ] [[package]] name = "encode_unicode" -version = "0.3.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] -name = "enum_dispatch" -version = "0.3.13" +name = "enum-ordinalize" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" +checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" dependencies = [ - "once_cell", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.1", ] +[[package]] +name = "error-code" +version = "3.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" + [[package]] name = "ethnum" -version = "1.5.0" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca81e6b4777c89fd810c25a4be2b1bd93ea034fbe58e6a75216a34c6b82c539b" + +[[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 = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] [[package]] name = "eyre" @@ -1728,16 +2263,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] -name = "fast-float" -version = "0.2.0" +name = "fast-float2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95765f67b4b18863968b4a1bd5bb576f732b29a4a28c7cd84c09fa3e2875f33c" +checksum = "f8eb564c5c7423d25c886fb561d1e4ee69f72354d16918afa32c08811f6b6a55" [[package]] name = "fastrand" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fastrlp" @@ -1750,16 +2285,33 @@ dependencies = [ "bytes", ] +[[package]] +name = "fastrlp" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce8dba4714ef14b8274c371879b175aa55b16b30f269663f19d576f380018dc4" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + [[package]] name = "ff" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ - "rand_core", + "rand_core 0.6.4", "subtle", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3" + [[package]] name = "fixed-hash" version = "0.8.0" @@ -1767,26 +2319,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ "byteorder", - "rand", + "rand 0.8.5", "rustc-hex", "static_assertions", ] [[package]] name = "flate2" -version = "1.0.35" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +checksum = "04bcaeafafdd3cd1cb5d986ff32096ad1136630207c49b9091e3ae541090d938" dependencies = [ "crc32fast", + "libz-rs-sys", "miniz_oxide", ] [[package]] name = "float-cmp" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8" dependencies = [ "num-traits", ] @@ -1799,9 +2352,15 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.3" +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 = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "foreign-types" @@ -1819,18 +2378,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] -name = "foreign_vec" -version = "0.1.0" +name = "form_urlencoded" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee1b05cbd864bcaecbd3455d6d967862d446e4ebfc3c2e5e5b9841e53cba6673" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] [[package]] -name = "form_urlencoded" -version = "1.2.1" +name = "fs4" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "8640e34b88f7652208ce9e88b1a37a2ae95227d84abec377ccd3c5cfeb141ed4" dependencies = [ - "percent-encoding", + "rustix", + "windows-sys 0.59.0", ] [[package]] @@ -1895,7 +2458,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] @@ -1951,49 +2514,76 @@ dependencies = [ "zeroize", ] +[[package]] +name = "gethostname" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc257fdb4038301ce4b9cd1b3b51704509692bb3ff716a410cbd07925d9dae55" +dependencies = [ + "rustix", + "windows-targets 0.52.6", +] + [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "r-efi", + "wasi 0.14.7+wasi-0.2.4", "wasm-bindgen", ] [[package]] name = "gimli" -version = "0.31.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "glob" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "governor" -version = "0.6.3" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" +checksum = "444405bbb1a762387aa22dd569429533b54a1d8759d35d3b64cb39b0293eaa19" dependencies = [ "cfg-if", - "dashmap 5.5.3", - "futures", + "dashmap", + "futures-sink", "futures-timer", - "no-std-compat", + "futures-util", + "getrandom 0.3.3", + "hashbrown 0.15.5", "nonzero_ext", "parking_lot", "portable-atomic", "quanta", - "rand", + "rand 0.9.2", "smallvec", "spinning_top", + "web-time", ] [[package]] @@ -2003,54 +2593,73 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", - "rand_core", + "rand_core 0.6.4", "subtle", ] +[[package]] +name = "h2" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap 2.11.4", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "halfbrown" -version = "0.2.5" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8588661a8607108a5ca69cab034063441a0413a0b041c13618a7dd348021ef6f" +checksum = "aa2c385c6df70fd180bbb673d93039dbd2cd34e41d782600bdf6e1ca7bce39aa" dependencies = [ - "hashbrown 0.14.5", + "hashbrown 0.15.5", "serde", ] [[package]] name = "hashbrown" -version = "0.13.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", - "allocator-api2", - "rayon", -] [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "equivalent", - "foldhash", + "foldhash 0.1.5", + "rayon", "serde", ] [[package]] -name = "heck" -version = "0.4.1" +name = "hashbrown" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +dependencies = [ + "foldhash 0.2.0", + "serde", +] [[package]] name = "heck" @@ -2060,30 +2669,24 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.4.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -dependencies = [ - "serde", -] [[package]] -name = "hex-literal" -version = "0.4.1" +name = "hex-conservative" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" +checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" +dependencies = [ + "arrayvec", +] [[package]] name = "hmac" @@ -2096,18 +2699,18 @@ dependencies = [ [[package]] name = "home" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "http" -version = "1.1.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ "bytes", "fnv", @@ -2126,12 +2729,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", - "futures-util", + "futures-core", "http", "http-body", "pin-project-lite", @@ -2139,29 +2742,63 @@ dependencies = [ [[package]] name = "httparse" -version = "1.9.5" +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 = "humantime" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" +checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" [[package]] name = "hyper" -version = "1.5.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" +checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" dependencies = [ + "atomic-waker", "bytes", "futures-channel", - "futures-util", + "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-native-certs", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots 1.0.2", +] + [[package]] name = "hyper-tls" version = "0.6.0" @@ -2180,33 +2817,41 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.10" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" dependencies = [ + "base64", "bytes", "futures-channel", + "futures-core", "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.61" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", "windows-core", ] @@ -2222,21 +2867,22 @@ dependencies = [ [[package]] name = "icu_collections" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" dependencies = [ "displaydoc", + "potential_utf", "yoke", "zerofrom", "zerovec", ] [[package]] -name = "icu_locid" -version = "1.5.0" +name = "icu_locale_core" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" dependencies = [ "displaydoc", "litemap", @@ -2245,31 +2891,11 @@ dependencies = [ "zerovec", ] -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" - [[package]] name = "icu_normalizer" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" dependencies = [ "displaydoc", "icu_collections", @@ -2277,72 +2903,65 @@ dependencies = [ "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "utf8_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" [[package]] name = "icu_properties" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" dependencies = [ "displaydoc", "icu_collections", - "icu_locid_transform", + "icu_locale_core", "icu_properties_data", "icu_provider", - "tinystr", + "potential_utf", + "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "1.5.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" [[package]] name = "icu_provider" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" dependencies = [ "displaydoc", - "icu_locid", - "icu_provider_macros", + "icu_locale_core", "stable_deref_trait", "tinystr", "writeable", "yoke", "zerofrom", + "zerotrie", "zerovec", ] [[package]] -name = "icu_provider_macros" -version = "1.5.0" +name = "ident_case" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.89", -] +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -2351,9 +2970,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -2376,50 +2995,62 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] name = "indenter" -version = "0.3.3" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" + +[[package]] +name = "indexmap" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] [[package]] name = "indexmap" -version = "2.6.0" +version = "2.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "equivalent", - "hashbrown 0.15.2", + "hashbrown 0.16.0", "serde", + "serde_core", ] [[package]] name = "indicatif" -version = "0.17.9" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf675b85ed934d3c67b5c5469701eec7db22689d0a2139d856e0925fa28b281" +checksum = "70a646d946d06bedbbc4cac4c218acf4bbf2d87757a784857025f4d447e4e1cd" dependencies = [ "console", - "number_prefix", "portable-atomic", - "unicode-width 0.2.0", + "unicode-width", + "unit-prefix", "web-time", ] [[package]] name = "indoc" -version = "2.0.5" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" +checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" [[package]] name = "interprocess" -version = "2.2.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "894148491d817cb36b6f778017b8ac46b17408d522dd90f539d677ea938362eb" +checksum = "d941b405bd2322993887859a8ee6ac9134945a24ec5ec763a8a962fc64dfec2d" dependencies = [ "doctest-file", "futures-core", @@ -2431,30 +3062,55 @@ dependencies = [ ] [[package]] -name = "ipnet" -version = "2.10.1" +name = "inventory" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" +checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e" +dependencies = [ + "rustversion", +] [[package]] -name = "is-terminal" -version = "0.4.13" +name = "io-uring" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" dependencies = [ - "hermit-abi 0.4.0", + "bitflags", + "cfg-if", "libc", - "windows-sys 0.52.0", ] [[package]] -name = "itertools" -version = "0.10.5" +name = "ipnet" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] [[package]] name = "itertools" @@ -2466,32 +3122,37 @@ dependencies = [ ] [[package]] -name = "itoa" -version = "1.0.14" +name = "itertools" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] [[package]] -name = "itoap" -version = "1.0.1" +name = "itoa" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9028f49264629065d057f340a86acb84867925865f73bbf8d47b4d149a7e88b8" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jobserver" -version = "0.1.32" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ + "getrandom 0.3.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -2506,6 +3167,21 @@ dependencies = [ "serde_json", ] +[[package]] +name = "jsonwebtoken" +version = "9.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" +dependencies = [ + "base64", + "js-sys", + "pem", + "ring", + "serde", + "serde_json", + "simple_asn1", +] + [[package]] name = "k256" version = "0.13.4" @@ -2516,6 +3192,7 @@ dependencies = [ "ecdsa", "elliptic-curve", "once_cell", + "serdect", "sha2", ] @@ -2545,123 +3222,119 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] -name = "lexical-core" -version = "1.0.2" +name = "libc" +version = "0.2.176" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0431c65b318a590c1de6b8fd6e72798c92291d27762d94c9e6c37ed7a73d8458" -dependencies = [ - "lexical-parse-float", - "lexical-parse-integer", - "lexical-util", - "lexical-write-float", - "lexical-write-integer", -] +checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" [[package]] -name = "lexical-parse-float" -version = "1.0.2" +name = "libflate" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb17a4bdb9b418051aa59d41d65b1c9be5affab314a872e5ad7f06231fb3b4e0" +checksum = "5ff4ae71b685bbad2f2f391fe74f6b7659a34871c08b210fdc039e43bee07d18" dependencies = [ - "lexical-parse-integer", - "lexical-util", - "static_assertions", + "adler32", + "crc32fast", + "libflate_lz77", ] [[package]] -name = "lexical-parse-integer" -version = "1.0.2" +name = "libflate_lz77" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5df98f4a4ab53bf8b175b363a34c7af608fe31f93cc1fb1bf07130622ca4ef61" +checksum = "a52d3a8bfc85f250440e4424db7d857e241a3aebbbe301f3eb606ab15c39acbf" dependencies = [ - "lexical-util", - "static_assertions", + "rle-decode-fast", ] [[package]] -name = "lexical-util" -version = "1.0.3" +name = "libloading" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85314db53332e5c192b6bca611fb10c114a80d1b831ddac0af1e9be1b9232ca0" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ - "static_assertions", + "cfg-if", + "windows-link 0.2.0", ] [[package]] -name = "lexical-write-float" -version = "1.0.2" +name = "libm" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e7c3ad4e37db81c1cbe7cf34610340adc09c322871972f74877a712abc6c809" -dependencies = [ - "lexical-util", - "lexical-write-integer", - "static_assertions", -] +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] -name = "lexical-write-integer" -version = "1.0.2" +name = "libmimalloc-sys" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb89e9f6958b83258afa3deed90b5de9ef68eef090ad5086c791cd2345610162" +checksum = "667f4fec20f29dfc6bc7357c582d91796c169ad7e2fce709468aefeb2c099870" dependencies = [ - "lexical-util", - "static_assertions", + "cc", + "libc", ] [[package]] -name = "libc" -version = "0.2.165" +name = "libz-rs-sys" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb4d3d38eab6c5239a362fa8bae48c03baf980a6e7079f063942d563ef3533e" +checksum = "840db8cf39d9ec4dd794376f38acc40d0fc65eec2a8f484f7fd375b84602becd" +dependencies = [ + "zlib-rs", +] [[package]] -name = "libm" -version = "0.2.11" +name = "linux-raw-sys" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] -name = "linux-raw-sys" -version = "0.4.14" +name = "litemap" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] -name = "litemap" -version = "0.7.4" +name = "litrs" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" +checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.22" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "lru" -version = "0.12.5" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465" dependencies = [ - "hashbrown 0.15.2", + "hashbrown 0.15.5", ] +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "lz4" -version = "1.28.0" +version = "1.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d1febb2b4a79ddd1980eede06a8f7902197960aa0383ffcfdd62fe723036725" +checksum = "a20b523e860d03443e98350ceaac5e71c6ba89aea7d960769ec3ce37f4de5af4" dependencies = [ "lz4-sys", ] @@ -2676,17 +3349,48 @@ dependencies = [ "libc", ] +[[package]] +name = "macro-string" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "matrixmultiply" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08" +dependencies = [ + "autocfg", + "rawpointer", +] + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest 0.10.7", +] + [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memmap2" -version = "0.7.1" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" +checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7" dependencies = [ "libc", ] @@ -2702,20 +3406,23 @@ dependencies = [ [[package]] name = "mesc" -version = "0.1.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4effaaca264c057c870afd19cf7137ef000ca64fc7292d5a0634ce5ebbb6e27" +checksum = "d04b0347d2799ef17df4623dbcb03531031142105168e0c549e0bf1f980e9e7e" dependencies = [ "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] -name = "mime" -version = "0.3.17" +name = "mimalloc" +version = "0.1.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +checksum = "e1ee66a4b64c74f4ef288bcbb9192ad9c3feaad75193129ac8509af543894fd8" +dependencies = [ + "libmimalloc-sys", +] [[package]] name = "minimal-lexical" @@ -2725,52 +3432,30 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.0" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] name = "mio" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ - "hermit-abi 0.3.9", "libc", - "wasi", - "windows-sys 0.52.0", -] - -[[package]] -name = "multiversion" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4851161a11d3ad0bf9402d90ffc3967bf231768bfd7aeb61755ad06dbf1a142" -dependencies = [ - "multiversion-macros", - "target-features", -] - -[[package]] -name = "multiversion-macros" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79a74ddee9e0c27d2578323c13905793e91622148f138ba29738f9dddb835e90" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "target-features", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", ] [[package]] name = "native-tls" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" dependencies = [ "libc", "log", @@ -2778,16 +3463,25 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "security-framework", + "security-framework 2.11.1", "security-framework-sys", "tempfile", ] [[package]] -name = "no-std-compat" -version = "0.4.1" +name = "ndarray" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" +checksum = "882ed72dce9365842bf196bdeedf5055305f11fc8c03dee7bb0194a6cad34841" +dependencies = [ + "matrixmultiply", + "num-complex", + "num-integer", + "num-traits", + "portable-atomic", + "portable-atomic-util", + "rawpointer", +] [[package]] name = "nom" @@ -2815,12 +3509,12 @@ dependencies = [ ] [[package]] -name = "ntapi" -version = "0.4.1" +name = "nu-ansi-term" +version = "0.50.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -2833,6 +3527,21 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" version = "0.1.46" @@ -2854,60 +3563,202 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi", "libc", ] [[package]] name = "num_enum" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" dependencies = [ "num_enum_derive", + "rustversion", ] [[package]] name = "num_enum_derive" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] -name = "number_prefix" -version = "0.4.0" +name = "numpy" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29f1dee9aa8d3f6f8e8b9af3803006101bb3653866ef056d530d53ae68587191" +dependencies = [ + "libc", + "ndarray", + "num-complex", + "num-integer", + "num-traits", + "pyo3", + "pyo3-build-config", + "rustc-hash", +] + +[[package]] +name = "nybbles" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4b5ecbd0beec843101bffe848217f770e8b8da81d8355b7d6e226f2199b3dc" +dependencies = [ + "alloy-rlp", + "cfg-if", + "proptest", + "ruint", + "serde", + "smallvec", +] + +[[package]] +name = "objc2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-app-kit" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" +dependencies = [ + "bitflags", + "objc2", + "objc2-core-graphics", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags", + "dispatch2", + "objc2", +] + +[[package]] +name = "objc2-core-graphics" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" +dependencies = [ + "bitflags", + "dispatch2", + "objc2", + "objc2-core-foundation", + "objc2-io-surface", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "bitflags", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-surface" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" +dependencies = [ + "bitflags", + "objc2", + "objc2-core-foundation", +] [[package]] name = "object" -version = "0.36.5" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "memchr", ] +[[package]] +name = "object_store" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c1be0c6c22ec0817cdc77d3842f721a17fd30ab6965001415b5402a74e6b740" +dependencies = [ + "async-trait", + "base64", + "bytes", + "chrono", + "form_urlencoded", + "futures", + "http", + "http-body-util", + "httparse", + "humantime", + "hyper", + "itertools 0.14.0", + "md-5", + "parking_lot", + "percent-encoding", + "quick-xml", + "rand 0.9.2", + "reqwest", + "ring", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "thiserror 2.0.17", + "tokio", + "tracing", + "url", + "walkdir", + "wasm-bindgen-futures", + "web-time", +] + [[package]] name = "once_cell" -version = "1.20.2" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" [[package]] name = "openssl" -version = "0.10.68" +version = "0.10.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ "bitflags", "cfg-if", @@ -2926,20 +3777,20 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] name = "openssl-probe" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.104" +version = "0.9.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" dependencies = [ "cc", "libc", @@ -2949,13 +3800,14 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.7.0" +version = "3.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be4817d39f3272f69c59fe05d0535ae6456c2dc2fa1ba02910296c7e0a5c590" +checksum = "799781ae679d79a948e13d4824a40970bfa500058d245760dd857301059810fa" dependencies = [ "arrayvec", "bitvec", "byte-slice-cast", + "const_format", "impl-trait-for-tuples", "parity-scale-codec-derive", "rustversion", @@ -2964,21 +3816,27 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.7.0" +version = "3.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8781a75c6205af67215f382092b6e0a4ff3734798523e69073d4bcd294ec767b" +checksum = "34b4653168b563151153c9e4c08ebed57fb8262bebfa79711552fa983c623e7a" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -2986,56 +3844,46 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-link 0.2.0", ] [[package]] -name = "parquet-format-safe" -version = "0.2.4" +name = "paste" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1131c54b167dd4e4799ce762e1ab01549ebb94d5bdd13e6ec1b467491c378e1f" -dependencies = [ - "async-trait", - "futures", -] +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] -name = "parse-zoneinfo" -version = "0.3.1" +name = "pem" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24" +checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" dependencies = [ - "regex", + "base64", + "serde", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.7.14" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" +checksum = "989e7521a040efde50c3ab6bbadafbe15ab6dc042686926be59ac35d74607df4" dependencies = [ "memchr", - "thiserror", "ucd-trie", ] @@ -3051,67 +3899,47 @@ dependencies = [ [[package]] name = "phf" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" -dependencies = [ - "phf_shared", -] - -[[package]] -name = "phf_codegen" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" -dependencies = [ - "phf_generator", - "phf_shared", -] - -[[package]] -name = "phf_generator" -version = "0.11.2" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" dependencies = [ "phf_shared", - "rand", ] [[package]] name = "phf_shared" -version = "0.11.2" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" dependencies = [ "siphasher", ] [[package]] name = "pin-project" -version = "1.1.7" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.7" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] name = "pin-project-lite" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -3131,26 +3959,28 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "planus" -version = "0.3.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1691dd09e82f428ce8d6310bd6d5da2557c82ff17694d2a32cad7242aea89f" +checksum = "3daf8e3d4b712abe1d690838f6e29fb76b76ea19589c4afa39ec30e12f62af71" dependencies = [ "array-init-cursor", + "hashbrown 0.15.5", ] [[package]] name = "polars" -version = "0.38.3" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f01006048a264047d6cba081fed8e11adbd69c15956f9e53185a9ac4a541853c" +checksum = "a5f7feb5d56b954e691dff22a8b2d78d77433dcc93c35fe21c3777fdc121b697" dependencies = [ - "getrandom", + "getrandom 0.2.16", + "getrandom 0.3.3", "polars-arrow", "polars-core", "polars-error", @@ -3158,6 +3988,7 @@ dependencies = [ "polars-lazy", "polars-ops", "polars-parquet", + "polars-plan", "polars-sql", "polars-time", "polars-utils", @@ -3166,45 +3997,42 @@ dependencies = [ [[package]] name = "polars-arrow" -version = "0.38.3" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25197f40d71f82b2f79bb394f03e555d3cc1ce4db1dd052c28318721c71e96ad" +checksum = "32b4fed2343961b3eea3db2cee165540c3e1ad9d5782350cc55a9e76cf440148" dependencies = [ - "ahash", - "atoi", "atoi_simd", + "avro-schema", + "bitflags", "bytemuck", "chrono", "chrono-tz", "dyn-clone", "either", "ethnum", - "fast-float", - "foreign_vec", - "futures", - "getrandom", - "hashbrown 0.14.5", + "getrandom 0.2.16", + "getrandom 0.3.3", + "hashbrown 0.15.5", "itoa", - "itoap", "lz4", - "multiversion", "num-traits", "polars-arrow-format", "polars-error", + "polars-schema", "polars-utils", - "ryu", + "serde", "simdutf8", "streaming-iterator", - "strength_reduce", + "strum_macros", "version_check", "zstd", ] [[package]] name = "polars-arrow-format" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b0ef2474af9396b19025b189d96e992311e6a47f90c53cd998b36c4c64b84c" +checksum = "a556ac0ee744e61e167f34c1eb0013ce740e0ee6cd8c158b2ec0b518f10e6675" dependencies = [ "planus", "serde", @@ -3212,116 +4040,194 @@ dependencies = [ [[package]] name = "polars-compute" -version = "0.38.3" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c354515f73cdbbad03c2bf723fcd68e6825943b3ec503055abc8a8cb08ce46bb" +checksum = "138785beda4e4a90a025219f09d0d15a671b2be9091513ede58e05db6ad4413f" dependencies = [ + "atoi_simd", "bytemuck", + "chrono", "either", + "fast-float2", + "hashbrown 0.15.5", + "itoa", "num-traits", "polars-arrow", "polars-error", "polars-utils", + "rand 0.9.2", + "ryu", + "serde", + "skiplist", "strength_reduce", + "strum_macros", "version_check", ] [[package]] name = "polars-core" -version = "0.38.3" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f20d3c227186f74aa3c228c64ef72f5a15617322fed30b4323eaf53b25f8e7b" +checksum = "e77b1f08ef6dbb032bb1d0d3365464be950df9905f6827a95b24c4ca5518901d" dependencies = [ - "ahash", "bitflags", + "boxcar", "bytemuck", "chrono", "chrono-tz", "comfy-table", "either", - "hashbrown 0.14.5", - "indexmap", + "hashbrown 0.15.5", + "indexmap 2.11.4", + "itoa", + "ndarray", "num-traits", - "once_cell", "polars-arrow", "polars-compute", + "polars-dtype", "polars-error", "polars-row", + "polars-schema", "polars-utils", - "rand", + "rand 0.9.2", "rand_distr", "rayon", "regex", - "smartstring", - "thiserror", + "serde", + "serde_json", + "strum_macros", + "uuid", "version_check", "xxhash-rust", ] +[[package]] +name = "polars-dtype" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89c43d0ea57168be4546c4d8064479ed8b29a9c79c31a0c7c367ee734b9b7158" +dependencies = [ + "boxcar", + "hashbrown 0.15.5", + "polars-arrow", + "polars-error", + "polars-utils", + "serde", + "uuid", +] + [[package]] name = "polars-error" -version = "0.38.3" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dd0ce51f8bd620eb8bd376502fe68a2b1a446d5433ecd2e75270b0755ce76" +checksum = "b9cb5d98f59f8b94673ee391840440ad9f0d2170afced95fc98aa86f895563c0" dependencies = [ + "avro-schema", + "object_store", + "parking_lot", "polars-arrow-format", + "pyo3", "regex", + "signal-hook", "simdutf8", - "thiserror", +] + +[[package]] +name = "polars-expr" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343931b818cf136349135ba11dbc18c27683b52c3477b1ba8ca606cf5ab1965c" +dependencies = [ + "bitflags", + "hashbrown 0.15.5", + "num-traits", + "polars-arrow", + "polars-compute", + "polars-core", + "polars-io", + "polars-ops", + "polars-plan", + "polars-row", + "polars-time", + "polars-utils", + "rand 0.9.2", + "rayon", + "recursive", +] + +[[package]] +name = "polars-ffi" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36290608e6afed321123e85881116232c29b53e85d73c09448cf5e0fd74c1566" +dependencies = [ + "polars-arrow", + "polars-core", ] [[package]] name = "polars-io" -version = "0.38.3" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b40bef2edcdc58394792c4d779465144283a09ff1836324e7b72df7978a6e992" +checksum = "10388c64b8155122488229a881d1c6f4fdc393bc988e764ab51b182fcb2307e4" dependencies = [ - "ahash", "async-trait", "atoi_simd", + "blake3", "bytes", "chrono", - "fast-float", + "chrono-tz", + "fast-float2", + "flate2", + "fs4", "futures", + "glob", + "hashbrown 0.15.5", "home", "itoa", "memchr", "memmap2", "num-traits", - "once_cell", + "object_store", "percent-encoding", "polars-arrow", "polars-core", "polars-error", "polars-json", "polars-parquet", + "polars-schema", "polars-time", "polars-utils", + "pyo3", "rayon", "regex", + "reqwest", "ryu", + "serde", "serde_json", "simd-json", "simdutf8", - "smartstring", "tokio", "tokio-util", + "url", + "zstd", ] [[package]] name = "polars-json" -version = "0.38.3" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef86aca08f10ddc939fe95aabb44e1d2582dcb08b55d4dadb93353ce42adc248" +checksum = "b26d1a04292a82183c8eba94fdf1584f200bfac5ac2f4a6c5652c8c8ed3bb41c" dependencies = [ - "ahash", "chrono", + "chrono-tz", "fallible-streaming-iterator", - "hashbrown 0.14.5", - "indexmap", + "hashbrown 0.15.5", + "indexmap 2.11.4", "itoa", "num-traits", "polars-arrow", + "polars-compute", "polars-error", "polars-utils", "ryu", @@ -3331,45 +4237,75 @@ dependencies = [ [[package]] name = "polars-lazy" -version = "0.38.3" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c27df26a19d3092298d31d47614ad84dc330c106e38aa8cd53727cd91c07cf56" +checksum = "0fb6e2c6c2fa4ea0c660df1c06cf56960c81e7c2683877995bae3d4e3d408147" dependencies = [ - "ahash", "bitflags", - "glob", - "once_cell", + "chrono", + "either", + "futures", + "memchr", "polars-arrow", + "polars-compute", "polars-core", + "polars-expr", "polars-io", "polars-json", + "polars-mem-engine", "polars-ops", - "polars-pipe", "polars-plan", + "polars-stream", "polars-time", "polars-utils", + "pyo3", "rayon", - "smartstring", + "tokio", "version_check", ] +[[package]] +name = "polars-mem-engine" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20a856e98e253587c28d8132a5e7e5a75cb2c44731ca090f1481d45f1d123771" +dependencies = [ + "futures", + "memmap2", + "polars-arrow", + "polars-core", + "polars-error", + "polars-expr", + "polars-io", + "polars-json", + "polars-ops", + "polars-plan", + "polars-time", + "polars-utils", + "pyo3", + "rayon", + "recursive", + "tokio", +] + [[package]] name = "polars-ops" -version = "0.38.3" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f8a51c3bdc9e7c34196ff6f5c3cb17da134e5aafb1756aaf24b76c7118e63dc" +checksum = "acf6062173fdc9ba05775548beb66e76643a148d9aeadc9984ed712bc4babd76" dependencies = [ - "ahash", + "aho-corasick", "argminmax", - "base64 0.21.7", + "base64", "bytemuck", "chrono", "chrono-tz", "either", - "hashbrown 0.14.5", + "hashbrown 0.15.5", "hex", - "indexmap", + "indexmap 2.11.4", "jsonpath_lib_polars_vendor", + "libm", "memchr", "num-traits", "polars-arrow", @@ -3377,35 +4313,43 @@ dependencies = [ "polars-core", "polars-error", "polars-json", + "polars-schema", "polars-utils", + "rand 0.9.2", + "rand_distr", "rayon", "regex", + "regex-syntax", + "serde", "serde_json", - "smartstring", + "strum_macros", + "unicode-normalization", "unicode-reverse", "version_check", ] [[package]] name = "polars-parquet" -version = "0.38.3" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8824ee00fbbe83d69553f2711014c50361238d210ed81a7a297695b7db97d42" +checksum = "cc1d769180dec070df0dc4b89299b364bf2cfe32b218ecc4ddd8f1a49ae60669" dependencies = [ - "ahash", "async-stream", - "base64 0.21.7", + "base64", "brotli", + "bytemuck", "ethnum", "flate2", "futures", + "hashbrown 0.15.5", "lz4", "num-traits", - "parquet-format-safe", "polars-arrow", + "polars-compute", "polars-error", + "polars-parquet-format", "polars-utils", - "seq-macro", + "serde", "simdutf8", "snap", "streaming-decompression", @@ -3413,148 +4357,295 @@ dependencies = [ ] [[package]] -name = "polars-pipe" -version = "0.38.3" +name = "polars-parquet-format" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c5e2c1f14e81d60cfa9afe4e611a9bad9631a2cb7cd19b7c0094d0dc32f0231" +checksum = "c025243dcfe8dbc57e94d9f82eb3bef10b565ab180d5b99bed87fd8aea319ce1" dependencies = [ - "crossbeam-channel", - "crossbeam-queue", - "enum_dispatch", - "hashbrown 0.14.5", + "async-trait", + "futures", +] + +[[package]] +name = "polars-plan" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd3a2e33ae4484fe407ab2d2ba5684f0889d1ccf3ad6b844103c03638e6d0a0" +dependencies = [ + "bitflags", + "bytemuck", + "bytes", + "chrono", + "chrono-tz", + "either", + "futures", + "hashbrown 0.15.5", + "libloading", + "memmap2", "num-traits", + "percent-encoding", "polars-arrow", "polars-compute", "polars-core", + "polars-error", + "polars-ffi", "polars-io", + "polars-json", "polars-ops", - "polars-plan", - "polars-row", + "polars-parquet", + "polars-time", "polars-utils", + "pyo3", "rayon", - "smartstring", - "uuid", + "recursive", + "regex", + "serde", + "sha2", + "strum_macros", "version_check", ] [[package]] -name = "polars-plan" -version = "0.38.3" +name = "polars-python" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff48362bd1b078bbbec7e7ba9ec01fea58fee2887db22a8e3deaf78f322fa3c4" +checksum = "640c4d87cce063ff8ffacb659960f81cbfc1c41e7706e10bf7238bd0585037ea" dependencies = [ - "ahash", + "arboard", + "bincode", "bytemuck", + "bytes", + "chrono", "chrono-tz", - "once_cell", - "percent-encoding", + "either", + "flate2", + "hashbrown 0.15.5", + "itoa", + "libc", + "mimalloc", + "ndarray", + "num-traits", + "numpy", + "parking_lot", + "polars", "polars-arrow", + "polars-compute", "polars-core", + "polars-dtype", + "polars-error", + "polars-expr", + "polars-ffi", "polars-io", - "polars-json", + "polars-lazy", + "polars-mem-engine", "polars-ops", "polars-parquet", + "polars-plan", + "polars-row", + "polars-testing", "polars-time", "polars-utils", + "pyo3", "rayon", - "regex", - "smartstring", - "strum_macros 0.25.3", + "recursive", + "serde_json", + "tikv-jemallocator", "version_check", ] [[package]] -name = "polars-row" -version = "0.38.3" +name = "polars-row" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18734f17e0e348724df3ae65f3ee744c681117c04b041cac969dfceb05edabc0" +dependencies = [ + "bitflags", + "bytemuck", + "polars-arrow", + "polars-compute", + "polars-dtype", + "polars-error", + "polars-utils", +] + +[[package]] +name = "polars-schema" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63029da56ff6a720b190490bbc7b6263f9b72d1134311b1f381fc8d306d37770" +checksum = "8e6c1ab13e04d5167661a9854ed1ea0482b2ed9b8a0f1118dabed7cd994a85e3" dependencies = [ - "bytemuck", - "polars-arrow", + "indexmap 2.11.4", "polars-error", "polars-utils", + "serde", + "version_check", ] [[package]] name = "polars-sql" -version = "0.38.3" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3652c362959f608d1297196b973d1e3acb508a9562b886ac39bf7606b841052b" +checksum = "c4e7766da02cc1d464994404d3e88a7a0ccd4933df3627c325480fbd9bbc0a11" dependencies = [ + "bitflags", "hex", - "polars-arrow", "polars-core", "polars-error", "polars-lazy", + "polars-ops", "polars-plan", - "rand", + "polars-time", + "polars-utils", + "rand 0.9.2", + "regex", "serde", - "serde_json", "sqlparser", ] +[[package]] +name = "polars-stream" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f6c6ca1ea01f9dea424d167e4f33f5ec44cd67fbfac9efd40575ed20521f14" +dependencies = [ + "async-channel", + "async-trait", + "atomic-waker", + "bitflags", + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-queue", + "crossbeam-utils", + "futures", + "memmap2", + "parking_lot", + "percent-encoding", + "pin-project-lite", + "polars-arrow", + "polars-core", + "polars-error", + "polars-expr", + "polars-io", + "polars-mem-engine", + "polars-ops", + "polars-parquet", + "polars-plan", + "polars-utils", + "pyo3", + "rand 0.9.2", + "rayon", + "recursive", + "slotmap", + "tokio", + "tokio-util", + "version_check", +] + +[[package]] +name = "polars-testing" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac634a5457c2287ccb4e546a88445816be728a12ea4f60c5b686d67eb5c90bb6" +dependencies = [ + "polars-core", + "polars-ops", +] + [[package]] name = "polars-time" -version = "0.38.3" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86eb74ea6ddfe675aa5c3f33c00dadbe2b85f0e8e3887b85db1fd5a3397267fd" +checksum = "f6a3a6e279a7a984a0b83715660f9e880590c6129ec2104396bfa710bcd76dee" dependencies = [ - "atoi", + "atoi_simd", + "bytemuck", "chrono", "chrono-tz", "now", - "once_cell", + "num-traits", "polars-arrow", + "polars-compute", "polars-core", "polars-error", "polars-ops", "polars-utils", + "rayon", "regex", - "smartstring", + "serde", + "strum_macros", ] [[package]] name = "polars-utils" -version = "0.38.3" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "694656a7d2b0cd8f07660dbc8d0fb7a81066ff57a452264907531d805c1e58c4" +checksum = "57b267021b0e5422d7fbc70fd79e51b9f9a8466c585779373a18b0199e973f29" dependencies = [ - "ahash", + "bincode", "bytemuck", - "hashbrown 0.14.5", - "indexmap", + "bytes", + "compact_str", + "either", + "flate2", + "foldhash 0.1.5", + "hashbrown 0.15.5", + "indexmap 2.11.4", + "libc", + "memmap2", "num-traits", - "once_cell", "polars-error", + "pyo3", + "rand 0.9.2", "raw-cpuid", "rayon", - "smartstring", - "sysinfo", + "regex", + "rmp-serde", + "serde", + "serde_json", + "serde_stacker", + "slotmap", + "stacker", + "uuid", "version_check", ] [[package]] name = "portable-atomic" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] -name = "ppv-lite86" -version = "0.2.20" +name = "portable-atomic-util" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" dependencies = [ - "zerocopy", + "portable-atomic", ] [[package]] -name = "prefix-hex" -version = "0.7.1" +name = "potential_utf" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f1799f398371ad6957951ec446d3ff322d35c46d9db2e217b67e828b311c249" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" dependencies = [ - "hex", + "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]] @@ -3570,9 +4661,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.2.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ "toml_edit", ] @@ -3596,31 +4687,31 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] [[package]] name = "proptest" -version = "1.5.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" +checksum = "2bb0be07becd10686a0bb407298fb425360a5c44a663774406340c59a22de4ce" dependencies = [ "bit-set", "bit-vec", "bitflags", "lazy_static", "num-traits", - "rand", - "rand_chacha", + "rand 0.9.2", + "rand_chacha 0.9.0", "rand_xorshift", "regex-syntax", "rusty-fork", @@ -3628,17 +4719,28 @@ dependencies = [ "unarray", ] +[[package]] +name = "psm" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e66fcd288453b748497d8fb18bccc83a16b0518e3906d4b8df0a8d42d93dbb1c" +dependencies = [ + "cc", +] + [[package]] name = "pyo3" -version = "0.20.3" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53bdbb96d49157e65d45cc287af5f32ffadd5f4761438b527b055fb0d4bb8233" +checksum = "8970a78afe0628a3e3430376fc5fd76b6b45c4d43360ffd6cdd40bdde72b682a" dependencies = [ - "cfg-if", + "chrono", + "chrono-tz", "indoc", + "inventory", "libc", "memoffset", - "parking_lot", + "once_cell", "portable-atomic", "pyo3-build-config", "pyo3-ffi", @@ -3647,10 +4749,10 @@ dependencies = [ ] [[package]] -name = "pyo3-asyncio" -version = "0.20.0" +name = "pyo3-async-runtimes" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea6b68e93db3622f3bb3bf363246cf948ed5375afe7abff98ccbdd50b184995" +checksum = "d73cc6b1b7d8b3cef02101d37390dbdfe7e450dfea14921cae80a9534ba59ef2" dependencies = [ "futures", "once_cell", @@ -3661,9 +4763,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.20.3" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deaa5745de3f5231ce10517a1f5dd97d53e5a2fd77aa6b5842292085831d48d7" +checksum = "458eb0c55e7ece017adeba38f2248ff3ac615e53660d7c71a238d7d2a01c7598" dependencies = [ "once_cell", "target-lexicon", @@ -3671,9 +4773,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.20.3" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b42531d03e08d4ef1f6e85a2ed422eb678b8cd62b762e53891c05faf0d4afa" +checksum = "7114fe5457c61b276ab77c5055f206295b812608083644a5c5b2640c3102565c" dependencies = [ "libc", "pyo3-build-config", @@ -3681,52 +4783,56 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.20.3" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7305c720fa01b8055ec95e484a6eca7a83c841267f0dd5280f0c8b8551d2c158" +checksum = "a8725c0a622b374d6cb051d11a0983786448f7785336139c3c94f5aa6bef7e50" dependencies = [ "proc-macro2", "pyo3-macros-backend", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] name = "pyo3-macros-backend" -version = "0.20.3" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c7e9b68bb9c3149c5b0cade5d07f953d6d125eb4337723c4ccdb665f1f96185" +checksum = "4109984c22491085343c05b0dbc54ddc405c3cf7b4374fc533f5c3313a572ccc" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "pyo3-build-config", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] name = "pyo3-polars" -version = "0.12.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6ab8ad08494161085fb0d2d9de82c7fde7398da1778ee7e7a5a596ff4201f5b" +checksum = "64e7954e98cb5af21afca4b68c73d2e00035b07b06dc2cab9355e99d03d09557" dependencies = [ + "libc", + "once_cell", "polars", + "polars-arrow", "polars-core", + "polars-error", "pyo3", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "quanta" -version = "0.12.3" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +checksum = "f3ab5a9d756f0d97bdc89019bd2e4ea098cf9cde50ee7564dde6b81ccc8f06c7" dependencies = [ "crossbeam-utils", "libc", "once_cell", "raw-cpuid", - "wasi", + "wasi 0.11.1+wasi-snapshot-preview1", "web-sys", "winapi", ] @@ -3737,15 +4843,86 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +[[package]] +name = "quick-xml" +version = "0.38.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a232e7487fc2ef313d96dde7948e7a3c05101870d8985e4fd8d26aedd27b89" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.17", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" +dependencies = [ + "bytes", + "getrandom 0.3.3", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.17", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.60.2", +] + [[package]] name = "quote" -version = "1.0.37" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" 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" @@ -3759,8 +4936,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", + "serde", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", "serde", ] @@ -3771,7 +4959,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] @@ -3780,42 +4978,58 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", + "serde", ] [[package]] name = "rand_distr" -version = "0.4.3" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +checksum = "6a8615d50dcf34fa31f7ab52692afec947c4dd0ab803cc87cb3b0b4570ff7463" dependencies = [ "num-traits", - "rand", + "rand 0.9.2", ] [[package]] name = "rand_xorshift" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" dependencies = [ - "rand_core", + "rand_core 0.9.3", ] [[package]] name = "raw-cpuid" -version = "11.2.0" +version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ab240315c661615f2ee9f0f2cd32d5a7343a84d5ebcccb99d46e6637565e7b0" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ "bitflags", ] +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + [[package]] name = "rayon" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ "either", "rayon-core", @@ -3823,14 +5037,34 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", ] +[[package]] +name = "recursive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0786a43debb760f491b1bc0269fe5e84155353c67482b9e60d0cfb596054b43e" +dependencies = [ + "recursive-proc-macro-impl", + "stacker", +] + +[[package]] +name = "recursive-proc-macro-impl" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76009fbe0614077fc1a2ce255e3a1881a2e3a3527097d5dc6d8212c585e7e38b" +dependencies = [ + "quote", + "syn 2.0.106", +] + [[package]] name = "recvmsg" version = "1.0.0" @@ -3839,38 +5073,38 @@ checksum = "d3edd4d5d42c92f0a659926464d4cce56b562761267ecf0f469d85b7de384175" [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ "bitflags", ] [[package]] name = "ref-cast" -version = "1.0.23" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf0a6f84d5f1d581da8b41b47ec8600871962f2a528115b542b362d4b744931" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.23" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] name = "regex" -version = "1.11.1" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" dependencies = [ "aho-corasick", "memchr", @@ -3880,9 +5114,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" dependencies = [ "aho-corasick", "memchr", @@ -3891,47 +5125,54 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" [[package]] name = "reqwest" -version = "0.12.9" +version = "0.12.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" +checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" dependencies = [ - "base64 0.22.1", + "base64", "bytes", "futures-core", "futures-util", + "h2", "http", "http-body", "http-body-util", "hyper", + "hyper-rustls", "hyper-tls", "hyper-util", - "ipnet", "js-sys", "log", - "mime", "native-tls", - "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile", + "quinn", + "rustls", + "rustls-native-certs", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 1.0.2", + "sync_wrapper", "tokio", "tokio-native-tls", + "tokio-rustls", + "tokio-util", + "tower", + "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", + "wasm-streams", "web-sys", - "windows-registry", + "webpki-roots 1.0.2", ] [[package]] @@ -3946,19 +5187,24 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.8" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.16", "libc", - "spin", "untrusted", "windows-sys 0.52.0", ] +[[package]] +name = "rle-decode-fast" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" + [[package]] name = "rlp" version = "0.5.2" @@ -3969,26 +5215,52 @@ dependencies = [ "rustc-hex", ] +[[package]] +name = "rmp" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" +dependencies = [ + "byteorder", + "num-traits", + "paste", +] + +[[package]] +name = "rmp-serde" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" +dependencies = [ + "byteorder", + "rmp", + "serde", +] + [[package]] name = "ruint" -version = "1.12.3" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c3cc4c2511671f327125da14133d0c5c5d137f006a1017a16f557bc85b16286" +checksum = "a68df0380e5c9d20ce49534f292a36a7514ae21350726efe1865bdb1fa91d278" dependencies = [ "alloy-rlp", "ark-ff 0.3.0", "ark-ff 0.4.2", + "ark-ff 0.5.0", "bytes", - "fastrlp", + "fastrlp 0.3.1", + "fastrlp 0.4.0", "num-bigint", + "num-integer", "num-traits", "parity-scale-codec", "primitive-types", "proptest", - "rand", + "rand 0.8.5", + "rand 0.9.2", "rlp", "ruint-macro", - "serde", + "serde_core", "valuable", "zeroize", ] @@ -4001,15 +5273,15 @@ checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustc-hex" @@ -4032,27 +5304,27 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.23", + "semver 1.0.27", ] [[package]] name = "rustix" -version = "0.38.41" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.61.1", ] [[package]] name = "rustls" -version = "0.23.18" +version = "0.23.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9cc1d47e243d655ace55ed38201c19ae02c148ae56412ab8750e8f0166ab7f" +checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" dependencies = [ "once_cell", "ring", @@ -4062,6 +5334,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework 3.5.1", +] + [[package]] name = "rustls-pemfile" version = "2.2.0" @@ -4073,15 +5357,19 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "web-time", + "zeroize", +] [[package]] name = "rustls-webpki" -version = "0.102.8" +version = "0.103.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" dependencies = [ "ring", "rustls-pki-types", @@ -4090,15 +5378,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "rusty-fork" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" dependencies = [ "fnv", "quick-error", @@ -4108,28 +5396,50 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "same-file" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] [[package]] name = "schannel" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.1", ] [[package]] -name = "schnellru" -version = "0.2.3" +name = "schemars" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9a8ef13a93c54d20580de1e5c413e624e53121d42fc7e2c11d10ef7f8b02367" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" dependencies = [ - "ahash", - "cfg-if", - "hashbrown 0.13.2", + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", ] [[package]] @@ -4148,10 +5458,32 @@ dependencies = [ "der", "generic-array", "pkcs8", + "serdect", "subtle", "zeroize", ] +[[package]] +name = "secp256k1" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b50c5943d326858130af85e049f2661ba3c78b26589b8ab98e65e80ae44a1252" +dependencies = [ + "bitcoin_hashes", + "rand 0.8.5", + "secp256k1-sys", + "serde", +] + +[[package]] +name = "secp256k1-sys" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" +dependencies = [ + "cc", +] + [[package]] name = "security-framework" version = "2.11.1" @@ -4159,7 +5491,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags", - "core-foundation", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +dependencies = [ + "bitflags", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -4167,9 +5512,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.12.1" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", @@ -4186,9 +5531,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.23" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" [[package]] name = "semver-parser" @@ -4206,42 +5551,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] -name = "seq-macro" -version = "0.3.5" +name = "serde" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] [[package]] -name = "serde" -version = "1.0.215" +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] name = "serde_json" -version = "1.0.133" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ - "indexmap", + "indexmap 2.11.4", "itoa", "memchr", "ryu", "serde", + "serde_core", +] + +[[package]] +name = "serde_stacker" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4936375d50c4be7eff22293a9344f8e46f323ed2b3c243e52f89138d9bb0f4a" +dependencies = [ + "serde", + "serde_core", + "stacker", ] [[package]] @@ -4256,6 +5617,47 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "3.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6093cd8c01b25262b84927e0f7151692158fab02d961e04c979d3903eba7ecc5" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.11.4", + "schemars 0.9.0", + "schemars 1.0.4", + "serde_core", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7e6c180db0816026a61afa1cff5344fb7ebded7e4d3062772179f2501481c27" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct", + "serde", +] + [[package]] name = "sha1" version = "0.10.6" @@ -4269,9 +5671,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -4298,12 +5700,40 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signal-hook" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +dependencies = [ + "libc", +] + [[package]] name = "signature" version = "2.2.0" @@ -4311,19 +5741,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", - "rand_core", + "rand_core 0.6.4", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "simd-json" -version = "0.13.11" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0228a564470f81724e30996bbc2b171713b37b15254a6440c7e2d5449b95691" +checksum = "c962f626b54771990066e5435ec8331d1462576cd2d1e62f24076ae014f92112" dependencies = [ "ahash", - "getrandom", + "getrandom 0.3.3", "halfbrown", - "lexical-core", "once_cell", "ref-cast", "serde", @@ -4338,38 +5773,58 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" +[[package]] +name = "simple_asn1" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror 2.0.17", + "time", +] + [[package]] name = "siphasher" -version = "0.3.11" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] -name = "slab" -version = "0.4.9" +name = "skiplist" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +checksum = "f354fd282d3177c2951004953e2fdc4cb342fa159bbee8b829852b6a081c8ea1" dependencies = [ - "autocfg", + "rand 0.9.2", + "thiserror 2.0.17", ] [[package]] -name = "smallvec" -version = "1.13.2" +name = "slab" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] -name = "smartstring" -version = "1.0.1" +name = "slotmap" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" dependencies = [ - "autocfg", - "static_assertions", "version_check", ] +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] + [[package]] name = "snap" version = "1.1.1" @@ -4378,20 +5833,14 @@ checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" [[package]] name = "socket2" -version = "0.5.7" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - [[package]] name = "spinning_top" version = "0.3.0" @@ -4413,9 +5862,9 @@ dependencies = [ [[package]] name = "sqlparser" -version = "0.39.0" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743b4dc2cbde11890ccb254a8fc9d537fa41b36da00de2a1c5e9848c9bc42bd7" +checksum = "05a528114c392209b3264855ad491fcce534b94a38771b0a0b97a79379275ce8" dependencies = [ "log", ] @@ -4426,6 +5875,19 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "stacker" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1f8b29fb42aafcea4edeeb6b2f2d7ecd0d969c48b4cf0d2e64aafc471dd6e59" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "windows-sys 0.59.0", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -4455,43 +5917,29 @@ checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" -dependencies = [ - "strum_macros 0.26.4", -] - -[[package]] -name = "strum_macros" -version = "0.25.3" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.89", + "strum_macros", ] [[package]] name = "strum_macros" -version = "0.26.4" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", - "rustversion", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] @@ -4513,9 +5961,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.89" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", @@ -4524,22 +5972,16 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.8.13" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdaa7b9e815582ba343a20c66627437cf45f1c6fba7f69772cbfd1358c7e197" +checksum = "2375c17f6067adc651d8c2c51658019cef32edfff4a982adaf1d7fd1c039f08b" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - [[package]] name = "sync_wrapper" version = "1.0.2" @@ -4551,27 +5993,34 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] -name = "sysinfo" -version = "0.30.13" +name = "system-configuration" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a5b4ddaee55fb2bea2bf0e5000747e5f5c0de765e5a5ff87f4cd106439f4bb3" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" dependencies = [ - "cfg-if", "core-foundation-sys", "libc", - "ntapi", - "once_cell", - "windows", ] [[package]] @@ -4580,29 +6029,23 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" -[[package]] -name = "target-features" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1bbb9f3c5c463a01705937a24fdabc5047929ac764b2d5b9cf681c1f5041ed5" - [[package]] name = "target-lexicon" -version = "0.12.16" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" +checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" [[package]] name = "tempfile" -version = "3.14.0" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ - "cfg-if", "fastrand", + "getrandom 0.3.3", "once_cell", "rustix", - "windows-sys 0.59.0", + "windows-sys 0.61.1", ] [[package]] @@ -4611,7 +6054,16 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +dependencies = [ + "thiserror-impl 2.0.17", ] [[package]] @@ -4622,7 +6074,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] @@ -4631,6 +6094,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + [[package]] name = "threadpool" version = "1.8.1" @@ -4640,6 +6112,57 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "tikv-jemalloc-sys" +version = "0.6.0+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd3c60906412afa9c2b5b5a48ca6a5abe5736aec9eb48ad05037a677e52e4e2d" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "tikv-jemallocator" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cec5ff18518d81584f477e9bfdf957f5bb0979b0bac3af4ca30b5b3ae2d2865" +dependencies = [ + "libc", + "tikv-jemalloc-sys", +] + +[[package]] +name = "time" +version = "0.3.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" + +[[package]] +name = "time-macros" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -4651,39 +6174,56 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.6" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" dependencies = [ "displaydoc", "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" -version = "1.41.1" +version = "1.47.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" dependencies = [ "backtrace", "bytes", + "io-uring", "libc", "mio", "pin-project-lite", + "slab", "socket2", "tokio-macros", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "tokio-macros" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] @@ -4698,20 +6238,19 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.0" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ "rustls", - "rustls-pki-types", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" dependencies = [ "futures-core", "pin-project-lite", @@ -4721,9 +6260,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.24.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" +checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084" dependencies = [ "futures-util", "log", @@ -4732,49 +6271,82 @@ dependencies = [ "tokio", "tokio-rustls", "tungstenite", - "webpki-roots", + "webpki-roots 0.26.11", ] [[package]] name = "tokio-util" -version = "0.7.12" +version = "0.7.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" dependencies = [ "bytes", "futures-core", "futures-sink", + "futures-util", "pin-project-lite", "tokio", ] [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1" +dependencies = [ + "serde_core", +] [[package]] name = "toml_edit" -version = "0.22.22" +version = "0.23.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +checksum = "f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b" dependencies = [ - "indexmap", + "indexmap 2.11.4", "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627" +dependencies = [ "winnow", ] [[package]] name = "tower" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", "pin-project-lite", - "sync_wrapper 0.1.2", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", "tower-layer", "tower-service", ] @@ -4793,9 +6365,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -4804,22 +6376,48 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ + "log", "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", ] [[package]] @@ -4830,29 +6428,28 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tungstenite" -version = "0.24.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" dependencies = [ - "byteorder", "bytes", "data-encoding", "http", "httparse", "log", - "rand", + "rand 0.9.2", "rustls", "rustls-pki-types", "sha1", - "thiserror", + "thiserror 2.0.17", "utf-8", ] [[package]] name = "typenum" -version = "1.17.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "ucd-trie" @@ -4880,9 +6477,18 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] [[package]] name = "unicode-reverse" @@ -4901,15 +6507,9 @@ checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - -[[package]] -name = "unicode-width" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" +checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" [[package]] name = "unicode-xid" @@ -4919,9 +6519,15 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "unindent" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce" +checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3" + +[[package]] +name = "unit-prefix" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "323402cff2dd658f39ca17c789b502021b3f18707c91cdf22e3838e1b4023817" [[package]] name = "untrusted" @@ -4929,15 +6535,22 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "unty" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" + [[package]] name = "url" -version = "2.5.4" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -4946,12 +6559,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -4966,24 +6573,27 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.11.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ - "getrandom", + "getrandom 0.3.3", + "js-sys", + "serde", + "wasm-bindgen", ] [[package]] name = "valuable" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "value-trait" -version = "0.8.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad8db98c1e677797df21ba03fca7d3bf9bec3ca38db930954e4fe6e1ea27eb4" +checksum = "0508fce11ad19e0aab49ce20b6bec7f8f82902ded31df1c9fc61b90f0eb396b8" dependencies = [ "float-cmp", "halfbrown", @@ -5003,15 +6613,31 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "virtue" +version = "0.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1" + [[package]] name = "wait-timeout" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" dependencies = [ "libc", ] +[[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" @@ -5023,53 +6649,73 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.7+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.45" +version = "0.4.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5077,28 +6723,44 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-streams" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] [[package]] name = "wasmtimer" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0048ad49a55b9deb3953841fa1fc5858f0efbcb7a18868c899a360269fac1b23" +checksum = "1c598d6b99ea013e35844697fc4670d08339d5cda15588f193c6beedd12f644b" dependencies = [ "futures", "js-sys", @@ -5110,9 +6772,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" dependencies = [ "js-sys", "wasm-bindgen", @@ -5130,18 +6792,27 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.7" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.2", +] + +[[package]] +name = "webpki-roots" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" +checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" dependencies = [ "rustls-pki-types", ] [[package]] name = "widestring" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" +checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" [[package]] name = "winapi" @@ -5159,6 +6830,15 @@ 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.61.1", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -5166,61 +6846,97 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.52.0" +name = "windows-core" +version = "0.62.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +checksum = "6844ee5416b285084d3d3fffd743b925a6c9385455f64f6d4fa3031c4c2749a9" dependencies = [ - "windows-core", - "windows-targets 0.52.6", + "windows-implement", + "windows-interface", + "windows-link 0.2.0", + "windows-result 0.4.0", + "windows-strings 0.5.0", ] [[package]] -name = "windows-core" -version = "0.52.0" +name = "windows-implement" +version = "0.60.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "edb307e42a74fb6de9bf3a02d9712678b22399c87e6fa869d6dfcd8c1b7754e0" dependencies = [ - "windows-targets 0.52.6", + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] -name = "windows-registry" +name = "windows-interface" +version = "0.59.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0abd1ddbc6964ac14db11c7213d6532ef34bd9aa042c2e5935f59d7908b46a5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-link" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + +[[package]] +name = "windows-registry" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" dependencies = [ - "windows-result", - "windows-strings", - "windows-targets 0.52.6", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", ] [[package]] name = "windows-result" -version = "0.2.0" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-targets 0.52.6", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f" +dependencies = [ + "windows-link 0.2.0", ] [[package]] name = "windows-strings" -version = "0.1.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-result", - "windows-targets 0.52.6", + "windows-link 0.1.3", ] [[package]] -name = "windows-sys" -version = "0.48.0" +name = "windows-strings" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda" dependencies = [ - "windows-targets 0.48.5", + "windows-link 0.2.0", ] [[package]] @@ -5242,18 +6958,21 @@ dependencies = [ ] [[package]] -name = "windows-targets" -version = "0.48.5" +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.4", +] + +[[package]] +name = "windows-sys" +version = "0.61.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" 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", + "windows-link 0.2.0", ] [[package]] @@ -5265,7 +6984,7 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", @@ -5273,10 +6992,21 @@ dependencies = [ ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" +name = "windows-targets" +version = "0.53.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +checksum = "2d42b7b7f66d2a06854650af09cfdf8713e427a439c97ad65a6375318033ac4b" +dependencies = [ + "windows-link 0.2.0", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] [[package]] name = "windows_aarch64_gnullvm" @@ -5285,10 +7015,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" +name = "windows_aarch64_gnullvm" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" [[package]] name = "windows_aarch64_msvc" @@ -5297,10 +7027,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] -name = "windows_i686_gnu" -version = "0.48.5" +name = "windows_aarch64_msvc" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" [[package]] name = "windows_i686_gnu" @@ -5308,6 +7038,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" @@ -5315,10 +7051,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] -name = "windows_i686_msvc" -version = "0.48.5" +name = "windows_i686_gnullvm" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" [[package]] name = "windows_i686_msvc" @@ -5327,10 +7063,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" +name = "windows_i686_msvc" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" [[package]] name = "windows_x86_64_gnu" @@ -5339,10 +7075,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" +name = "windows_x86_64_gnu" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" [[package]] name = "windows_x86_64_gnullvm" @@ -5351,10 +7087,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" +name = "windows_x86_64_gnullvm" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" [[package]] name = "windows_x86_64_msvc" @@ -5362,32 +7098,38 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "winnow" -version = "0.6.20" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" dependencies = [ "memchr", ] [[package]] -name = "write16" -version = "1.0.0" +name = "wit-bindgen" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" -version = "0.5.5" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "ws_stream_wasm" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" +checksum = "6c173014acad22e83f16403ee360115b38846fe754e735c5d9d3803fe70c6abc" dependencies = [ "async_io_stream", "futures", @@ -5396,7 +7138,7 @@ dependencies = [ "pharos", "rustc_version 0.4.1", "send_wrapper", - "thiserror", + "thiserror 2.0.17", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -5411,17 +7153,34 @@ dependencies = [ "tap", ] +[[package]] +name = "x11rb" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" +dependencies = [ + "gethostname", + "rustix", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" + [[package]] name = "xxhash-rust" -version = "0.8.12" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a5cbf750400958819fb6178eaa83bee5cd9c29a26a40cc241df8c70fdd46984" +checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3" [[package]] name = "yoke" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" dependencies = [ "serde", "stable_deref_trait", @@ -5431,63 +7190,62 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", "synstructure", ] [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ - "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] [[package]] name = "zerofrom" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", "synstructure", ] [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" dependencies = [ "zeroize_derive", ] @@ -5500,14 +7258,25 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", +] + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", ] [[package]] name = "zerovec" -version = "0.10.4" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" dependencies = [ "yoke", "zerofrom", @@ -5516,38 +7285,44 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.106", ] +[[package]] +name = "zlib-rs" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f06ae92f42f5e5c42443fd094f245eb656abf56dd7cce9b8b263236565e00f2" + [[package]] name = "zstd" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.2.1" +version = "7.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.13+zstd.1.5.6" +version = "2.0.16+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index bde9386e..d6a0fed0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,38 +16,35 @@ exclude = [".github/"] [workspace.dependencies] cryo_cli = { version = "0.3.2", path = "./crates/cli" } -cryo_freeze = { version = "0.3.2", path = "./crates/freeze" } +cryo_freeze = { version = "0.3.2", path = "./crates/freeze", default-features = false } cryo_to_df = { version = "0.3.2", path = "./crates/to_df" } -alloy = { version = "0.6.4", features = [ +alloy = { version = "1.0.9", default-features = false, features = [ + "std", "full", - "rpc-types-trace", - "provider-ws", - "provider-ipc", - "provider-debug-api", - "provider-trace-api", "transport-ipc-mock", ] } +alloy-transport-http = { version = "1.0.9", default-features = false, features = ["jwt-auth"] } anstyle = "1.0.4" async-trait = "0.1.74" chrono = { version = "0.4.31", features = ["serde"] } -clap_cryo = { version = "4.3.21-cryo", features = [ +clap = { version = "4.3.21", features = [ "derive", "color", "unstable-styles", ] } -colored = "2.0.4" +colored = "3.0" color-print = "0.3.5" eyre = "0.6.8" futures = "0.3.29" -governor = "0.6.0" +governor = "0.10.0" hex = "0.4.3" -heck = "0.4.1" +heck = "0.5.0" indexmap = "2.1.0" -indicatif = "0.17.7" +indicatif = "0.18.0" lazy_static = "1.4.0" -mesc = "0.1.4" -polars = { version = "0.38.3", features = [ +mesc = "0.3.0" +polars = { version = "0.51.0", features = [ "parquet", "string_encoding", "polars-lazy", @@ -56,18 +53,19 @@ polars = { version = "0.38.3", features = [ "json", "dtype-struct", ] } -prefix-hex = "0.7.1" -pyo3 = { version = "0.20.0", features = ["extension-module"] } -pyo3-build-config = "0.20.0" -pyo3-asyncio = { version = "0.20.0", features = ["tokio-runtime"] } -pyo3-polars = "0.12.0" -rand = "0.8.5" +polars-python = "0.51.0" +pyo3 = { version = "0.25.0" } +pyo3-build-config = "0.25.0" +pyo3-async-runtimes = { version = "0.25.0", features = ["tokio-runtime"] } +pyo3-polars = "0.24.0" +rand = "0.9.2" regex = "1.10.2" serde = { version = "1.0.191", features = ["derive"] } serde_json = "1.0.108" -thiserror = "1.0.50" +thiserror = "2.0" thousands = "0.2.0" tokio = { version = "1.33.0", features = ["macros", "rt-multi-thread", "sync"] } +tracing = "0.1.41" [profile.dev] incremental = true diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 49cb9a0d..372ab94e 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -20,7 +20,7 @@ path = "src/main.rs" [dependencies] alloy = { workspace = true } anstyle = { workspace = true } -clap_cryo = { workspace = true } +clap = { workspace = true } color-print = { workspace = true } colored = { workspace = true } cryo_freeze = { workspace = true } @@ -33,3 +33,11 @@ rand = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } tokio = { workspace = true } +tracing = { workspace = true } +tracing-subscriber = "0.3.20" + +[features] +default = ["reqwest-default-tls"] +reqwest-default-tls = ["alloy/reqwest", "cryo_freeze/reqwest-default-tls"] +reqwest-native-tls = ["alloy/reqwest-native-tls", "cryo_freeze/reqwest-native-tls"] +reqwest-rustls-tls = ["alloy/reqwest-rustls-tls", "cryo_freeze/reqwest-rustls-tls"] diff --git a/crates/cli/src/args.rs b/crates/cli/src/args.rs index 238db4e5..fcdc094a 100644 --- a/crates/cli/src/args.rs +++ b/crates/cli/src/args.rs @@ -1,4 +1,4 @@ -use clap_cryo::Parser; +use clap::Parser; use color_print::cstr; use colored::Colorize; use serde::{Deserialize, Serialize}; @@ -15,7 +15,6 @@ use std::{default::Default, path::PathBuf}; long_about = None, styles=get_styles(), after_help=&get_after_str(), - allow_negative_numbers = true, )] pub struct Args { /// Datatype to collect @@ -23,11 +22,11 @@ pub struct Args { pub datatype: Vec, /// Block numbers, see syntax below - #[arg(short, long, allow_negative_numbers = true, help_heading = "Content Options", num_args(1..))] + #[arg(short, long, value_delimiter = ',', help_heading = "Content Options", num_args(1..))] pub blocks: Option>, /// Timestamps in unix, see syntax below - #[arg(long, allow_negative_numbers = true, help_heading = "Content Options", num_args(0..))] + #[arg(long, value_delimiter = ',', help_heading = "Content Options", num_args(0..))] pub timestamps: Option>, /// Transaction hashes, see syntax below @@ -78,6 +77,10 @@ pub struct Args { #[arg(long, help_heading = "Content Options")] pub hex: bool, + /// Use hex string encoding without a prefix for binary columns + #[arg(long, help_heading = "Content Options")] + pub no_hex_prefix: bool, + /// Columns(s) to sort by, `none` for unordered #[arg(short, long, num_args(0..), help_heading="Content Options")] pub sort: Option>, @@ -90,6 +93,10 @@ pub struct Args { #[arg(short, long, help_heading = "Source Options")] pub rpc: Option, + /// JWT auth token for RPC (Bearer), can also be provided via ETH_RPC_JWT env var + #[arg(long, help_heading = "Source Options")] + pub jwt: Option, + /// Network name [default: name of eth_getChainId] #[arg(long, help_heading = "Source Options")] pub network_name: Option, @@ -290,14 +297,14 @@ impl Args { } } -pub(crate) fn get_styles() -> clap_cryo::builder::Styles { +pub(crate) fn get_styles() -> clap::builder::Styles { let white = anstyle::Color::Rgb(anstyle::RgbColor(255, 255, 255)); let green = anstyle::Color::Rgb(anstyle::RgbColor(0, 225, 0)); let grey = anstyle::Color::Rgb(anstyle::RgbColor(170, 170, 170)); let title = anstyle::Style::new().bold().fg_color(Some(green)); let arg = anstyle::Style::new().bold().fg_color(Some(white)); let comment = anstyle::Style::new().fg_color(Some(grey)); - clap_cryo::builder::Styles::styled() + clap::builder::Styles::styled() .header(title) .error(comment) .usage(title) @@ -322,7 +329,7 @@ fn get_after_str() -> String { cryo help"# ); let post_subcommands = " display info about a dataset"; - format!("{}{}{}", header, subcommands, post_subcommands) + format!("{header}{subcommands}{post_subcommands}") } fn get_datatype_help() -> &'static str { @@ -330,3 +337,83 @@ fn get_datatype_help() -> &'static str { r#"datatype(s) to collect, use cryo datasets to see all available"# ) } + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_merge_args() { + let args1 = Args { + datatype: vec!["blocks".to_string()], + rpc: Some("http://localhost:8545".to_string()), + chunk_size: 500, + ..Default::default() + }; + + let args2 = Args { + rpc: Some("http://example.com:8545".to_string()), + max_retries: 10, + ..Default::default() + }; + + let merged = args1.clone().merge_with_precedence(args2.clone()); + + assert_eq!(merged.datatype, args1.datatype); + assert_eq!(merged.rpc, args2.rpc); + assert_eq!(merged.chunk_size, args1.chunk_size); + assert_eq!(merged.max_retries, args2.max_retries); + } + + #[test] + fn test_short_blocks() { + let args = Args::parse_from(["cryo", "--blocks", "1000", "2000"]); + assert_eq!(args.blocks, Some(vec!["1000".to_string(), "2000".to_string()])); + + fn test_shortcut(value: &str) { + let result = value.split(",").map(|i| i.to_string()).collect::>(); + tracing::debug!("test_shortcut: {} {:?}", value, result); + let args = Args::parse_from(["cryo", "--blocks", value]); + assert_eq!(args.blocks, Some(result.clone())); + + let args = Args::parse_from(["cryo", "-b", value]); + assert_eq!(args.blocks, Some(result.clone())); + + let args = Args::parse_from(["cryo", &format!("--blocks={value}")]); + assert_eq!(args.blocks, Some(result.clone())); + + let args = Args::parse_from(["cryo", &format!("-b={value}")]); + assert_eq!(args.blocks, Some(result.clone())); + + let args = Args::parse_from(["cryo", &format!("-b{value}")]); + assert_eq!(args.blocks, Some(result.clone())); + + let args = Args::parse_from(["cryo", "--blocks", value, "-v"]); + assert_eq!(args.blocks, Some(result.clone())); + + let args = Args::parse_from(["cryo", "-b", value, "-v"]); + assert_eq!(args.blocks, Some(result.clone())); + + let args = Args::parse_from(["cryo", &format!("--blocks={value}"), "-v"]); + assert_eq!(args.blocks, Some(result.clone())); + + let args = Args::parse_from(["cryo", &format!("-b={value}"), "-v"]); + assert_eq!(args.blocks, Some(result.clone())); + + let args = Args::parse_from(["cryo", &format!("-b{value}"), "-v"]); + assert_eq!(args.blocks, Some(result.clone())); + } + + test_shortcut("1000"); + test_shortcut("1000:2000"); + test_shortcut("1_000:2_000"); + test_shortcut("1k:2M"); + test_shortcut(":2000"); + test_shortcut("1000:"); + test_shortcut("1000:latest"); + test_shortcut("latest"); + test_shortcut(":latest"); + + test_shortcut("1000,2000,3000"); + test_shortcut("1000,2000,3000:latest"); + } +} diff --git a/crates/cli/src/lib.rs b/crates/cli/src/lib.rs index 516f23de..cfd791e4 100644 --- a/crates/cli/src/lib.rs +++ b/crates/cli/src/lib.rs @@ -7,6 +7,9 @@ attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables)) ))] +#[macro_use] +extern crate tracing; + mod args; mod parse; mod remember; @@ -15,6 +18,7 @@ mod run; // used in main.rs but not lib.rs use eyre as _; use tokio as _; +use tracing_subscriber as _; pub use args::Args; pub use parse::{parse_args, parse_query, parse_str}; diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 779d3b76..2028e2a9 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -1,21 +1,17 @@ //! cryo_cli is a cli for cryo_freeze -use clap_cryo::Parser; +use clap::Parser; -mod args; -mod parse; -mod remember; -mod run; - -pub use args::Args; +pub use cryo_cli::{run, Args}; use eyre::Result; #[tokio::main] #[allow(unreachable_code)] #[allow(clippy::needless_return)] async fn main() -> Result<()> { + tracing_subscriber::fmt().init(); let args = Args::parse(); - match run::run(args).await { + match run(args).await { Ok(Some(freeze_summary)) if freeze_summary.errored.is_empty() => Ok(()), Ok(Some(_freeze_summary)) => std::process::exit(1), Ok(None) => Ok(()), @@ -29,7 +25,7 @@ async fn main() -> Result<()> { // handle release build #[cfg(not(debug_assertions))] { - println!("{}", e); + tracing::error!("{}", e); std::process::exit(1); } } diff --git a/crates/cli/src/parse/args.rs b/crates/cli/src/parse/args.rs index 2e6ad87c..373a82ed 100644 --- a/crates/cli/src/parse/args.rs +++ b/crates/cli/src/parse/args.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use cryo_freeze::{ExecutionEnv, FileOutput, ParseError, Query, Source}; use crate::args::Args; -use clap_cryo::Parser; +use clap::Parser; use super::{execution, file_output, query, source}; diff --git a/crates/cli/src/parse/blocks.rs b/crates/cli/src/parse/blocks.rs index a9e75df2..9caf04ad 100644 --- a/crates/cli/src/parse/blocks.rs +++ b/crates/cli/src/parse/blocks.rs @@ -20,7 +20,7 @@ pub(crate) async fn parse_blocks( for path in files { let column = if path.contains(':') { path.split(':') - .last() + .next_back() .ok_or(ParseError::ParseError("could not parse txs path column".to_string()))? } else { "block_number" @@ -395,8 +395,8 @@ mod tests { use std::path::PathBuf; use alloy::{ - providers::{IpcConnect, ProviderBuilder}, - transports::ipc::MockIpcServer, + providers::{Provider, ProviderBuilder}, + transports::ipc::{IpcConnect, MockIpcServer}, }; use super::*; @@ -412,7 +412,7 @@ mod tests { mock_ipc_path: PathBuf, ) { let ipc = IpcConnect::new(mock_ipc_path); - let provider = ProviderBuilder::new().on_ipc(ipc).await.unwrap().boxed(); + let provider = ProviderBuilder::new().connect_ipc(ipc).await.unwrap().erased(); let source = Source { provider, semaphore: Arc::new(None), @@ -421,6 +421,7 @@ mod tests { inner_request_size: 1, max_concurrent_chunks: None, rpc_url: "".to_string(), + jwt: None, labels: cryo_freeze::SourceLabels::default(), }; let source = Arc::new(source); @@ -478,7 +479,7 @@ mod tests { mock_ipc_path: PathBuf, ) { let ipc = IpcConnect::new(mock_ipc_path); - let provider = ProviderBuilder::new().on_ipc(ipc).await.unwrap().boxed(); + let provider = ProviderBuilder::new().connect_ipc(ipc).await.unwrap().erased(); let source = Arc::new(Source { provider, chain_id: 1, @@ -487,6 +488,7 @@ mod tests { semaphore: Arc::new(None), max_concurrent_chunks: Some(1), rate_limiter: Arc::new(None), + jwt: None, labels: cryo_freeze::SourceLabels::default(), }); for (test, res) in tests { @@ -498,11 +500,11 @@ mod tests { ); } BlockInputTest::WithoutMock((inputs, expected)) => { - println!("RES {:?}", res); - println!("inputs {:?}", inputs); - println!("EXPECTED {:?}", expected); + println!("RES {res:?}"); + println!("inputs {inputs:?}"); + println!("EXPECTED {expected:?}"); let actual = block_input_test_executor(inputs, expected, source.clone()).await; - println!("ACTUAL {:?}", actual); + println!("ACTUAL {actual:?}"); assert_eq!(actual, res); } } @@ -518,8 +520,8 @@ mod tests { assert_eq!(block_chunks.len(), expected.len()); for (i, block_chunk) in block_chunks.iter().enumerate() { let expected_chunk = &expected[i]; - println!("BLOCK_CHUNK {:?}", block_chunk); - println!("EXCPECTED_CHUNK {:?}", expected_chunk); + println!("BLOCK_CHUNK {block_chunk:?}"); + println!("EXCPECTED_CHUNK {expected_chunk:?}"); match expected_chunk { BlockChunk::Numbers(expected_block_numbers) => { assert!(matches!(block_chunk, BlockChunk::Numbers { .. })); @@ -554,8 +556,11 @@ mod tests { tests: Vec<(BlockNumberTest<'_>, bool)>, mock_ipc_path: PathBuf, ) { - let provider = - ProviderBuilder::new().on_ipc(IpcConnect::new(mock_ipc_path)).await.unwrap().boxed(); + let provider = ProviderBuilder::new() + .connect_ipc(IpcConnect::new(mock_ipc_path)) + .await + .unwrap() + .erased(); let source = Source { provider, semaphore: Arc::new(None), @@ -564,6 +569,7 @@ mod tests { inner_request_size: 1, max_concurrent_chunks: Some(1), rpc_url: "".to_string(), + jwt: None, labels: cryo_freeze::SourceLabels::default(), }; let source = Arc::new(source); diff --git a/crates/cli/src/parse/file_output.rs b/crates/cli/src/parse/file_output.rs index db6430b1..563e0d47 100644 --- a/crates/cli/src/parse/file_output.rs +++ b/crates/cli/src/parse/file_output.rs @@ -12,7 +12,7 @@ pub(crate) fn parse_file_output(args: &Args, source: &Source) -> Result {} - Err(e) => return Err(ParseError::ParseError(format!("Error creating directory: {}", e))), + Err(e) => return Err(ParseError::ParseError(format!("Error creating directory: {e}"))), }; let label = &args.label; diff --git a/crates/cli/src/parse/parse_utils.rs b/crates/cli/src/parse/parse_utils.rs index d445df4a..9f2e7eec 100644 --- a/crates/cli/src/parse/parse_utils.rs +++ b/crates/cli/src/parse/parse_utils.rs @@ -1,13 +1,13 @@ -use cryo_freeze::ParseError; +use cryo_freeze::{ParseError, RawBytes}; use std::collections::HashMap; -pub(crate) fn hex_string_to_binary(hex_string: &str) -> Result, ParseError> { +pub(crate) fn hex_string_to_binary(hex_string: &str) -> Result { let hex_string = hex_string.strip_prefix("0x").unwrap_or(hex_string); hex::decode(hex_string) .map_err(|_| ParseError::ParseError("could not parse data as hex".to_string())) } -pub(crate) fn hex_strings_to_binary(hex_strings: &[String]) -> Result>, ParseError> { +pub(crate) fn hex_strings_to_binary(hex_strings: &[String]) -> Result, ParseError> { hex_strings .iter() .map(|x| { @@ -39,7 +39,7 @@ impl BinaryInputList { } } -type ParsedBinaryArg = HashMap>>; +type ParsedBinaryArg = HashMap>; /// parse binary argument list /// each argument can be a hex string or a parquet column reference diff --git a/crates/cli/src/parse/partitions.rs b/crates/cli/src/parse/partitions.rs index 0816435e..bd43d3c9 100644 --- a/crates/cli/src/parse/partitions.rs +++ b/crates/cli/src/parse/partitions.rs @@ -8,7 +8,7 @@ use cryo_freeze::{ AddressChunk, CallDataChunk, Datatype, Dim, ParseError, Partition, PartitionLabels, SlotChunk, Source, Table, TimeDimension, TopicChunk, TransactionChunk, }; -use rand::{seq::SliceRandom, thread_rng}; +use rand::{rng, seq::SliceRandom}; use std::{collections::HashMap, str::FromStr, sync::Arc}; type ChunkLabels = Vec>; @@ -105,14 +105,14 @@ pub(crate) async fn parse_partitions( }; let mut partitions = chunk .partition_with_labels(labels, partition_by.clone()) - .map_err(|e| ParseError::ParseError(format!("could not partition labels ({})", e)))?; + .map_err(|e| ParseError::ParseError(format!("could not partition labels ({e})")))?; match args.chunk_order.as_deref() { None => {} Some("normal") => {} Some("reverse") => partitions.reverse(), Some("random") => { - let mut rng = thread_rng(); + let mut rng = rng(); partitions.shuffle(&mut rng); } _ => { diff --git a/crates/cli/src/parse/schemas.rs b/crates/cli/src/parse/schemas.rs index 4590bbe0..12d0d264 100644 --- a/crates/cli/src/parse/schemas.rs +++ b/crates/cli/src/parse/schemas.rs @@ -38,6 +38,11 @@ pub(crate) fn parse_schemas( true => ColumnEncoding::Hex, false => ColumnEncoding::Binary, }; + let table_config = cryo_freeze::TableConfig { + binary_type: binary_column_format, + u256_types: u256_types.clone(), + hex_prefix: !args.no_hex_prefix, + }; let log_decoder = match args.event_signature { Some(ref sig) => match LogDecoder::new(sig.clone()) { @@ -53,8 +58,7 @@ pub(crate) fn parse_schemas( .map(|datatype| { datatype .table_schema( - &u256_types, - &binary_column_format, + table_config.clone(), &args.include_columns, &args.exclude_columns, &args.columns, @@ -64,8 +68,7 @@ pub(crate) fn parse_schemas( .map(|schema| (*datatype, schema)) .map_err(|e| { ParseError::ParseError(format!( - "Failed to get schema for datatype: {:?}, {:?}", - datatype, e + "Failed to get schema for datatype: {datatype:?}, {e:?}" )) }) }) @@ -86,21 +89,22 @@ pub(crate) fn parse_schemas( fn parse_u256_types(args: &Args) -> Result, ParseError> { args.u256_types.as_ref().map_or( - Ok(vec![U256Type::Binary, U256Type::String, U256Type::F64]), + Ok(vec![U256Type::NamedBinary, U256Type::String, U256Type::F64]), |raw_u256_types| { raw_u256_types .iter() .map(|raw| { let lower_case = raw.to_lowercase(); match lower_case.as_str() { - "binary" => Ok(U256Type::Binary), + "binary" => Ok(U256Type::NamedBinary), + "plain_binary" => Ok(U256Type::Binary), "string" | "str" => Ok(U256Type::String), "f32" | "float32" => Ok(U256Type::F32), "f64" | "float64" | "float" => Ok(U256Type::F64), "u32" | "uint32" => Ok(U256Type::U32), "u64" | "uint64" => Ok(U256Type::U64), "decimal128" | "d128" => Ok(U256Type::Decimal128), - _ => Err(ParseError::ParseError(format!("invalid u256 type: {}", raw))), + _ => Err(ParseError::ParseError(format!("invalid u256 type: {raw}"))), } }) .collect() @@ -129,8 +133,7 @@ fn ensure_included_columns( } if !unknown_columns.is_empty() { return Err(ParseError::ParseError(format!( - "datatypes do not support these columns: {:?}", - unknown_columns + "datatypes do not support these columns: {unknown_columns:?}" ))) } Ok(()) @@ -157,8 +160,7 @@ fn ensure_excluded_columns( } if !unknown_columns.is_empty() { return Err(ParseError::ParseError(format!( - "datatypes do not support these columns: {:?}", - unknown_columns + "datatypes do not support these columns: {unknown_columns:?}" ))) } Ok(()) diff --git a/crates/cli/src/parse/source.rs b/crates/cli/src/parse/source.rs index 6b625157..f104ecac 100644 --- a/crates/cli/src/parse/source.rs +++ b/crates/cli/src/parse/source.rs @@ -1,33 +1,18 @@ use std::env; use crate::args::Args; -use alloy::{ - providers::{Provider, ProviderBuilder, RootProvider}, - rpc::client::{BuiltInConnectionString, ClientBuilder, RpcClient}, - transports::{layers::RetryBackoffLayer, BoxTransport}, -}; use cryo_freeze::{ParseError, Source, SourceLabels}; use governor::{Quota, RateLimiter}; -use polars::prelude::*; use std::num::NonZeroU32; pub(crate) async fn parse_source(args: &Args) -> Result { // parse network info let rpc_url = parse_rpc_url(args)?; - let retry_layer = RetryBackoffLayer::new( - args.max_retries, - args.initial_backoff, - args.compute_units_per_second, - ); - let connect: BuiltInConnectionString = rpc_url.parse().map_err(ParseError::ProviderError)?; - let client: RpcClient = ClientBuilder::default() - .layer(retry_layer) - .connect_boxed(connect) - .await - .map_err(ParseError::ProviderError)? - .boxed(); - let provider: RootProvider = ProviderBuilder::default().on_client(client); - let chain_id = provider.get_chain_id().await.map_err(ParseError::ProviderError)?; + // capture jwt token from args or environment + let jwt = match &args.jwt { + Some(v) => Some(v.clone()), + None => std::env::var("ETH_RPC_JWT").ok(), + }; let rate_limiter = match args.requests_per_second { Some(rate_limit) => match (NonZeroU32::new(1), NonZeroU32::new(rate_limit)) { (Some(one), Some(value)) => { @@ -48,25 +33,28 @@ pub(crate) async fn parse_source(args: &Args) -> Result { }; let semaphore = tokio::sync::Semaphore::new(max_concurrent_requests as usize); - let semaphore = Arc::new(Some(semaphore)); - let output = Source { - chain_id, - inner_request_size: args.inner_request_size, - max_concurrent_chunks, - semaphore, - rate_limiter: rate_limiter.into(), - rpc_url, - provider, - labels: SourceLabels { - max_concurrent_requests: args.max_concurrent_requests, - max_requests_per_second: args.requests_per_second.map(|x| x as u64), - max_retries: Some(args.max_retries), - initial_backoff: Some(args.initial_backoff), - }, + let labels = SourceLabels { + max_concurrent_requests: args.max_concurrent_requests, + max_requests_per_second: args.requests_per_second.map(|x| x as u64), + max_retries: Some(args.max_retries), + initial_backoff: Some(args.initial_backoff), }; - Ok(output) + let source = Source::builder() + .rpc_url(rpc_url.clone()) + .inner_request_size(args.inner_request_size) + .max_concurrent_chunks(max_concurrent_chunks) + .semaphore(Some(semaphore)) + .rate_limiter(rate_limiter) + .jwt(jwt) + .labels(labels) + .retry_policy(args.max_retries, args.initial_backoff, args.compute_units_per_second) + .build() + .await + .map_err(|e| ParseError::ParseError(format!("failed to build Source: {e}")))?; + + Ok(source) } pub(crate) fn parse_rpc_url(args: &Args) -> Result { @@ -79,7 +67,7 @@ pub(crate) fn parse_rpc_url(args: &Args) -> Result { match endpoint { Ok(endpoint) => endpoint.map(|endpoint| endpoint.url), Err(e) => { - eprintln!("Could not load MESC data: {}", e); + error!("Could not load MESC data: {e}"); None } } @@ -100,9 +88,5 @@ pub(crate) fn parse_rpc_url(args: &Args) -> Result { }; // prepend http or https if need be - if !url.starts_with("http") & !url.starts_with("ws") & !url.ends_with(".ipc") { - Ok("http://".to_string() + url.as_str()) - } else { - Ok(url) - } + Ok(url) } diff --git a/crates/cli/src/parse/timestamps.rs b/crates/cli/src/parse/timestamps.rs index 35b54ab8..82d2d833 100644 --- a/crates/cli/src/parse/timestamps.rs +++ b/crates/cli/src/parse/timestamps.rs @@ -24,7 +24,7 @@ pub(crate) async fn parse_timestamps( for path in files { let column = if path.contains(':') { path.split(':') - .last() + .next_back() .ok_or(ParseError::ParseError("could not parse txs path column".to_string()))? } else { "timestamp" @@ -325,9 +325,9 @@ mod tests { use std::num::NonZeroU32; use alloy::{ - providers::ProviderBuilder, - rpc::client::{BuiltInConnectionString, ClientBuilder, RpcClient}, - transports::{layers::RetryBackoffLayer, BoxTransport}, + providers::{Provider, ProviderBuilder}, + rpc::client::ClientBuilder, + transports::layers::RetryBackoffLayer, }; use governor::{Quota, RateLimiter}; @@ -345,16 +345,13 @@ mod tests { let max_concurrent_requests = 100; let retry_layer = RetryBackoffLayer::new(max_retry, initial_backoff, compute_units_per_second); - let connect: BuiltInConnectionString = - rpc_url.parse().map_err(ParseError::ProviderError).unwrap(); - let client: RpcClient = ClientBuilder::default() + let client = ClientBuilder::default() .layer(retry_layer) - .connect_boxed(connect) + .connect(&rpc_url) .await .map_err(ParseError::ProviderError) - .unwrap() - .boxed(); - let provider = ProviderBuilder::default().on_client(client); + .unwrap(); + let provider = ProviderBuilder::default().connect_client(client).erased(); let quota = Quota::per_second(NonZeroU32::new(15).unwrap()) .allow_burst(NonZeroU32::new(1).unwrap()); let rate_limiter = Some(RateLimiter::direct(quota)); @@ -368,6 +365,7 @@ mod tests { inner_request_size: 1, max_concurrent_chunks: None, rpc_url: "".to_string(), + jwt: None, labels: SourceLabels::default(), } } diff --git a/crates/cli/src/run.rs b/crates/cli/src/run.rs index 7251348c..b57a64ea 100644 --- a/crates/cli/src/run.rs +++ b/crates/cli/src/run.rs @@ -1,5 +1,5 @@ use crate::{args, parse, remember}; -use clap_cryo::Parser; +use clap::Parser; use color_print::cstr; use colored::Colorize; use cryo_freeze::{err, CollectError, ExecutionEnv, FreezeSummary}; @@ -43,7 +43,7 @@ fn load_or_remember_command( let remembered = remember::load_remembered_command(cryo_dir.to_path_buf())?; // Warn if the remembered command comes from a different Cryo version. if remembered.cryo_version != cryo_freeze::CRYO_VERSION { - eprintln!("remembered command comes from a different Cryo version, proceed with caution\n"); + warn!("remembered command comes from a different Cryo version, proceed with caution\n"); } print_remembered_command(&remembered.command); args = args.merge_with_precedence(remembered.args); @@ -114,7 +114,7 @@ fn print_syntax_help() { (default column name is transaction_hash) - can use multiple parquet files --txs ./path/to/ethereum__logs*.parquet"# ); - println!("{}", content); + println!("{content}"); } /// Handle detailed help by parsing schemas and printing dataset information. @@ -129,7 +129,7 @@ fn handle_detailed_help(args: args::Args) -> Result<(), CollectError> { if let Some(schema) = schemas.get(&datatype) { cryo_freeze::print_dataset_info(datatype, schema); } else { - return Err(err(format!("missing schema for datatype: {:?}", datatype).as_str())); + return Err(err(format!("missing schema for datatype: {datatype:?}").as_str())); } } diff --git a/crates/freeze/Cargo.toml b/crates/freeze/Cargo.toml index b6df7eb9..916c2e2f 100644 --- a/crates/freeze/Cargo.toml +++ b/crates/freeze/Cargo.toml @@ -12,6 +12,7 @@ repository.workspace = true [dependencies] alloy = { workspace = true } +alloy-transport-http = { workspace = true } async-trait = { workspace = true } chrono = { workspace = true } colored = { workspace = true } @@ -19,15 +20,23 @@ cryo_to_df = { workspace = true } futures = { workspace = true } governor = { workspace = true } heck = { workspace = true } +http-body-util = "0.1.3" indexmap = { workspace = true } indicatif = { workspace = true } mesc = { workspace = true } polars = { workspace = true } -prefix-hex = { workspace = true } regex = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } thiserror = { workspace = true } thousands = { workspace = true } tokio = { workspace = true } -url = "2.5.2" +tower = "0.5.2" +tracing = { workspace = true } +url = "2.5.7" + +[features] +default = ["reqwest-default-tls"] +reqwest-default-tls = ["alloy/reqwest"] +reqwest-native-tls = ["alloy/reqwest-native-tls"] +reqwest-rustls-tls = ["alloy/reqwest-rustls-tls"] diff --git a/crates/freeze/build.rs b/crates/freeze/build.rs index 6aa435a9..5485b6b0 100644 --- a/crates/freeze/build.rs +++ b/crates/freeze/build.rs @@ -4,7 +4,7 @@ fn main() { let git_description = get_git_description().unwrap_or_else(|_| env!("CARGO_PKG_VERSION").to_string()); - println!("cargo:rustc-env=GIT_DESCRIPTION={}", git_description); + println!("cargo:rustc-env=GIT_DESCRIPTION={git_description}"); } fn get_git_description() -> Result { @@ -18,6 +18,6 @@ fn get_git_description() -> Result { Ok(description) } else { - Err(std::io::Error::new(std::io::ErrorKind::Other, "Git command failed")) + Err(std::io::Error::other("Git command failed")) } } diff --git a/crates/freeze/src/datasets/address_appearances.rs b/crates/freeze/src/datasets/address_appearances.rs index c3600105..c93ab223 100644 --- a/crates/freeze/src/datasets/address_appearances.rs +++ b/crates/freeze/src/datasets/address_appearances.rs @@ -12,14 +12,13 @@ use polars::prelude::*; use std::collections::HashMap; /// columns for transactions -#[cryo_to_df::to_df(Datatype::AddressAppearances)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct AddressAppearances { n_rows: usize, block_number: Vec, - block_hash: Vec>, - transaction_hash: Vec>, - address: Vec>, + block_hash: Vec, + transaction_hash: Vec, + address: Vec, relationship: Vec, chain_id: Vec, } @@ -114,7 +113,7 @@ impl CollectByTransaction for AddressAppearances { fn name(log: &Log) -> Option<&'static str> { let event = log.topic0().unwrap(); if event == *ERC20::Transfer::SIGNATURE_HASH { - if log.data().data.len() > 0 { + if !log.data().data.is_empty() { Some("erc20_transfer") } else if log.topics().len() == 4 { Some("erc721_transfer") diff --git a/crates/freeze/src/datasets/balance_diffs.rs b/crates/freeze/src/datasets/balance_diffs.rs index 595f0d34..2273bc1c 100644 --- a/crates/freeze/src/datasets/balance_diffs.rs +++ b/crates/freeze/src/datasets/balance_diffs.rs @@ -6,14 +6,13 @@ use alloy::{ use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::BalanceDiffs)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct BalanceDiffs { pub(crate) n_rows: u64, pub(crate) block_number: Vec>, pub(crate) transaction_index: Vec>, - pub(crate) transaction_hash: Vec>>, - pub(crate) address: Vec>, + pub(crate) transaction_hash: Vec>, + pub(crate) address: Vec, pub(crate) from_value: Vec, pub(crate) to_value: Vec, pub(crate) chain_id: Vec, @@ -22,7 +21,7 @@ pub struct BalanceDiffs { #[async_trait::async_trait] impl Dataset for BalanceDiffs {} -type BlockTxsTraces = (Option, Vec>>, Vec); +type BlockTxsTraces = (Option, Vec>, Vec); #[async_trait::async_trait] impl CollectByBlock for BalanceDiffs { @@ -77,7 +76,7 @@ pub(crate) fn process_balance_diff( addr: &Address, diff: &Delta, block_number: &Option, - transaction_hash: &Option>, + transaction_hash: &Option, transaction_index: usize, columns: &mut BalanceDiffs, schema: &Table, diff --git a/crates/freeze/src/datasets/balance_reads.rs b/crates/freeze/src/datasets/balance_reads.rs index 6f9ba0ab..933737f1 100644 --- a/crates/freeze/src/datasets/balance_reads.rs +++ b/crates/freeze/src/datasets/balance_reads.rs @@ -7,14 +7,13 @@ use polars::prelude::*; use std::collections::BTreeMap; /// columns for transactions -#[cryo_to_df::to_df(Datatype::BalanceReads)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct BalanceReads { pub(crate) n_rows: u64, pub(crate) block_number: Vec>, pub(crate) transaction_index: Vec>, - pub(crate) transaction_hash: Vec>>, - pub(crate) address: Vec>, + pub(crate) transaction_hash: Vec>, + pub(crate) address: Vec, pub(crate) balance: Vec, pub(crate) chain_id: Vec, } @@ -22,7 +21,7 @@ pub struct BalanceReads { #[async_trait::async_trait] impl Dataset for BalanceReads {} -type BlockTxsTraces = (Option, Vec>>, Vec>); +type BlockTxsTraces = (Option, Vec>, Vec>); #[async_trait::async_trait] impl CollectByBlock for BalanceReads { @@ -76,7 +75,7 @@ pub(crate) fn process_balance_read( addr: &Address, account_state: &AccountState, block_number: &Option, - transaction_hash: &Option>, + transaction_hash: &Option, transaction_index: usize, columns: &mut BalanceReads, schema: &Table, diff --git a/crates/freeze/src/datasets/balances.rs b/crates/freeze/src/datasets/balances.rs index 5b0583a1..d6632c10 100644 --- a/crates/freeze/src/datasets/balances.rs +++ b/crates/freeze/src/datasets/balances.rs @@ -3,12 +3,11 @@ use alloy::primitives::{Address, U256}; use polars::prelude::*; /// columns for balances -#[cryo_to_df::to_df(Datatype::Balances)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct Balances { n_rows: usize, block_number: Vec, - address: Vec>, + address: Vec, balance: Vec, chain_id: Vec, } @@ -28,7 +27,7 @@ impl Dataset for Balances { } } -type BlockTxAddressOutput = (u32, Option>, Vec, U256); +type BlockTxAddressOutput = (u32, Option, RawBytes, U256); #[async_trait::async_trait] impl CollectByBlock for Balances { diff --git a/crates/freeze/src/datasets/blocks.rs b/crates/freeze/src/datasets/blocks.rs index d259a797..3f5d59bb 100644 --- a/crates/freeze/src/datasets/blocks.rs +++ b/crates/freeze/src/datasets/blocks.rs @@ -6,30 +6,29 @@ use alloy::{ use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::Blocks)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct Blocks { n_rows: u64, - block_hash: Vec>>, - parent_hash: Vec>, - uncles_hash: Vec>, - author: Vec>>, - state_root: Vec>, - transactions_root: Vec>, - receipts_root: Vec>, + block_hash: Vec>, + parent_hash: Vec, + uncles_hash: Vec, + author: Vec>, + state_root: Vec, + transactions_root: Vec, + receipts_root: Vec, block_number: Vec>, gas_used: Vec, gas_limit: Vec, - extra_data: Vec>, - logs_bloom: Vec>>, + extra_data: Vec, + logs_bloom: Vec>, timestamp: Vec, difficulty: Vec, total_difficulty: Vec>, size: Vec>, - mix_hash: Vec>>, - nonce: Vec>>, + mix_hash: Vec>, + nonce: Vec>, base_fee_per_gas: Vec>, - withdrawals_root: Vec>>, + withdrawals_root: Vec>, chain_id: Vec, } diff --git a/crates/freeze/src/datasets/code_diffs.rs b/crates/freeze/src/datasets/code_diffs.rs index f8893b37..87b062a5 100644 --- a/crates/freeze/src/datasets/code_diffs.rs +++ b/crates/freeze/src/datasets/code_diffs.rs @@ -6,23 +6,22 @@ use alloy::{ use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::CodeDiffs)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct CodeDiffs { pub(crate) n_rows: u64, pub(crate) block_number: Vec>, pub(crate) transaction_index: Vec>, - pub(crate) transaction_hash: Vec>>, - pub(crate) address: Vec>, - pub(crate) from_value: Vec>, - pub(crate) to_value: Vec>, + pub(crate) transaction_hash: Vec>, + pub(crate) address: Vec, + pub(crate) from_value: Vec, + pub(crate) to_value: Vec, pub(crate) chain_id: Vec, } #[async_trait::async_trait] impl Dataset for CodeDiffs {} -type BlockTxTraces = (Option, Vec>>, Vec); +type BlockTxTraces = (Option, Vec>, Vec); #[async_trait::async_trait] impl CollectByBlock for CodeDiffs { @@ -76,7 +75,7 @@ pub(crate) fn process_code_diff( addr: &Address, diff: &Delta, block_number: &Option, - transaction_hash: &Option>, + transaction_hash: &Option, transaction_index: usize, columns: &mut CodeDiffs, schema: &Table, diff --git a/crates/freeze/src/datasets/code_reads.rs b/crates/freeze/src/datasets/code_reads.rs index 1127e5cb..362788cc 100644 --- a/crates/freeze/src/datasets/code_reads.rs +++ b/crates/freeze/src/datasets/code_reads.rs @@ -4,22 +4,21 @@ use polars::prelude::*; use std::collections::BTreeMap; /// columns for transactions -#[cryo_to_df::to_df(Datatype::CodeReads)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct CodeReads { pub(crate) n_rows: u64, pub(crate) block_number: Vec>, pub(crate) transaction_index: Vec>, - pub(crate) transaction_hash: Vec>>, - pub(crate) contract_address: Vec>, - pub(crate) code: Vec>, + pub(crate) transaction_hash: Vec>, + pub(crate) contract_address: Vec, + pub(crate) code: Vec, pub(crate) chain_id: Vec, } #[async_trait::async_trait] impl Dataset for CodeReads {} -type BlockTxsTraces = (Option, Vec>>, Vec>); +type BlockTxsTraces = (Option, Vec>, Vec>); #[async_trait::async_trait] impl CollectByBlock for CodeReads { @@ -71,7 +70,7 @@ pub(crate) fn process_code_read( addr: &Address, account_state: &AccountState, block_number: &Option, - transaction_hash: &Option>, + transaction_hash: &Option, transaction_index: usize, columns: &mut CodeReads, schema: &Table, diff --git a/crates/freeze/src/datasets/codes.rs b/crates/freeze/src/datasets/codes.rs index 16bc5dca..9015f326 100644 --- a/crates/freeze/src/datasets/codes.rs +++ b/crates/freeze/src/datasets/codes.rs @@ -3,13 +3,12 @@ use alloy::primitives::Address; use polars::prelude::*; /// columns for balances -#[cryo_to_df::to_df(Datatype::Codes)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct Codes { n_rows: usize, block_number: Vec, - address: Vec>, - code: Vec>, + address: Vec, + code: Vec, chain_id: Vec, } @@ -32,7 +31,7 @@ impl Dataset for Codes { } } -type BlockTxAddressOutput = (u32, Option>, Vec, Vec); +type BlockTxAddressOutput = (u32, Option, RawBytes, RawBytes); #[async_trait::async_trait] impl CollectByBlock for Codes { diff --git a/crates/freeze/src/datasets/contracts.rs b/crates/freeze/src/datasets/contracts.rs index 7df089a2..fb779a37 100644 --- a/crates/freeze/src/datasets/contracts.rs +++ b/crates/freeze/src/datasets/contracts.rs @@ -7,23 +7,22 @@ use alloy::{ use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::Contracts)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct Contracts { n_rows: u64, block_number: Vec, - block_hash: Vec>, + block_hash: Vec, create_index: Vec, - transaction_hash: Vec>>, - contract_address: Vec>, - deployer: Vec>, - factory: Vec>, - init_code: Vec>, - code: Vec>, - init_code_hash: Vec>, + transaction_hash: Vec>, + contract_address: Vec, + deployer: Vec, + factory: Vec, + init_code: Vec, + code: Vec, + init_code_hash: Vec, n_init_code_bytes: Vec, n_code_bytes: Vec, - code_hash: Vec>, + code_hash: Vec, chain_id: Vec, } diff --git a/crates/freeze/src/datasets/erc20_approvals.rs b/crates/freeze/src/datasets/erc20_approvals.rs index acba313a..765b489e 100644 --- a/crates/freeze/src/datasets/erc20_approvals.rs +++ b/crates/freeze/src/datasets/erc20_approvals.rs @@ -7,18 +7,17 @@ use alloy::{ use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::Erc20Approvals)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct Erc20Approvals { n_rows: u64, block_number: Vec, - block_hash: Vec>>, + block_hash: Vec>, transaction_index: Vec, log_index: Vec, - transaction_hash: Vec>, - erc20: Vec>, - from_address: Vec>, - to_address: Vec>, + transaction_hash: Vec, + erc20: Vec, + from_address: Vec, + to_address: Vec, value: Vec, chain_id: Vec, } diff --git a/crates/freeze/src/datasets/erc20_balances.rs b/crates/freeze/src/datasets/erc20_balances.rs index 70fd4f86..f09f6125 100644 --- a/crates/freeze/src/datasets/erc20_balances.rs +++ b/crates/freeze/src/datasets/erc20_balances.rs @@ -3,13 +3,12 @@ use alloy::{primitives::U256, sol_types::SolCall}; use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::Erc20Balances)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct Erc20Balances { n_rows: u64, block_number: Vec, - erc20: Vec>, - address: Vec>, + erc20: Vec, + address: Vec, balance: Vec>, chain_id: Vec, } @@ -27,7 +26,7 @@ impl Dataset for Erc20Balances { #[async_trait::async_trait] impl CollectByBlock for Erc20Balances { - type Response = (u32, Vec, Vec, Option); + type Response = (u32, RawBytes, RawBytes, Option); async fn extract(request: Params, source: Arc, _: Arc) -> R { let signature = ERC20::balanceOfCall::SELECTOR; diff --git a/crates/freeze/src/datasets/erc20_metadata.rs b/crates/freeze/src/datasets/erc20_metadata.rs index ec254c92..362069fb 100644 --- a/crates/freeze/src/datasets/erc20_metadata.rs +++ b/crates/freeze/src/datasets/erc20_metadata.rs @@ -3,12 +3,11 @@ use alloy::sol_types::SolCall; use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::Erc20Metadata)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct Erc20Metadata { n_rows: u64, block_number: Vec, - erc20: Vec>, + erc20: Vec, name: Vec>, symbol: Vec>, decimals: Vec>, @@ -41,7 +40,7 @@ pub(crate) fn remove_control_characters(s: &str) -> String { #[async_trait::async_trait] impl CollectByBlock for Erc20Metadata { - type Response = (u32, Vec, Option, Option, Option); + type Response = (u32, RawBytes, Option, Option, Option); async fn extract(request: Params, source: Arc, _: Arc) -> R { let block_number = request.ethers_block_number()?; diff --git a/crates/freeze/src/datasets/erc20_supplies.rs b/crates/freeze/src/datasets/erc20_supplies.rs index d02f1cab..96578fa2 100644 --- a/crates/freeze/src/datasets/erc20_supplies.rs +++ b/crates/freeze/src/datasets/erc20_supplies.rs @@ -3,12 +3,11 @@ use alloy::{primitives::U256, sol_types::SolCall}; use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::Erc20Supplies)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct Erc20Supplies { n_rows: u64, block_number: Vec, - erc20: Vec>, + erc20: Vec, total_supply: Vec>, chain_id: Vec, } @@ -34,10 +33,10 @@ impl Dataset for Erc20Supplies { #[async_trait::async_trait] impl CollectByBlock for Erc20Supplies { - type Response = (u32, Vec, Option); + type Response = (u32, RawBytes, Option); async fn extract(request: Params, source: Arc, _: Arc) -> R { - let signature: Vec = ERC20::totalSupplyCall::SELECTOR.to_vec(); + let signature: RawBytes = ERC20::totalSupplyCall::SELECTOR.to_vec(); let mut call_data = signature.clone(); call_data.extend(request.address()?); let block_number = request.ethers_block_number()?; diff --git a/crates/freeze/src/datasets/erc20_transfers.rs b/crates/freeze/src/datasets/erc20_transfers.rs index 6881266b..35bfea58 100644 --- a/crates/freeze/src/datasets/erc20_transfers.rs +++ b/crates/freeze/src/datasets/erc20_transfers.rs @@ -7,18 +7,17 @@ use alloy::{ use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::Erc20Transfers)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct Erc20Transfers { n_rows: u64, block_number: Vec, - block_hash: Vec>>, + block_hash: Vec>, transaction_index: Vec, log_index: Vec, - transaction_hash: Vec>, - erc20: Vec>, - from_address: Vec>, - to_address: Vec>, + transaction_hash: Vec, + erc20: Vec, + from_address: Vec, + to_address: Vec, value: Vec, chain_id: Vec, } diff --git a/crates/freeze/src/datasets/erc721_metadata.rs b/crates/freeze/src/datasets/erc721_metadata.rs index 734f2d70..3eea87c8 100644 --- a/crates/freeze/src/datasets/erc721_metadata.rs +++ b/crates/freeze/src/datasets/erc721_metadata.rs @@ -4,12 +4,11 @@ use alloy::sol_types::SolCall; use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::Erc721Metadata)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct Erc721Metadata { n_rows: u64, block_number: Vec, - erc721: Vec>, + erc721: Vec, name: Vec>, symbol: Vec>, chain_id: Vec, @@ -31,7 +30,7 @@ impl Dataset for Erc721Metadata { #[async_trait::async_trait] impl CollectByBlock for Erc721Metadata { - type Response = (u32, Vec, Option, Option); + type Response = (u32, RawBytes, Option, Option); async fn extract(request: Params, source: Arc, _: Arc) -> R { let block_number = request.ethers_block_number()?; diff --git a/crates/freeze/src/datasets/erc721_transfers.rs b/crates/freeze/src/datasets/erc721_transfers.rs index 065dc176..c27baab0 100644 --- a/crates/freeze/src/datasets/erc721_transfers.rs +++ b/crates/freeze/src/datasets/erc721_transfers.rs @@ -7,18 +7,17 @@ use alloy::{ use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::Erc721Transfers)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct Erc721Transfers { n_rows: u64, block_number: Vec, - block_hash: Vec>>, + block_hash: Vec>, transaction_index: Vec, log_index: Vec, - transaction_hash: Vec>, - erc20: Vec>, - from_address: Vec>, - to_address: Vec>, + transaction_hash: Vec, + erc20: Vec, + from_address: Vec, + to_address: Vec, token_id: Vec, chain_id: Vec, } @@ -71,7 +70,7 @@ impl CollectByBlock for Erc721Transfers { let filter = Filter { topics, ..request.ethers_log_filter()? }; let logs = source.get_logs(&filter).await?; - Ok(logs.into_iter().filter(|x| x.topics().len() == 4 && x.data().data.len() == 0).collect()) + Ok(logs.into_iter().filter(|x| x.topics().len() == 4 && x.data().data.is_empty()).collect()) } fn transform(response: Self::Response, columns: &mut Self, query: &Arc) -> R<()> { @@ -97,7 +96,7 @@ impl CollectByTransaction for Erc721Transfers { fn is_erc721_transfer(log: &Log) -> bool { log.topics().len() == 4 && - log.data().data.len() == 0 && + log.data().data.is_empty() && log.topics()[0] == ERC721::Transfer::SIGNATURE_HASH } diff --git a/crates/freeze/src/datasets/eth_calls.rs b/crates/freeze/src/datasets/eth_calls.rs index 203528f8..dfc4b340 100644 --- a/crates/freeze/src/datasets/eth_calls.rs +++ b/crates/freeze/src/datasets/eth_calls.rs @@ -6,16 +6,15 @@ use alloy::{ use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::EthCalls)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct EthCalls { n_rows: u64, block_number: Vec, - contract_address: Vec>, - call_data: Vec>, - call_data_hash: Vec>, - output_data: Vec>>, - output_data_hash: Vec>>, + contract_address: Vec, + call_data: Vec, + call_data_hash: Vec, + output_data: Vec>, + output_data_hash: Vec>, chain_id: Vec, } @@ -42,7 +41,7 @@ impl Dataset for EthCalls { } } -type EthCallsResponse = (u32, Vec, Vec, Option>); +type EthCallsResponse = (u32, RawBytes, RawBytes, Option); #[async_trait::async_trait] impl CollectByBlock for EthCalls { diff --git a/crates/freeze/src/datasets/four_byte_counts.rs b/crates/freeze/src/datasets/four_byte_counts.rs index 01d7145d..5d0778ac 100644 --- a/crates/freeze/src/datasets/four_byte_counts.rs +++ b/crates/freeze/src/datasets/four_byte_counts.rs @@ -3,14 +3,13 @@ use polars::prelude::*; use std::collections::BTreeMap; /// columns for transactions -#[cryo_to_df::to_df(Datatype::FourByteCounts)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct FourByteCounts { pub(crate) n_rows: u64, pub(crate) block_number: Vec>, pub(crate) transaction_index: Vec>, - pub(crate) transaction_hash: Vec>>, - pub(crate) signature: Vec>, + pub(crate) transaction_hash: Vec>, + pub(crate) signature: Vec, pub(crate) size: Vec, pub(crate) count: Vec, pub(crate) chain_id: Vec, @@ -23,7 +22,7 @@ impl Dataset for FourByteCounts { } } -type BlockTxsTraces = (Option, Vec>>, Vec>); +type BlockTxsTraces = (Option, Vec>, Vec>); #[async_trait::async_trait] impl CollectByBlock for FourByteCounts { @@ -82,7 +81,7 @@ pub(crate) fn process_storage_reads( Ok(()) } -fn parse_signature_size(signature_size: &str) -> R<(Vec, u64)> { +fn parse_signature_size(signature_size: &str) -> R<(RawBytes, u64)> { let parts: Vec<&str> = signature_size.splitn(2, '-').collect(); if parts.len() != 2 { return Err(err("could not parse 4byte-size pair")) @@ -93,7 +92,7 @@ fn parse_signature_size(signature_size: &str) -> R<(Vec, u64)> { let bytes = (0..hex_part.len()) .step_by(2) .map(|i| u8::from_str_radix(&hex_part[i..i + 2], 16)) - .collect::, _>>() + .collect::>() .map_err(|_| err("could not parse signature bytes"))?; // Parse the number as u64 diff --git a/crates/freeze/src/datasets/geth_balance_diffs.rs b/crates/freeze/src/datasets/geth_balance_diffs.rs index a7197150..e0bb74d1 100644 --- a/crates/freeze/src/datasets/geth_balance_diffs.rs +++ b/crates/freeze/src/datasets/geth_balance_diffs.rs @@ -3,14 +3,13 @@ use alloy::primitives::U256; use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::GethBalanceDiffs)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct GethBalanceDiffs { pub(crate) n_rows: u64, pub(crate) block_number: Vec>, pub(crate) transaction_index: Vec>, - pub(crate) transaction_hash: Vec>>, - pub(crate) address: Vec>, + pub(crate) transaction_hash: Vec>, + pub(crate) address: Vec, pub(crate) from_value: Vec, pub(crate) to_value: Vec, pub(crate) chain_id: Vec, diff --git a/crates/freeze/src/datasets/geth_calls.rs b/crates/freeze/src/datasets/geth_calls.rs index db5df396..680d6a71 100644 --- a/crates/freeze/src/datasets/geth_calls.rs +++ b/crates/freeze/src/datasets/geth_calls.rs @@ -3,21 +3,20 @@ use alloy::{primitives::U256, rpc::types::trace::geth::CallFrame}; use polars::prelude::*; /// columns for geth traces -#[cryo_to_df::to_df(Datatype::GethCalls)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct GethCalls { n_rows: u64, typ: Vec, - from_address: Vec>, - to_address: Vec>>, + from_address: Vec, + to_address: Vec>, value: Vec>, gas: Vec, gas_used: Vec, - input: Vec>, - output: Vec>>, + input: Vec, + output: Vec>, error: Vec>, block_number: Vec>, - transaction_hash: Vec>>, + transaction_hash: Vec>, transaction_index: Vec, trace_address: Vec, chain_id: Vec, @@ -28,7 +27,7 @@ impl Dataset for GethCalls {} #[async_trait::async_trait] impl CollectByBlock for GethCalls { - type Response = (Option, Vec>>, Vec); + type Response = (Option, Vec>, Vec); async fn extract(request: Params, source: Arc, query: Arc) -> R { let schema = query.schemas.get_schema(&Datatype::GethCalls)?; @@ -44,7 +43,7 @@ impl CollectByBlock for GethCalls { #[async_trait::async_trait] impl CollectByTransaction for GethCalls { - type Response = (Option, Vec>>, Vec); + type Response = (Option, Vec>, Vec); async fn extract(request: Params, source: Arc, query: Arc) -> R { let schema = query.schemas.get_schema(&Datatype::GethCalls)?; @@ -60,7 +59,7 @@ impl CollectByTransaction for GethCalls { } fn process_geth_traces( - traces: (Option, Vec>>, Vec), + traces: (Option, Vec>, Vec), columns: &mut GethCalls, schemas: &Schemas, ) -> R<()> { @@ -77,7 +76,7 @@ fn process_trace( columns: &mut GethCalls, schema: &Table, block_number: &Option, - tx: &Option>, + tx: &Option, tx_index: u32, trace_address: Vec, ) -> R<()> { diff --git a/crates/freeze/src/datasets/geth_code_diffs.rs b/crates/freeze/src/datasets/geth_code_diffs.rs index 9982b7de..a5bfc6db 100644 --- a/crates/freeze/src/datasets/geth_code_diffs.rs +++ b/crates/freeze/src/datasets/geth_code_diffs.rs @@ -2,16 +2,15 @@ use crate::*; use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::GethCodeDiffs)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct GethCodeDiffs { pub(crate) n_rows: u64, pub(crate) block_number: Vec>, pub(crate) transaction_index: Vec>, - pub(crate) transaction_hash: Vec>>, - pub(crate) address: Vec>, - pub(crate) from_value: Vec>, - pub(crate) to_value: Vec>, + pub(crate) transaction_hash: Vec>, + pub(crate) address: Vec, + pub(crate) from_value: Vec, + pub(crate) to_value: Vec, pub(crate) chain_id: Vec, } diff --git a/crates/freeze/src/datasets/geth_nonce_diffs.rs b/crates/freeze/src/datasets/geth_nonce_diffs.rs index 47a86b02..76697371 100644 --- a/crates/freeze/src/datasets/geth_nonce_diffs.rs +++ b/crates/freeze/src/datasets/geth_nonce_diffs.rs @@ -2,14 +2,13 @@ use crate::*; use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::GethNonceDiffs)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct GethNonceDiffs { pub(crate) n_rows: u64, pub(crate) block_number: Vec>, pub(crate) transaction_index: Vec>, - pub(crate) transaction_hash: Vec>>, - pub(crate) address: Vec>, + pub(crate) transaction_hash: Vec>, + pub(crate) address: Vec, pub(crate) from_value: Vec, pub(crate) to_value: Vec, pub(crate) chain_id: Vec, diff --git a/crates/freeze/src/datasets/geth_opcodes.rs b/crates/freeze/src/datasets/geth_opcodes.rs index 95f519b1..74648a5d 100644 --- a/crates/freeze/src/datasets/geth_opcodes.rs +++ b/crates/freeze/src/datasets/geth_opcodes.rs @@ -5,12 +5,11 @@ use alloy::rpc::types::trace::geth::{ use polars::prelude::*; /// columns for geth traces -#[cryo_to_df::to_df(Datatype::GethOpcodes)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct GethOpcodes { n_rows: u64, block_number: Vec>, - transaction_hash: Vec>>, + transaction_hash: Vec>, transaction_index: Vec, trace_address: Vec, depth: Vec, @@ -24,7 +23,7 @@ pub struct GethOpcodes { memory: Vec>, stack: Vec>, storage: Vec>, - return_data: Vec>>, + return_data: Vec>, chain_id: Vec, } @@ -38,7 +37,7 @@ impl Dataset for GethOpcodes { #[async_trait::async_trait] impl CollectByBlock for GethOpcodes { - type Response = (Option, Vec>>, Vec); + type Response = (Option, Vec>, Vec); async fn extract(request: Params, source: Arc, query: Arc) -> R { let schema = query.schemas.get_schema(&Datatype::GethOpcodes)?; @@ -69,7 +68,7 @@ impl CollectByBlock for GethOpcodes { #[async_trait::async_trait] impl CollectByTransaction for GethOpcodes { - type Response = (Option, Vec>>, Vec); + type Response = (Option, Vec>, Vec); async fn extract(request: Params, source: Arc, query: Arc) -> R { let schema = query.schemas.get_schema(&Datatype::GethOpcodes)?; @@ -97,7 +96,7 @@ impl CollectByTransaction for GethOpcodes { } fn process_geth_opcodes( - traces: (Option, Vec>>, Vec), + traces: (Option, Vec>, Vec), columns: &mut GethOpcodes, schemas: &Schemas, ) -> R<()> { @@ -115,7 +114,7 @@ fn process_trace( columns: &mut GethOpcodes, schema: &Table, block_number: &Option, - tx: &Option>, + tx: &Option, tx_index: u32, trace_address: Vec, ) -> R<()> { @@ -138,7 +137,7 @@ fn process_trace( store!(schema, columns, gas, struct_log.gas); store!(schema, columns, gas_cost, struct_log.gas_cost); store!(schema, columns, pc, struct_log.pc); - store!(schema, columns, op, struct_log.op); + store!(schema, columns, op, struct_log.op.to_string()); store!(schema, columns, refund_counter, struct_log.refund_counter); if schema.has_column("memory") { diff --git a/crates/freeze/src/datasets/geth_storage_diffs.rs b/crates/freeze/src/datasets/geth_storage_diffs.rs index 62e964be..da139a6e 100644 --- a/crates/freeze/src/datasets/geth_storage_diffs.rs +++ b/crates/freeze/src/datasets/geth_storage_diffs.rs @@ -2,17 +2,16 @@ use crate::*; use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::GethStorageDiffs)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct GethStorageDiffs { pub(crate) n_rows: u64, pub(crate) block_number: Vec>, pub(crate) transaction_index: Vec>, - pub(crate) transaction_hash: Vec>>, - pub(crate) address: Vec>, - pub(crate) slot: Vec>, - pub(crate) from_value: Vec>, - pub(crate) to_value: Vec>, + pub(crate) transaction_hash: Vec>, + pub(crate) address: Vec, + pub(crate) slot: Vec, + pub(crate) from_value: Vec, + pub(crate) to_value: Vec, pub(crate) chain_id: Vec, } diff --git a/crates/freeze/src/datasets/javascript_traces.rs b/crates/freeze/src/datasets/javascript_traces.rs index 056d3543..c1fdeff6 100644 --- a/crates/freeze/src/datasets/javascript_traces.rs +++ b/crates/freeze/src/datasets/javascript_traces.rs @@ -2,13 +2,12 @@ use crate::*; use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::JavascriptTraces)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct JavascriptTraces { pub(crate) n_rows: u64, pub(crate) block_number: Vec>, pub(crate) transaction_index: Vec>, - pub(crate) transaction_hash: Vec>>, + pub(crate) transaction_hash: Vec>, pub(crate) output: Vec, pub(crate) chain_id: Vec, } @@ -20,7 +19,7 @@ impl Dataset for JavascriptTraces { } } -type BlockTxsTraces = (Option, Vec>>, Vec); +type BlockTxsTraces = (Option, Vec>, Vec); #[async_trait::async_trait] impl CollectByBlock for JavascriptTraces { diff --git a/crates/freeze/src/datasets/logs.rs b/crates/freeze/src/datasets/logs.rs index 01313f6d..397d0a14 100644 --- a/crates/freeze/src/datasets/logs.rs +++ b/crates/freeze/src/datasets/logs.rs @@ -1,27 +1,27 @@ use crate::*; use alloy::{ - dyn_abi::{DynSolType, DynSolValue, EventExt}, + dyn_abi::{DynSolValue, EventExt}, rpc::types::Log, }; use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::Logs)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct Logs { n_rows: u64, block_number: Vec, - block_hash: Vec>>, + block_hash: Vec>, transaction_index: Vec, log_index: Vec, - transaction_hash: Vec>, - address: Vec>, - topic0: Vec>>, - topic1: Vec>>, - topic2: Vec>>, - topic3: Vec>>, - data: Vec>, + transaction_hash: Vec, + address: Vec, + topic0: Vec>, + topic1: Vec>, + topic2: Vec>, + topic3: Vec>, + data: Vec, n_data_bytes: Vec, + #[to_df(flatten = "extract_event_cols")] event_cols: indexmap::IndexMap>, chain_id: Vec, } @@ -110,20 +110,8 @@ fn process_logs(logs: Vec, columns: &mut Logs, schema: &Table) -> R<()> { let (indexed_keys, body_keys) = match &schema.log_decoder { None => (None, None), Some(decoder) => { - let indexed: Vec = decoder - .event - .inputs - .clone() - .into_iter() - .filter_map(|x| if x.indexed { Some(x.name) } else { None }) - .collect(); - let body: Vec = decoder - .event - .inputs - .clone() - .into_iter() - .filter_map(|x| if x.indexed { None } else { Some(x.name) }) - .collect(); + let indexed = decoder.indexed_names(); + let body = decoder.body_names(); (Some(indexed), Some(body)) } }; @@ -136,26 +124,30 @@ fn process_logs(logs: Vec, columns: &mut Logs, schema: &Table) -> R<()> { if let (Some(decoder), Some(indexed_keys), Some(body_keys)) = (&schema.log_decoder, &indexed_keys, &body_keys) { - match decoder.event.decode_log(&log.inner.data, true) { + match decoder.event.decode_log(&log.inner.data) { Ok(log) => { // for param in log.indexed { // if decode_keys.contains(param.name.as_str()) { // columns.event_cols.entry(param.name).or_default().push(param. // value); } // } - for (idx, indexed_param) in log.indexed.into_iter().enumerate() { - columns - .event_cols - .entry(indexed_keys[idx].clone()) - .or_default() - .push(indexed_param); + for (indexed_param, name) in log.indexed.into_iter().zip(indexed_keys) { + if schema.has_column(&format!("event__{name}")) { + columns + .event_cols + .entry(name.clone()) + .or_default() + .push(indexed_param); + } } - for (idx, body_param) in log.body.into_iter().enumerate() { - columns - .event_cols - .entry(body_keys[idx].clone()) - .or_default() - .push(body_param); + for (body_param, name) in log.body.into_iter().zip(body_keys) { + if schema.has_column(&format!("event__{name}")) { + columns + .event_cols + .entry(name.clone()) + .or_default() + .push(body_param); + } } } Err(_) => continue, @@ -189,3 +181,38 @@ fn process_logs(logs: Vec, columns: &mut Logs, schema: &Table) -> R<()> { Ok(()) } + +fn extract_event_cols( + cols: &mut Vec, + _field_name: &str, + values: indexmap::IndexMap>, + chunk_len: usize, + schema: &Table, +) -> Result<(), CollectError> { + if let Some(decoder) = &schema.log_decoder { + // Write columns even if there are no values decoded - indicates empty dataframe + if values.is_empty() { + for name in decoder.field_names() { + let name = format!("event__{name}"); + let name = PlSmallStr::from_string(name); + if let Some(col_type) = schema.column_type(&name) { + cols.extend(col_type.create_empty_columns(&name, &schema.config)); + } + } + } else { + for (name, data) in values { + let name = format!("event__{name}"); + if let Some(col_type) = schema.column_type(&name) { + let series_vec = col_type.create_column_from_values( + name, + data, + chunk_len, + &schema.config, + )?; + cols.extend(series_vec); + } + } + } + } + Ok(()) +} diff --git a/crates/freeze/src/datasets/native_transfers.rs b/crates/freeze/src/datasets/native_transfers.rs index a8f27048..9e12495a 100644 --- a/crates/freeze/src/datasets/native_transfers.rs +++ b/crates/freeze/src/datasets/native_transfers.rs @@ -6,17 +6,16 @@ use alloy::{ use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::NativeTransfers)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct NativeTransfers { n_rows: u64, block_number: Vec, - block_hash: Vec>, + block_hash: Vec, transaction_index: Vec>, transfer_index: Vec, - transaction_hash: Vec>>, - from_address: Vec>, - to_address: Vec>, + transaction_hash: Vec>, + from_address: Vec, + to_address: Vec, value: Vec, chain_id: Vec, } diff --git a/crates/freeze/src/datasets/nonce_diffs.rs b/crates/freeze/src/datasets/nonce_diffs.rs index c17e7f7b..67339550 100644 --- a/crates/freeze/src/datasets/nonce_diffs.rs +++ b/crates/freeze/src/datasets/nonce_diffs.rs @@ -6,14 +6,13 @@ use alloy::{ use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::NonceDiffs)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct NonceDiffs { pub(crate) n_rows: u64, pub(crate) block_number: Vec>, pub(crate) transaction_index: Vec>, - pub(crate) transaction_hash: Vec>>, - pub(crate) address: Vec>, + pub(crate) transaction_hash: Vec>, + pub(crate) address: Vec, pub(crate) from_value: Vec, pub(crate) to_value: Vec, pub(crate) chain_id: Vec, @@ -22,7 +21,7 @@ pub struct NonceDiffs { #[async_trait::async_trait] impl Dataset for NonceDiffs {} -type BlockTxsTraces = (Option, Vec>>, Vec); +type BlockTxsTraces = (Option, Vec>, Vec); #[async_trait::async_trait] impl CollectByBlock for NonceDiffs { @@ -75,7 +74,7 @@ pub(crate) fn process_nonce_diff( addr: &Address, diff: &Delta, block_number: &Option, - transaction_hash: &Option>, + transaction_hash: &Option, transaction_index: usize, columns: &mut NonceDiffs, schema: &Table, diff --git a/crates/freeze/src/datasets/nonce_reads.rs b/crates/freeze/src/datasets/nonce_reads.rs index 052c2eba..298fd44f 100644 --- a/crates/freeze/src/datasets/nonce_reads.rs +++ b/crates/freeze/src/datasets/nonce_reads.rs @@ -4,14 +4,13 @@ use polars::prelude::*; use std::collections::BTreeMap; /// columns for transactions -#[cryo_to_df::to_df(Datatype::NonceReads)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct NonceReads { pub(crate) n_rows: u64, pub(crate) block_number: Vec>, pub(crate) transaction_index: Vec>, - pub(crate) transaction_hash: Vec>>, - pub(crate) address: Vec>, + pub(crate) transaction_hash: Vec>, + pub(crate) address: Vec, pub(crate) nonce: Vec, pub(crate) chain_id: Vec, } @@ -19,7 +18,7 @@ pub struct NonceReads { #[async_trait::async_trait] impl Dataset for NonceReads {} -type BlockTxsTraces = (Option, Vec>>, Vec>); +type BlockTxsTraces = (Option, Vec>, Vec>); #[async_trait::async_trait] impl CollectByBlock for NonceReads { @@ -71,7 +70,7 @@ pub(crate) fn process_nonce_read( addr: &Address, account_state: &AccountState, block_number: &Option, - transaction_hash: &Option>, + transaction_hash: &Option, transaction_index: usize, columns: &mut NonceReads, schema: &Table, diff --git a/crates/freeze/src/datasets/nonces.rs b/crates/freeze/src/datasets/nonces.rs index e44c9048..2c8302d4 100644 --- a/crates/freeze/src/datasets/nonces.rs +++ b/crates/freeze/src/datasets/nonces.rs @@ -3,12 +3,11 @@ use alloy::primitives::Address; use polars::prelude::*; /// columns for balances -#[cryo_to_df::to_df(Datatype::Nonces)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct Nonces { n_rows: usize, block_number: Vec, - address: Vec>, + address: Vec, nonce: Vec, chain_id: Vec, } @@ -28,7 +27,7 @@ impl Dataset for Nonces { } } -type BlockTxAddressOutput = (u32, Option>, Vec, u64); +type BlockTxAddressOutput = (u32, Option, RawBytes, u64); #[async_trait::async_trait] impl CollectByBlock for Nonces { diff --git a/crates/freeze/src/datasets/slots.rs b/crates/freeze/src/datasets/slots.rs index 14f292aa..8397c25a 100644 --- a/crates/freeze/src/datasets/slots.rs +++ b/crates/freeze/src/datasets/slots.rs @@ -3,14 +3,13 @@ use alloy::primitives::{Address, U256}; use polars::prelude::*; /// columns for balances -#[cryo_to_df::to_df(Datatype::Slots)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct Slots { n_rows: usize, block_number: Vec, - address: Vec>, - slot: Vec>, - value: Vec>, + address: Vec, + slot: Vec, + value: Vec, chain_id: Vec, } @@ -37,7 +36,7 @@ impl Dataset for Slots { } } -type BlockTxAddressOutput = (u32, Option>, Vec, Vec, Vec); +type BlockTxAddressOutput = (u32, Option, RawBytes, RawBytes, RawBytes); #[async_trait::async_trait] impl CollectByBlock for Slots { diff --git a/crates/freeze/src/datasets/storage_diffs.rs b/crates/freeze/src/datasets/storage_diffs.rs index b4ebfffd..cb9011eb 100644 --- a/crates/freeze/src/datasets/storage_diffs.rs +++ b/crates/freeze/src/datasets/storage_diffs.rs @@ -6,17 +6,16 @@ use alloy::{ use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::StorageDiffs)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct StorageDiffs { pub(crate) n_rows: u64, pub(crate) block_number: Vec>, pub(crate) transaction_index: Vec>, - pub(crate) transaction_hash: Vec>>, - pub(crate) address: Vec>, - pub(crate) slot: Vec>, - pub(crate) from_value: Vec>, - pub(crate) to_value: Vec>, + pub(crate) transaction_hash: Vec>, + pub(crate) address: Vec, + pub(crate) slot: Vec, + pub(crate) from_value: Vec, + pub(crate) to_value: Vec, pub(crate) chain_id: Vec, } @@ -27,7 +26,7 @@ impl Dataset for StorageDiffs { } } -type BlockTxsTraces = (Option, Vec>>, Vec); +type BlockTxsTraces = (Option, Vec>, Vec); #[async_trait::async_trait] impl CollectByBlock for StorageDiffs { @@ -81,7 +80,7 @@ pub(crate) fn process_storage_diff( addr: &Address, diff: &std::collections::BTreeMap>, block_number: &Option, - transaction_hash: &Option>, + transaction_hash: &Option, transaction_index: usize, columns: &mut StorageDiffs, schema: &Table, diff --git a/crates/freeze/src/datasets/storage_reads.rs b/crates/freeze/src/datasets/storage_reads.rs index d2769565..04bc2a7b 100644 --- a/crates/freeze/src/datasets/storage_reads.rs +++ b/crates/freeze/src/datasets/storage_reads.rs @@ -4,16 +4,15 @@ use polars::prelude::*; use std::collections::BTreeMap; /// columns for transactions -#[cryo_to_df::to_df(Datatype::StorageReads)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct StorageReads { pub(crate) n_rows: u64, pub(crate) block_number: Vec>, pub(crate) transaction_index: Vec>, - pub(crate) transaction_hash: Vec>>, - pub(crate) contract_address: Vec>, - pub(crate) slot: Vec>, - pub(crate) value: Vec>, + pub(crate) transaction_hash: Vec>, + pub(crate) contract_address: Vec, + pub(crate) slot: Vec, + pub(crate) value: Vec, pub(crate) chain_id: Vec, } @@ -24,7 +23,7 @@ impl Dataset for StorageReads { } } -type BlockTxsTraces = (Option, Vec>>, Vec>); +type BlockTxsTraces = (Option, Vec>, Vec>); #[async_trait::async_trait] impl CollectByBlock for StorageReads { @@ -78,7 +77,7 @@ pub(crate) fn process_storage_read( addr: &Address, account_state: &AccountState, block_number: &Option, - transaction_hash: &Option>, + transaction_hash: &Option, transaction_index: usize, columns: &mut StorageReads, schema: &Table, diff --git a/crates/freeze/src/datasets/trace_calls.rs b/crates/freeze/src/datasets/trace_calls.rs index c77f4adc..3cda4516 100644 --- a/crates/freeze/src/datasets/trace_calls.rs +++ b/crates/freeze/src/datasets/trace_calls.rs @@ -4,30 +4,29 @@ use alloy::rpc::types::trace::parity::{Action, TraceOutput, TraceType, Transacti use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::TraceCalls)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct TraceCalls { n_rows: u64, block_number: Vec, transaction_index: Vec, - action_from: Vec>>, - action_to: Vec>>, + action_from: Vec>, + action_to: Vec>, action_value: Vec, action_gas: Vec>, - action_input: Vec>>, + action_input: Vec>, action_call_type: Vec>, - action_init: Vec>>, + action_init: Vec>, action_reward_type: Vec>, action_type: Vec, result_gas_used: Vec>, - result_output: Vec>>, - result_code: Vec>>, - result_address: Vec>>, + result_output: Vec>, + result_code: Vec>, + result_address: Vec>, trace_address: Vec, subtraces: Vec, error: Vec>, - tx_to_address: Vec>, - tx_call_data: Vec>, + tx_to_address: Vec, + tx_call_data: Vec, chain_id: Vec, } @@ -47,7 +46,7 @@ impl Dataset for TraceCalls { #[async_trait::async_trait] impl CollectByBlock for TraceCalls { - type Response = (u32, Vec, Vec, Vec); + type Response = (u32, RawBytes, RawBytes, Vec); async fn extract(request: Params, source: Arc, _: Arc) -> R { let traces: Vec = source @@ -74,7 +73,7 @@ impl CollectByTransaction for TraceCalls { } fn process_transaction_traces( - response: (u32, Vec, Vec, Vec), + response: (u32, RawBytes, RawBytes, Vec), columns: &mut TraceCalls, schema: &Table, ) { diff --git a/crates/freeze/src/datasets/traces.rs b/crates/freeze/src/datasets/traces.rs index 5bde18f8..8ea6567e 100644 --- a/crates/freeze/src/datasets/traces.rs +++ b/crates/freeze/src/datasets/traces.rs @@ -8,29 +8,28 @@ use alloy::{ use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::Traces)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct Traces { n_rows: u64, - action_from: Vec>>, - action_to: Vec>>, + action_from: Vec>, + action_to: Vec>, action_value: Vec, action_gas: Vec>, - action_input: Vec>>, + action_input: Vec>, action_call_type: Vec>, - action_init: Vec>>, + action_init: Vec>, action_reward_type: Vec>, action_type: Vec, result_gas_used: Vec>, - result_output: Vec>>, - result_code: Vec>>, - result_address: Vec>>, + result_output: Vec>, + result_code: Vec>, + result_address: Vec>, trace_address: Vec, subtraces: Vec, transaction_index: Vec>, - transaction_hash: Vec>>, + transaction_hash: Vec>, block_number: Vec, - block_hash: Vec>, + block_hash: Vec, error: Vec>, chain_id: Vec, } @@ -76,8 +75,8 @@ impl CollectByTransaction for Traces { pub(crate) fn filter_traces_by_from_to_addresses( traces: Vec, - from_address: &Option>, - to_address: &Option>, + from_address: &Option, + to_address: &Option, ) -> Vec { // filter by from_address let from_filter: Box bool + Send> = diff --git a/crates/freeze/src/datasets/transactions.rs b/crates/freeze/src/datasets/transactions.rs index a2c7ac0c..d027503d 100644 --- a/crates/freeze/src/datasets/transactions.rs +++ b/crates/freeze/src/datasets/transactions.rs @@ -9,18 +9,17 @@ use alloy::{ use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::Transactions)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct Transactions { n_rows: u64, block_number: Vec>, transaction_index: Vec>, - transaction_hash: Vec>, + transaction_hash: Vec, nonce: Vec, - from_address: Vec>, - to_address: Vec>>, + from_address: Vec, + to_address: Vec>, value: Vec, - input: Vec>, + input: Vec, gas_limit: Vec, gas_used: Vec>, gas_price: Vec>, @@ -32,11 +31,11 @@ pub struct Transactions { n_input_zero_bytes: Vec, n_input_nonzero_bytes: Vec, n_rlp_bytes: Vec, - block_hash: Vec>, + block_hash: Vec, chain_id: Vec, timestamp: Vec, - r: Vec>, - s: Vec>, + r: Vec, + s: Vec, v: Vec, } @@ -93,7 +92,7 @@ impl CollectByBlock for Transactions { // filter by from_address let from_filter: Box bool + Send> = if let Some(from_address) = &request.from_address { - Box::new(move |tx| tx.from == Address::from_slice(from_address)) + Box::new(move |tx| tx.inner.signer() == Address::from_slice(from_address)) } else { Box::new(|_| true) }; @@ -228,7 +227,7 @@ pub(crate) fn process_transaction( store!(schema, columns, block_number, tx.block_number.map(|x| x as u32)); store!(schema, columns, transaction_index, tx.transaction_index); store!(schema, columns, transaction_hash, tx.inner.tx_hash().to_vec()); - store!(schema, columns, from_address, tx.from.to_vec()); + store!(schema, columns, from_address, tx.inner.signer().to_vec()); store!( schema, columns, @@ -255,7 +254,7 @@ pub(crate) fn process_transaction( } // in alloy eip2718_encoded_length is rlp_encoded_length store!(schema, columns, n_rlp_bytes, tx.inner.eip2718_encoded_length() as u32); - store!(schema, columns, gas_used, receipt.as_ref().map(|r| r.gas_used as u64)); + store!(schema, columns, gas_used, receipt.as_ref().map(|r| r.gas_used)); // store!(schema, columns, gas_price, Some(receipt.unwrap().effective_gas_price as u64)); store!(schema, columns, gas_price, gas_price); store!(schema, columns, transaction_type, tx.inner.tx_type() as u32); @@ -277,7 +276,7 @@ pub(crate) fn process_transaction( } fn get_max_fee_per_gas(tx: &Transaction) -> Option { - match &tx.inner { + match tx.inner.as_ref() { alloy::consensus::TxEnvelope::Legacy(_) => None, alloy::consensus::TxEnvelope::Eip2930(_) => None, _ => Some(tx.inner.max_fee_per_gas() as u64), @@ -285,7 +284,7 @@ fn get_max_fee_per_gas(tx: &Transaction) -> Option { } pub(crate) fn get_gas_price(block: &Block, tx: &Transaction) -> Option { - match &tx.inner { + match tx.inner.as_ref() { alloy::consensus::TxEnvelope::Legacy(_) => tx.gas_price().map(|gas_price| gas_price as u64), alloy::consensus::TxEnvelope::Eip2930(_) => { tx.gas_price().map(|gas_price| gas_price as u64) @@ -310,9 +309,9 @@ fn tx_success(tx: &Transaction, receipt: &Option) -> R if let Some(r) = receipt { Ok(r.gas_used == 0) } else { - return Err(err("could not determine status of transaction")) + Err(err("could not determine status of transaction")) } } else { - return Err(err("could not determine status of transaction")) + Err(err("could not determine status of transaction")) } } diff --git a/crates/freeze/src/datasets/vm_traces.rs b/crates/freeze/src/datasets/vm_traces.rs index 1ede0dfa..9ae7a5e3 100644 --- a/crates/freeze/src/datasets/vm_traces.rs +++ b/crates/freeze/src/datasets/vm_traces.rs @@ -3,20 +3,19 @@ use alloy::rpc::types::trace::parity::{TraceResults, VmTrace}; use polars::prelude::*; /// columns for transactions -#[cryo_to_df::to_df(Datatype::VmTraces)] -#[derive(Default)] +#[derive(Default, cryo_to_df::ToDataFrames)] pub struct VmTraces { block_number: Vec>, - transaction_hash: Vec>>, + transaction_hash: Vec>, transaction_index: Vec, pc: Vec, cost: Vec, used: Vec>, - push: Vec>>, + push: Vec>, mem_off: Vec>, - mem_data: Vec>>, - storage_key: Vec>>, - storage_val: Vec>>, + mem_data: Vec>, + storage_key: Vec>, + storage_val: Vec>, op: Vec>, n_rows: usize, chain_id: Vec, @@ -39,7 +38,7 @@ impl Dataset for VmTraces { #[async_trait::async_trait] impl CollectByBlock for VmTraces { - type Response = (Option, Option>, Vec); + type Response = (Option, Option, Vec); async fn extract(request: Params, source: Arc, _: Arc) -> R { let (bn, txs, traces) = @@ -55,7 +54,7 @@ impl CollectByBlock for VmTraces { #[async_trait::async_trait] impl CollectByTransaction for VmTraces { - type Response = (Option, Option>, Vec); + type Response = (Option, Option, Vec); async fn extract(request: Params, source: Arc, _: Arc) -> R { source.trace_transaction_vm_traces(request.transaction_hash()?).await @@ -67,7 +66,7 @@ impl CollectByTransaction for VmTraces { } fn process_vm_traces( - response: (Option, Option>, Vec), + response: (Option, Option, Vec), columns: &mut VmTraces, schemas: &Schemas, ) -> R<()> { @@ -86,7 +85,7 @@ fn add_ops( schema: &Table, columns: &mut VmTraces, number: Option, - tx_hash: Option>, + tx_hash: Option, tx_pos: usize, ) { for opcode in vm_trace.ops { diff --git a/crates/freeze/src/freeze.rs b/crates/freeze/src/freeze.rs index f80bc623..1a247f91 100644 --- a/crates/freeze/src/freeze.rs +++ b/crates/freeze/src/freeze.rs @@ -157,7 +157,7 @@ async fn freeze_partitions( completed.push(partition) } Ok((partition, Err(e))) => errored.push((Some(partition), e)), - Err(e) => errored.push((None, err(format!("error joining chunks: {:?}", e).as_str()))), + Err(e) => errored.push((None, err(format!("error joining chunks: {e:?}").as_str()))), } } diff --git a/crates/freeze/src/lib.rs b/crates/freeze/src/lib.rs index cd3de566..9476050c 100644 --- a/crates/freeze/src/lib.rs +++ b/crates/freeze/src/lib.rs @@ -7,6 +7,9 @@ attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables)) ))] +#[macro_use] +extern crate tracing; + mod collect; mod datasets; mod freeze; diff --git a/crates/freeze/src/multi_datasets/geth_state_diffs.rs b/crates/freeze/src/multi_datasets/geth_state_diffs.rs index bd2f16cc..2733dd53 100644 --- a/crates/freeze/src/multi_datasets/geth_state_diffs.rs +++ b/crates/freeze/src/multi_datasets/geth_state_diffs.rs @@ -49,7 +49,7 @@ impl ToDataFrames for GethStateDiffs { } } -type BlockTxsTraces = (Option, Vec>>, Vec); +type BlockTxsTraces = (Option, Vec>, Vec); #[async_trait::async_trait] impl CollectByBlock for GethStateDiffs { @@ -154,7 +154,7 @@ fn add_balances( post: Option, columns: &mut GethBalanceDiffs, schema: &Table, - index: &(Option, u32, Option>), + index: &(Option, u32, Option), ) -> R<()> { let (from_value, to_value) = parse_pre_post(pre, post, U256::ZERO); let (block_number, transaction_index, transaction_hash) = index; @@ -174,7 +174,7 @@ fn add_codes( post: &Option, columns: &mut GethCodeDiffs, schema: &Table, - index: &(Option, u32, Option>), + index: &(Option, u32, Option), ) -> R<()> { let blank = Bytes::new(); let (from_value, to_value) = match (pre, post) { @@ -200,7 +200,7 @@ fn add_nonces( post: Option, columns: &mut GethNonceDiffs, schema: &Table, - index: &(Option, u32, Option>), + index: &(Option, u32, Option), ) -> R<()> { let (from_value, to_value) = parse_pre_post(pre, post, 0_u64); let (block_number, transaction_index, transaction_hash) = index; @@ -220,7 +220,7 @@ fn add_storages( post: &BTreeMap, columns: &mut GethStorageDiffs, schema: &Table, - index: &(Option, u32, Option>), + index: &(Option, u32, Option), ) -> R<()> { let (block_number, transaction_index, transaction_hash) = index; let slots: Vec<_> = pre diff --git a/crates/freeze/src/multi_datasets/state_diffs.rs b/crates/freeze/src/multi_datasets/state_diffs.rs index 2806fee2..09d0fd67 100644 --- a/crates/freeze/src/multi_datasets/state_diffs.rs +++ b/crates/freeze/src/multi_datasets/state_diffs.rs @@ -12,7 +12,7 @@ pub struct StateDiffs( storage_diffs::StorageDiffs, ); -type BlockTxsTraces = (Option, Vec>>, Vec); +type BlockTxsTraces = (Option, Vec>, Vec); impl ToDataFrames for StateDiffs { fn create_dfs( diff --git a/crates/freeze/src/multi_datasets/state_reads.rs b/crates/freeze/src/multi_datasets/state_reads.rs index 0fa8ae4b..56496135 100644 --- a/crates/freeze/src/multi_datasets/state_reads.rs +++ b/crates/freeze/src/multi_datasets/state_reads.rs @@ -12,7 +12,7 @@ pub struct StateReads( storage_reads::StorageReads, ); -type BlockTxsTraces = (Option, Vec>>, Vec>); +type BlockTxsTraces = (Option, Vec>, Vec>); impl ToDataFrames for StateReads { fn create_dfs( diff --git a/crates/freeze/src/types/chunks/binary_chunk.rs b/crates/freeze/src/types/chunks/binary_chunk.rs index 39b70093..0f2f915b 100644 --- a/crates/freeze/src/types/chunks/binary_chunk.rs +++ b/crates/freeze/src/types/chunks/binary_chunk.rs @@ -1,20 +1,22 @@ -use super::chunk_ops::ChunkData; -use crate::ChunkError; +use crate::{ChunkData, ChunkError}; + +/// alias of `Vec` +pub type RawBytes = Vec; /// Chunk of raw data entries #[derive(Debug, Clone)] pub enum BinaryChunk { /// Vec of values - Values(Vec>), + Values(Vec), // /// Range of values (start_prefix, end_prefix) - // Range(Vec, Vec), + // Range(RawBytes, RawBytes), } impl ChunkData for BinaryChunk { - type Inner = Vec; + type Inner = RawBytes; fn format_item(value: Self::Inner) -> Result { - let hash = prefix_hex::encode(value); + let hash = alloy::hex::encode_prefixed(value); let eigth = match hash.char_indices().nth(8) { Some(x) => x, None => return Err(ChunkError::ChunkError("could not format chunk".to_string())), @@ -52,7 +54,7 @@ impl ChunkData for BinaryChunk { } } - fn values(&self) -> Vec> { + fn values(&self) -> Vec { match self { BinaryChunk::Values(values) => values.to_vec(), // BinaryChunk::Range(_start, _end) => diff --git a/crates/freeze/src/types/chunks/chunk_ops.rs b/crates/freeze/src/types/chunks/chunk_ops.rs index 7a9e1551..ac2d62f2 100644 --- a/crates/freeze/src/types/chunks/chunk_ops.rs +++ b/crates/freeze/src/types/chunks/chunk_ops.rs @@ -114,7 +114,7 @@ impl ValueToString for u64 { impl ValueToString for Vec { fn to_value_string(&self) -> String { - prefix_hex::encode(self.clone()) + alloy::hex::encode_prefixed(self.clone()) } } diff --git a/crates/freeze/src/types/chunks/mod.rs b/crates/freeze/src/types/chunks/mod.rs index 2a243c6a..ed7db467 100644 --- a/crates/freeze/src/types/chunks/mod.rs +++ b/crates/freeze/src/types/chunks/mod.rs @@ -4,6 +4,7 @@ pub(crate) mod chunk_ops; pub(crate) mod number_chunk; pub(crate) mod subchunks; +pub use binary_chunk::{BinaryChunk, RawBytes}; pub use chunk::{ AddressChunk, BlockChunk, CallDataChunk, Chunk, SlotChunk, TopicChunk, TransactionChunk, }; diff --git a/crates/freeze/src/types/chunks/number_chunk.rs b/crates/freeze/src/types/chunks/number_chunk.rs index bb68d1f4..651f47c3 100644 --- a/crates/freeze/src/types/chunks/number_chunk.rs +++ b/crates/freeze/src/types/chunks/number_chunk.rs @@ -16,7 +16,7 @@ impl ChunkData for NumberChunk { type Inner = u64; fn format_item(value: Self::Inner) -> Result { - Ok(format!("{:0>8}", value)) + Ok(format!("{value:0>8}")) } fn size(&self) -> u64 { diff --git a/crates/freeze/src/types/columns.rs b/crates/freeze/src/types/columns.rs index 8d8baa61..f7632b93 100644 --- a/crates/freeze/src/types/columns.rs +++ b/crates/freeze/src/types/columns.rs @@ -66,6 +66,16 @@ pub trait ToDataFrames: Sized { ) -> Result, CollectError>; } +/// converts from dataframes +pub trait FromDataFrames: Sized { + /// create struct from dataframe data + fn parse_dfs( + &mut self, + dfs: HashMap, + datatype: &HashMap, + ) -> Result<&mut Self, CollectError>; +} + /// Dataset manages collection and management of a particular datatype pub trait Dataset: Sync + Send { /// alias of Dataset diff --git a/crates/freeze/src/types/conversions.rs b/crates/freeze/src/types/conversions.rs index 536ee3ac..2d1b2200 100644 --- a/crates/freeze/src/types/conversions.rs +++ b/crates/freeze/src/types/conversions.rs @@ -1,7 +1,6 @@ -use crate::CollectError; +use crate::{CollectError, OptionVec, RawBytes}; /// conversion operations use alloy::primitives::{Bytes, I256, U256}; -use prefix_hex; /// convert Bytes to u32 pub fn bytes_to_u32(value: Bytes) -> Result { @@ -63,21 +62,161 @@ pub trait ToVecHex { type Output; /// Convert to Vec of hex String - fn to_vec_hex(&self) -> Self::Output; + fn to_vec_hex(&self, with_prefix: bool) -> Self::Output; } -impl ToVecHex for Vec> { +fn encode_hex>(data: T, with_prefix: bool) -> String { + if with_prefix { + alloy::hex::encode_prefixed(data) + } else { + alloy::hex::encode(data) + } +} + +impl ToVecHex for Vec { type Output = Vec; - fn to_vec_hex(&self) -> Self::Output { - self.iter().map(|v| prefix_hex::encode(v.clone())).collect() + fn to_vec_hex(&self, with_prefix: bool) -> Self::Output { + self.iter().map(|v| encode_hex(v, with_prefix)).collect() } } -impl ToVecHex for Vec>> { +impl ToVecHex for Vec> { type Output = Vec>; - fn to_vec_hex(&self) -> Self::Output { - self.iter().map(|opt| opt.as_ref().map(|v| prefix_hex::encode(v.clone()))).collect() + fn to_vec_hex(&self, with_prefix: bool) -> Self::Output { + self.iter().map(|opt| opt.as_ref().map(|v| encode_hex(v, with_prefix))).collect() + } +} + +impl ToVecHex for OptionVec { + type Output = OptionVec; + + fn to_vec_hex(&self, with_prefix: bool) -> Self::Output { + match self { + OptionVec::Some(v) => OptionVec::Some(v.to_vec_hex(with_prefix)), + OptionVec::Option(v) => OptionVec::Option(v.to_vec_hex(with_prefix)), + } + } +} + +/// Trait for converting single binary value to specific types +pub trait FromBinary { + /// Convert from RawBytes to Self + fn from_binary(value: RawBytes) -> Result + where + Self: Sized; +} + +/// Implementation for U256 +impl FromBinary for U256 { + fn from_binary(value: RawBytes) -> Result { + if value.len() >= 32 { + Ok(U256::from_be_bytes(value[..32].try_into().unwrap_or([0u8; 32]))) + } else { + // Pad with zeros if needed + let mut padded = [0u8; 32]; + let start_idx = 32 - value.len(); + padded[start_idx..].copy_from_slice(&value); + Ok(U256::from_be_bytes(padded)) + } + } +} + +/// Implementation for I256 +impl FromBinary for I256 { + fn from_binary(value: RawBytes) -> Result { + if value.len() >= 32 { + let u256_bytes = value[..32].try_into().unwrap_or([0u8; 32]); + let u256_val = U256::from_be_bytes(u256_bytes); + Ok(I256::from_raw(u256_val)) + } else { + // Pad with 0xff for signed integers (negative extension) + let mut padded = [0xffu8; 32]; + let start_idx = 32 - value.len(); + padded[start_idx..].copy_from_slice(&value); + let u256_val = U256::from_be_bytes(padded); + Ok(I256::from_raw(u256_val)) + } + } +} + +/// Trait for converting binary data to specific types +pub trait FromBinaryVec { + /// Convert from Vec> to Self + fn from_binary_vec(data: Vec>) -> Result + where + Self: Sized; +} + +/// Implementation for Vec> +impl FromBinaryVec for Vec> { + fn from_binary_vec(data: Vec>) -> Result { + let mut result = Vec::with_capacity(data.len()); + for opt_bytes in data { + match opt_bytes { + Some(bytes) => { + result.push(Some(U256::from_binary(bytes)?)); + } + None => result.push(None), + } + } + Ok(result) + } +} + +/// Implementation for Vec +impl FromBinaryVec for Vec { + fn from_binary_vec(data: Vec>) -> Result { + let mut result = Vec::with_capacity(data.len()); + for (i, opt_bytes) in data.into_iter().enumerate() { + match opt_bytes { + Some(bytes) => { + result.push(U256::from_binary(bytes)?); + } + None => { + return Err(CollectError::CollectError(format!( + "Missing binary value at index {i}" + ))) + } + } + } + Ok(result) + } +} + +/// Implementation for Vec> +impl FromBinaryVec for Vec> { + fn from_binary_vec(data: Vec>) -> Result { + let mut result = Vec::with_capacity(data.len()); + for opt_bytes in data { + match opt_bytes { + Some(bytes) => { + result.push(Some(I256::from_binary(bytes)?)); + } + None => result.push(None), + } + } + Ok(result) + } +} + +/// Implementation for Vec +impl FromBinaryVec for Vec { + fn from_binary_vec(data: Vec>) -> Result { + let mut result = Vec::with_capacity(data.len()); + for (i, opt_bytes) in data.into_iter().enumerate() { + match opt_bytes { + Some(bytes) => { + result.push(I256::from_binary(bytes)?); + } + None => { + return Err(CollectError::CollectError(format!( + "Missing binary value at index {i}" + ))) + } + } + } + Ok(result) } } diff --git a/crates/freeze/src/types/dataframes/creation.rs b/crates/freeze/src/types/dataframes/creation.rs index 860d5b4c..75e6ea94 100644 --- a/crates/freeze/src/types/dataframes/creation.rs +++ b/crates/freeze/src/types/dataframes/creation.rs @@ -1,177 +1,348 @@ -/// convert a Vec to Series and add to Vec +use alloy::dyn_abi::DynSolValue; +use polars::prelude::Column; + +use crate::{err, CollectError, ColumnType, DynValues, RawBytes, TableConfig}; + +/// convert a Vec to Column and add to Vec #[macro_export] -macro_rules! with_series { - ($all_series:expr, $name:expr, $value:expr, $schema:expr) => { +macro_rules! with_column_primitive { + ($all_columns:expr, $name:expr, $value:expr, $schema:expr) => { if $schema.has_column($name) { - $all_series.push(Series::new($name, $value)); + $all_columns.push(Column::new($name.into(), $value)); } }; } -/// convert a Vec to Series, as hex if specified, and add to Vec +/// convert a Vec to Column and add to Vec, using [`crate::DynValues`] #[macro_export] -macro_rules! with_series_binary { - ($all_series:expr, $name:expr, $value:expr, $schema:expr) => { - if $schema.has_column($name) { - if let Some(ColumnType::Hex) = $schema.column_type($name) { - $all_series.push(Series::new($name, $value.to_vec_hex())); - } else { - $all_series.push(Series::new($name, $value)); - } +macro_rules! with_column { + ($all_columns:expr, $name:expr, $value:expr, $schema:expr) => { + if let Some(col_type) = $schema.column_type($name) { + let cols = DynValues::from($value).into_columns( + $name.to_string(), + col_type, + &$schema.config, + )?; + $all_columns.extend(cols); } }; } -/// convert a Vec to variety of u256 Series representations +/// parse a primitive type column from DataFrame and populate struct field #[macro_export] -macro_rules! with_series_u256 { - ($all_series:expr, $name:expr, $value:expr, $schema:expr) => { - if $schema.has_column($name) { - // binary - if $schema.u256_types.contains(&U256Type::Binary) { - let name = $name.to_string() + U256Type::Binary.suffix().as_str(); - let name = name.as_str(); - - let converted: Vec> = $value.iter().map(|v| v.to_vec_u8()).collect(); - if ColumnEncoding::Hex == $schema.binary_type { - $all_series.push(Series::new(name, converted.to_vec_hex())); - } else { - $all_series.push(Series::new(name, converted)); - } - } +macro_rules! parse_column_primitive { + // Special handling for String since we need to convert &str to String + ($df:expr, $column_name:expr, str, $field:expr, $schema:expr) => { + let option_vec = { + let series = $df.column($column_name).map_err(CollectError::PolarsError)?; + let str_array = series.str().map_err(CollectError::PolarsError)?; + let values: Vec> = + str_array.into_iter().map(|opt_str| opt_str.map(|s| s.to_string())).collect(); - // string - if $schema.u256_types.contains(&U256Type::String) { - let name = $name.to_string() + U256Type::String.suffix().as_str(); - let name = name.as_str(); + OptionVec::Option(values) + }; + $field = option_vec.try_into()?; + }; + ($df:expr, $column_name:expr, $polars_type:ident, $field:expr, $schema:expr) => { + let option_vec = { + let series = $df.column($column_name).map_err(CollectError::PolarsError)?; + let array = series.$polars_type().map_err(CollectError::PolarsError)?; + let values: Vec> = array.into_iter().collect(); - let converted: Vec = $value.iter().map(|v| v.to_string()).collect(); - $all_series.push(Series::new(name, converted)); - } + OptionVec::Option(values) + }; + $field = option_vec.try_into()?; + }; +} + +/// parse a complex type column from DataFrame and populate struct field (for U256/I256) +#[macro_export] +macro_rules! parse_column { + ($df:expr, $column_name:expr, U256, $field:expr, $schema:expr) => { + // Try to read from _u256binary first, then fall back to _binary + let u256_column_name = format!("{}_u256binary", $column_name); + let binary_column_name = format!("{}_binary", $column_name); - // float32 - if $schema.u256_types.contains(&U256Type::F32) { - let name = $name.to_string() + U256Type::F32.suffix().as_str(); - let name = name.as_str(); + let column_result = + $df.column(&u256_column_name).or_else(|_| $df.column(&binary_column_name)); - let converted: Vec> = - $value.iter().map(|v| v.to_string().parse::().ok()).collect(); - $all_series.push(Series::new(name, converted)); + match column_result { + Ok(series) => { + let binary_data = series.binary().map_err(CollectError::PolarsError)?; + let raw_data: Vec> = + binary_data.into_iter().map(|opt| opt.map(|bytes| bytes.to_vec())).collect(); + $field = $crate::FromBinaryVec::from_binary_vec(raw_data)?; + } + Err(_) => { + $field = vec![]; } + } + }; + ($df:expr, $column_name:expr, I256, $field:expr, $schema:expr) => { + // Try to read from _i256binary first, then fall back to _binary + let i256_column_name = format!("{}_i256binary", $column_name); + let binary_column_name = format!("{}_binary", $column_name); - // float64 - if $schema.u256_types.contains(&U256Type::F64) { - let name = $name.to_string() + U256Type::F64.suffix().as_str(); - let name = name.as_str(); + let column_result = + $df.column(&i256_column_name).or_else(|_| $df.column(&binary_column_name)); - let converted: Vec> = - $value.iter().map(|v| v.to_string().parse::().ok()).collect(); - $all_series.push(Series::new(name, converted)); + match column_result { + Ok(series) => { + let binary_data = series.binary().map_err(CollectError::PolarsError)?; + let raw_data: Vec> = + binary_data.into_iter().map(|opt| opt.map(|bytes| bytes.to_vec())).collect(); + $field = $crate::FromBinaryVec::from_binary_vec(raw_data)?; + } + Err(_) => { + $field = vec![]; } + } + }; +} - // u32 - if $schema.u256_types.contains(&U256Type::U32) { - let name = $name.to_string() + U256Type::U32.suffix().as_str(); - let name = name.as_str(); +impl ColumnType { + /// data should never be mixed type, otherwise this will return inconsistent results + pub fn create_column_from_values( + self, + name: String, + data: Vec, + chunk_len: usize, + config: &TableConfig, + ) -> Result, CollectError> { + let values = DynValues::from_sol_values(data, config)?; + let mixed_length_err = format!("could not parse column {name}, mixed type"); - let converted: Vec = $value.iter().map(|v| v.wrapping_to::()).collect(); - $all_series.push(Series::new(name, converted)); - } + if values.len() != chunk_len { + return Err(err(&mixed_length_err)) + } + values.into_columns(name, self, config) + } - // u64 - if $schema.u256_types.contains(&U256Type::U64) { - let name = $name.to_string() + U256Type::U64.suffix().as_str(); - let name = name.as_str(); + /// data should never be mixed type, otherwise this will return inconsistent results + pub fn create_empty_columns(self, name: &str, config: &TableConfig) -> Vec { + if self.is_256() { + return self.create_empty_u256_columns(name, config); + } + vec![self.create_single_empty_column(name)] + } - let converted: Vec = $value.iter().map(|v| v.wrapping_to::()).collect(); - $all_series.push(Series::new(name, converted)); - } + /// Create empty columns for U256 types + pub fn create_empty_u256_columns(self, name: &str, config: &TableConfig) -> Vec { + config + .u256_types + .iter() + .map(|u256_type| { + let new_type = u256_type.to_columntype(config.binary_type); + let full_name = name.to_string() + u256_type.suffix(self).as_str(); + new_type.create_single_empty_column(&full_name) + }) + .collect() + } - // decimal128 - if $schema.u256_types.contains(&U256Type::Decimal128) { - return Err(CollectError::CollectError("DECIMAL128 not implemented".to_string())) + /// Create an empty column of the specified type + pub fn create_single_empty_column(self, name: &str) -> Column { + match self { + ColumnType::Boolean => Column::new(name.into(), Vec::::new()), + ColumnType::UInt32 => Column::new(name.into(), Vec::::new()), + ColumnType::UInt64 => Column::new(name.into(), Vec::::new()), + ColumnType::UInt256 => { + Column::new(format!("{name}_u256binary").into(), Vec::::new()) + } + ColumnType::Int32 => Column::new(name.into(), Vec::::new()), + ColumnType::Int64 => Column::new(name.into(), Vec::::new()), + ColumnType::Int256 => { + Column::new(format!("{name}_i256binary").into(), Vec::::new()) } + ColumnType::Float32 => Column::new(name.into(), Vec::::new()), + ColumnType::Float64 => Column::new(name.into(), Vec::::new()), + ColumnType::Decimal128 => Column::new(name.into(), Vec::::new()), + ColumnType::String => Column::new(name.into(), Vec::::new()), + ColumnType::Binary => Column::new(name.into(), Vec::::new()), + ColumnType::Hex => Column::new(name.into(), Vec::::new()), } - }; + } } -/// convert a Vec> to variety of u256 Series representations -#[macro_export] -macro_rules! with_series_option_u256 { - ($all_series:expr, $name:expr, $value:expr, $schema:expr) => { - if $schema.has_column($name) { - // binary - if $schema.u256_types.contains(&U256Type::Binary) { - let name = $name.to_string() + U256Type::Binary.suffix().as_str(); - let name = name.as_str(); - - let converted: Vec>> = - $value.iter().map(|v| v.map(|x| x.to_vec_u8())).collect(); - if ColumnEncoding::Hex == $schema.binary_type { - $all_series.push(Series::new(name, converted.to_vec_hex())); - } else { - $all_series.push(Series::new(name, converted)); - } - } +#[cfg(test)] +mod tests { + use alloy::primitives::{I256, U256}; + use polars::prelude::DataType; - // string - if $schema.u256_types.contains(&U256Type::String) { - let name = $name.to_string() + U256Type::String.suffix().as_str(); - let name = name.as_str(); + use crate::{ColumnEncoding, U256Type}; - let converted: Vec> = - $value.iter().map(|v| v.map(|x| x.to_string())).collect(); - $all_series.push(Series::new(name, converted)); - } + use super::*; - // float32 - if $schema.u256_types.contains(&U256Type::F32) { - let name = $name.to_string() + U256Type::F32.suffix().as_str(); - let name = name.as_str(); + fn get_config() -> TableConfig { + TableConfig { + hex_prefix: true, + binary_type: ColumnEncoding::Binary, + u256_types: vec![U256Type::NamedBinary, U256Type::String, U256Type::F64], + } + } - let converted: Vec> = $value - .iter() - .map(|v| v.map(|x| x.to_string().parse::().ok()).flatten()) - .collect(); - $all_series.push(Series::new(name, converted)); - } + fn get_config_hex() -> TableConfig { + TableConfig { + hex_prefix: true, + binary_type: ColumnEncoding::Hex, + u256_types: vec![U256Type::NamedBinary, U256Type::String, U256Type::F64], + } + } - // float64 - if $schema.u256_types.contains(&U256Type::F64) { - let name = $name.to_string() + U256Type::F64.suffix().as_str(); - let name = name.as_str(); + macro_rules! test_empty_column { + ($($ty:ident)+) => { + $({ + let cols = ColumnType::$ty + .create_empty_columns(stringify!($ty), &get_config()); + assert_eq!(cols.len(), 1); + assert_eq!(cols[0].dtype(), &DataType::$ty); + assert_eq!(cols[0].len(), 0); + })+ + }; + } - let converted: Vec> = $value - .iter() - .map(|v| v.map(|x| x.to_string().parse::().ok()).flatten()) - .collect(); - $all_series.push(Series::new(name, converted)); - } + macro_rules! test_sol_column { + ($($ty:ident => $exp:expr,)+) => { + $({ + let len = $exp.len(); + let cols = ColumnType::$ty + .create_column_from_values(stringify!($ty).to_string(), $exp.clone().into_iter().map(|i| i.into()).collect(), len, &get_config()) + .unwrap(); + assert_eq!(cols.len(), 1); + assert_eq!(cols[0].dtype(), &DataType::$ty); + assert_eq!(cols[0].len(), len); + })+ + }; + } - // u32 - if $schema.u256_types.contains(&U256Type::U32) { - let name = $name.to_string() + U256Type::U32.suffix().as_str(); - let name = name.as_str(); + macro_rules! test_dyn_column { + ($($ty:ident => $exp:expr,)+) => { + $({ + let len = $exp.len(); + let cols = DynValues::from($exp).into_columns(stringify!($ty).to_string(), ColumnType::$ty, &get_config()).unwrap(); + assert_eq!(cols.len(), 1); + assert_eq!(cols[0].dtype(), &DataType::$ty); + assert_eq!(cols[0].len(), len); + })+ + }; + } - let converted: Vec> = - $value.iter().map(|v| v.map(|x| x.wrapping_to::())).collect(); - $all_series.push(Series::new(name, converted)); - } + #[test] + fn test_empty_column_creation() { + test_empty_column!(Boolean UInt32 UInt64 Int32 Int64 Float32 Float64 String Binary); + let cols = ColumnType::Hex.create_empty_columns("Hex", &get_config()); + assert_eq!(cols.len(), 1); + assert_eq!(cols[0].dtype(), &DataType::String); + assert_eq!(cols[0].len(), 0); - // u64 - if $schema.u256_types.contains(&U256Type::U64) { - let name = $name.to_string() + U256Type::U64.suffix().as_str(); - let name = name.as_str(); + let cols = ColumnType::Decimal128.create_empty_columns("Decimal128", &get_config()); + assert_eq!(cols.len(), 1); + assert_eq!(cols[0].dtype(), &DataType::Binary); + assert_eq!(cols[0].len(), 0); - let converted: Vec> = - $value.iter().map(|v| v.map(|x| x.wrapping_to::())).collect(); - $all_series.push(Series::new(name, converted)); - } + let cols = ColumnType::UInt256.create_empty_columns("UInt256", &get_config()); + assert_eq!(cols.len(), 3); + assert_eq!( + cols.iter().map(|c| c.dtype().clone()).collect::>(), + vec![DataType::Binary, DataType::String, DataType::Float64] + ); + assert_eq!( + cols.iter().map(|c| c.name().to_string()).collect::>(), + vec![ + "UInt256_u256binary".to_string(), + "UInt256_string".to_string(), + "UInt256_f64".to_string() + ] + ); + assert!(cols.iter().all(|c| c.is_empty())); - // decimal128 - if $schema.u256_types.contains(&U256Type::Decimal128) { - return Err(CollectError::CollectError("DECIMAL128 not implemented".to_string())) - } - } - }; + let cols = ColumnType::Int256.create_empty_columns("Int256", &get_config()); + assert_eq!(cols.len(), 3); + assert_eq!( + cols.iter().map(|c| c.dtype().clone()).collect::>(), + vec![DataType::Binary, DataType::String, DataType::Float64] + ); + assert_eq!( + cols.iter().map(|c| c.name().to_string()).collect::>(), + vec![ + "Int256_i256binary".to_string(), + "Int256_string".to_string(), + "Int256_f64".to_string() + ] + ); + assert!(cols.iter().all(|c| c.is_empty())); + } + + #[test] + fn test_column_creation() { + test_sol_column!( + Boolean => vec![true, false, true], + UInt32 => vec![1u32, 2, 3], + UInt64 => vec![1u64, 2, 3], + Int32 => vec![-1i32, 0, 1], + Int64 => vec![-1i64, 0, 1], + // Float32 => vec![1.0, 2.0, 3.0], + // Float64 => vec![1.0, 2.0, 3.0], + String => vec!["a".to_string(), "b".to_string(), "c".to_string()], + Binary => vec![vec![1, 2], vec![3, 4], vec![5, 6]], + ); + + test_dyn_column!( + Boolean => vec![true, false, true], + UInt32 => vec![1u32, 2, 3], + UInt64 => vec![1u64, 2, 3], + Int32 => vec![-1i32, 0, 1], + Int64 => vec![-1i64, 0, 1], + Float32 => vec![1.0, 2.0, 3.0], + Float64 => vec![1.0, 2.0, 3.0], + String => vec!["a".to_string(), "b".to_string(), "c".to_string()], + Binary => vec![vec![1, 2], vec![3, 4], vec![5, 6]], + ); + + let cols = DynValues::from(vec![vec![1, 2], vec![3, 4], vec![5, 6]]) + .into_columns("Hex".to_string(), ColumnType::Hex, &get_config_hex()) + .unwrap(); + assert_eq!(cols.len(), 1); + assert_eq!(cols[0].dtype(), &DataType::String); + assert_eq!(cols[0].len(), 3); + + let cols = DynValues::from(vec![U256::from(1), U256::from(2), U256::from(3)]) + .into_columns("UInt256".to_string(), ColumnType::UInt256, &get_config()) + .unwrap(); + assert_eq!(cols.len(), 3); + assert_eq!( + cols.iter().map(|c| c.dtype().clone()).collect::>(), + vec![DataType::Binary, DataType::String, DataType::Float64] + ); + assert_eq!( + cols.iter().map(|c| c.name().to_string()).collect::>(), + vec![ + "UInt256_u256binary".to_string(), + "UInt256_string".to_string(), + "UInt256_f64".to_string() + ] + ); + assert!(cols.iter().all(|c| c.len() == 3)); + + let cols = DynValues::from(vec![ + I256::try_from(-1).unwrap(), + I256::try_from(0).unwrap(), + I256::try_from(1).unwrap(), + ]) + .into_columns("Int256".to_string(), ColumnType::Int256, &get_config()) + .unwrap(); + assert_eq!(cols.len(), 3); + assert_eq!( + cols.iter().map(|c| c.dtype().clone()).collect::>(), + vec![DataType::Binary, DataType::String, DataType::Float64] + ); + assert_eq!( + cols.iter().map(|c| c.name().to_string()).collect::>(), + vec![ + "Int256_i256binary".to_string(), + "Int256_string".to_string(), + "Int256_f64".to_string() + ] + ); + assert!(cols.iter().all(|c| c.len() == 3)); + } } diff --git a/crates/freeze/src/types/dataframes/dyn_values.rs b/crates/freeze/src/types/dataframes/dyn_values.rs new file mode 100644 index 00000000..85f27b15 --- /dev/null +++ b/crates/freeze/src/types/dataframes/dyn_values.rs @@ -0,0 +1,361 @@ +use alloy::{ + dyn_abi::DynSolValue, + primitives::{I256, U256}, +}; +use polars::{ + prelude::{Column, NamedFrom}, + series::Series, +}; + +use crate::{ + err, CollectError, ColumnType, RawBytes, TableConfig, ToU256Series, ToVecHex, U256Type, +}; + +/// A vector that can hold either values or optional values. +pub enum OptionVec { + /// A vector of values + Some(Vec), + /// A vector of optional values + Option(Vec>), +} + +impl OptionVec { + /// Returns whether the vector is empty. + pub fn is_empty(&self) -> bool { + match self { + OptionVec::Some(v) => v.is_empty(), + OptionVec::Option(v) => v.is_empty(), + } + } + + /// Get the length of the vector + pub fn len(&self) -> usize { + match self { + OptionVec::Some(v) => v.len(), + OptionVec::Option(v) => v.len(), + } + } + + /// Map the elements of the vector + pub fn map(self, mut f: impl FnMut(T) -> U) -> OptionVec { + match self { + OptionVec::Some(v) => OptionVec::Some(v.into_iter().map(f).collect()), + OptionVec::Option(v) => { + OptionVec::Option(v.into_iter().map(|opt| opt.map(&mut f)).collect()) + } + } + } + + /// Convert into a polars Column + pub fn into_column(self, name: String) -> Column + where + Series: NamedFrom, P1>, + Series: NamedFrom>, P2>, + { + match self { + OptionVec::Some(v) => Column::new(name.into(), v), + OptionVec::Option(v) => Column::new(name.into(), v), + } + } + + /// Convert into a variety of u256 Column representations + pub fn into_u256_columns( + self, + name: String, + config: &TableConfig, + ) -> Result, CollectError> + where + Vec: ToU256Series, + Vec>: ToU256Series, + { + match self { + OptionVec::Some(v) => { + let mut series_vec = Vec::new(); + for u256_type in config.u256_types.iter() { + series_vec.push(v.to_u256_series( + name.to_string(), + u256_type.clone(), + config, + )?) + } + Ok(series_vec) + } + OptionVec::Option(v) => { + let mut series_vec = Vec::new(); + for u256_type in config.u256_types.iter() { + series_vec.push(v.to_u256_series( + name.to_string(), + u256_type.clone(), + config, + )?) + } + Ok(series_vec) + } + } + } +} + +impl TryInto> for OptionVec +where + T: Default, +{ + type Error = crate::CollectError; + + fn try_into(self) -> Result, Self::Error> { + match self { + OptionVec::Some(v) => Ok(v), + OptionVec::Option(v) => v + .into_iter() + .enumerate() + .map(|(i, opt)| { + opt.ok_or_else(|| { + crate::CollectError::CollectError(format!("Missing value at index {i}")) + }) + }) + .collect::, _>>(), + } + } +} + +impl TryInto>> for OptionVec { + type Error = crate::CollectError; + + fn try_into(self) -> Result>, Self::Error> { + match self { + OptionVec::Some(v) => Ok(v.into_iter().map(Some).collect()), + OptionVec::Option(v) => Ok(v), + } + } +} + +/// A collection of dynamic values that can be used in a DataFrame column. +pub enum DynValues { + /// int + Ints(OptionVec), + /// uint + UInts(OptionVec), + /// u256 + U256s(OptionVec), + /// i256 + I256s(OptionVec), + /// f64 + F64s(OptionVec), + /// bytes + Bytes(OptionVec), + /// bool + Bools(OptionVec), + /// string + Strings(OptionVec), +} + +macro_rules! impl_from_vec { + ($($ty:ty $(, $ty2:ty)* => $variant:ident,)+) => { + $(impl From> for DynValues { + fn from(value: Vec<$ty>) -> Self { + DynValues::$variant(OptionVec::Some(value)) + } + } + impl From>> for DynValues { + fn from(value: Vec>) -> Self { + DynValues::$variant(OptionVec::Option(value)) + } + } + + $(impl From> for DynValues { + fn from(value: Vec<$ty2>) -> Self { + DynValues::$variant(OptionVec::Some(value).map(|v| v.into())) + } + } + impl From>> for DynValues { + fn from(value: Vec>) -> Self { + DynValues::$variant(OptionVec::Option(value).map(|v| v.into())) + } + })* + )+ + }; +} + +impl_from_vec! { + i64, i32 => Ints, + u64, u32 => UInts, + U256 => U256s, + I256 => I256s, + f64, f32 => F64s, + RawBytes => Bytes, + String => Strings, + bool => Bools, +} + +impl DynValues { + /// Returns the data type as a string. + pub fn dtype_str(&self) -> &'static str { + match self { + DynValues::Ints(_) => "Int64", + DynValues::UInts(_) => "UInt64", + DynValues::U256s(_) => "UInt256", + DynValues::I256s(_) => "Int256", + DynValues::F64s(_) => "Float64", + DynValues::Bytes(_) => "Binary", + DynValues::Bools(_) => "Boolean", + DynValues::Strings(_) => "String", + } + } + + /// Create a new `DynValues` instance from a vector of `DynSolValue`s. + pub fn from_sol_values( + data: Vec, + _config: &TableConfig, + ) -> Result { + // This is a smooth brain way of doing this, but I can't think of a better way right now + let mut ints: Vec = vec![]; + let mut uints: Vec = vec![]; + let mut u256s: Vec = vec![]; + let mut i256s: Vec = vec![]; + let mut bytes: Vec = vec![]; + let mut bools: Vec = vec![]; + let mut strings: Vec = vec![]; + // TODO: support array & tuple types + + for token in data { + match token { + DynSolValue::Address(a) => { + bytes.push(a.to_vec()); + } + DynSolValue::FixedBytes(b, _) => { + bytes.push(b.to_vec()); + } + DynSolValue::Bytes(b) => { + bytes.push(b); + } + DynSolValue::Uint(i, size) => { + if size <= 64 { + uints.push(i.wrapping_to::()) + } else { + u256s.push(i) + } + } + DynSolValue::Int(i, size) => { + if size <= 64 { + ints.push(i.unchecked_into()); + } else { + i256s.push(i); + } + } + DynSolValue::Bool(b) => bools.push(b), + DynSolValue::String(s) => strings.push(s), + DynSolValue::Array(_) | DynSolValue::FixedArray(_) => {} + DynSolValue::Tuple(_) => {} + DynSolValue::Function(_) => {} + } + } + + let result = if !ints.is_empty() { + DynValues::Ints(OptionVec::Some(ints)) + } else if !i256s.is_empty() { + DynValues::I256s(OptionVec::Some(i256s)) + } else if !u256s.is_empty() { + DynValues::U256s(OptionVec::Some(u256s)) + } else if !uints.is_empty() { + DynValues::UInts(OptionVec::Some(uints)) + } else if !bytes.is_empty() { + DynValues::Bytes(OptionVec::Some(bytes)) + } else if !bools.is_empty() { + DynValues::Bools(OptionVec::Some(bools)) + } else if !strings.is_empty() { + DynValues::Strings(OptionVec::Some(strings)) + } else { + return Err(err("could not parse column, mixed type")) + }; + Ok(result) + } + + /// Returns whether the underlying data is empty. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Returns the length of the underlying data. + pub fn len(&self) -> usize { + match self { + DynValues::Ints(ints) => ints.len(), + DynValues::I256s(i256s) => i256s.len(), + DynValues::U256s(u256s) => u256s.len(), + DynValues::UInts(uints) => uints.len(), + DynValues::F64s(f64s) => f64s.len(), + DynValues::Bytes(bytes) => bytes.len(), + DynValues::Bools(bools) => bools.len(), + DynValues::Strings(strings) => strings.len(), + } + } + + /// Converts the `DynValues` into `Vec`. + pub fn into_columns( + self, + name: String, + col_type: ColumnType, + config: &TableConfig, + ) -> Result, CollectError> { + let mixed_type_err = format!( + "could not parse column {name}, mixed type expect {col_type:?}, actually {}", + self.dtype_str(), + ); + match self { + Self::Ints(ints) => match col_type { + ColumnType::Int256 => { + ints.map(|v| I256::try_from(v).unwrap()).into_u256_columns(name, config) + } + ColumnType::Int32 => Ok(vec![ints.map(|v| v as i32).into_column(name)]), + ColumnType::Int64 => Ok(vec![ints.into_column(name)]), + ColumnType::Float32 => Ok(vec![ints.map(|v| v as f32).into_column(name)]), + ColumnType::Float64 => Ok(vec![ints.map(|v| v as f64).into_column(name)]), + _ => Err(err(&mixed_type_err)), + }, + Self::UInts(uints) => match col_type { + ColumnType::UInt256 => uints.map(|v| U256::from(v)).into_u256_columns(name, config), + ColumnType::UInt32 => Ok(vec![uints.map(|v| v as u32).into_column(name)]), + ColumnType::UInt64 => Ok(vec![uints.into_column(name)]), + ColumnType::Float32 => Ok(vec![uints.map(|v| v as f32).into_column(name)]), + ColumnType::Float64 => Ok(vec![uints.map(|v| v as f64).into_column(name)]), + _ => Err(err(&mixed_type_err)), + }, + Self::I256s(i256s) => match col_type { + ColumnType::Int256 => i256s.into_u256_columns(name, config), + ColumnType::Float32 => { + Ok(vec![i256s.to_u256_series(name, U256Type::F32, config)?]) + } + ColumnType::Float64 => { + Ok(vec![i256s.to_u256_series(name, U256Type::F64, config)?]) + } + ColumnType::Binary => { + Ok(vec![i256s.to_u256_series(name, U256Type::Binary, config)?]) + } + _ => Err(err(&mixed_type_err)), + }, + Self::U256s(u256s) => match col_type { + ColumnType::UInt256 => u256s.into_u256_columns(name, config), + ColumnType::Float32 => { + Ok(vec![u256s.to_u256_series(name, U256Type::F32, config)?]) + } + ColumnType::Float64 => { + Ok(vec![u256s.to_u256_series(name, U256Type::F64, config)?]) + } + ColumnType::Binary => { + Ok(vec![u256s.to_u256_series(name, U256Type::Binary, config)?]) + } + _ => Err(err(&mixed_type_err)), + }, + Self::F64s(f64s) => match col_type { + ColumnType::Float32 => Ok(vec![f64s.map(|v| v as f32).into_column(name)]), + ColumnType::Float64 => Ok(vec![f64s.into_column(name)]), + _ => Err(err(&mixed_type_err)), + }, + Self::Bytes(bytes) => match col_type { + ColumnType::Binary => Ok(vec![bytes.into_column(name)]), + ColumnType::Hex => Ok(vec![bytes.to_vec_hex(config.hex_prefix).into_column(name)]), + _ => Err(err(&mixed_type_err)), + }, + Self::Bools(bools) => Ok(vec![bools.into_column(name)]), + Self::Strings(strings) => Ok(vec![strings.into_column(name)]), + } + } +} diff --git a/crates/freeze/src/types/dataframes/export.rs b/crates/freeze/src/types/dataframes/export.rs index 1e544988..36fb3844 100644 --- a/crates/freeze/src/types/dataframes/export.rs +++ b/crates/freeze/src/types/dataframes/export.rs @@ -30,8 +30,13 @@ fn df_to_parquet( file_output: &FileOutput, ) -> Result<(), FileError> { let file = std::fs::File::create(filename).map_err(|_e| FileError::FileWriteError)?; + let statistics_options = if file_output.parquet_statistics { + StatisticsOptions::full() + } else { + StatisticsOptions::empty() + }; let result = ParquetWriter::new(file) - .with_statistics(file_output.parquet_statistics) + .with_statistics(statistics_options) .with_compression(file_output.parquet_compression) .with_row_group_size(file_output.row_group_size) .finish(df); diff --git a/crates/freeze/src/types/dataframes/mod.rs b/crates/freeze/src/types/dataframes/mod.rs index 2ba14267..77e45c6c 100644 --- a/crates/freeze/src/types/dataframes/mod.rs +++ b/crates/freeze/src/types/dataframes/mod.rs @@ -1,3 +1,4 @@ +mod dyn_values; mod export; mod read; mod sort; @@ -6,6 +7,7 @@ mod u256s; #[macro_use] mod creation; +pub use dyn_values::*; pub(crate) use export::*; pub use read::*; pub(crate) use sort::SortableDataFrame; diff --git a/crates/freeze/src/types/dataframes/read.rs b/crates/freeze/src/types/dataframes/read.rs index c18da73d..9b261e12 100644 --- a/crates/freeze/src/types/dataframes/read.rs +++ b/crates/freeze/src/types/dataframes/read.rs @@ -1,8 +1,8 @@ -use crate::ParseError; +use crate::{ParseError, RawBytes}; use polars::prelude::*; -/// read single binary column of parquet file as Vec -pub fn read_binary_column(path: &str, column: &str) -> Result>, ParseError> { +/// read single binary column of parquet file as RawBytes +pub fn read_binary_column(path: &str, column: &str) -> Result, ParseError> { let file = std::fs::File::open(path) .map_err(|_e| ParseError::ParseError("could not open file path".to_string()))?; diff --git a/crates/freeze/src/types/dataframes/sort.rs b/crates/freeze/src/types/dataframes/sort.rs index 85bf07a6..663e90c0 100644 --- a/crates/freeze/src/types/dataframes/sort.rs +++ b/crates/freeze/src/types/dataframes/sort.rs @@ -10,7 +10,7 @@ impl SortableDataFrame for Result { fn sort_by_schema(self, schema: &Table) -> Self { match (self, &schema.sort_columns) { (Ok(df), Some(sort_columns)) => { - df.sort(sort_columns, false, false).map_err(CollectError::PolarsError) + df.sort(sort_columns, SortMultipleOptions::new()).map_err(CollectError::PolarsError) } (df, _) => df, } diff --git a/crates/freeze/src/types/dataframes/u256s.rs b/crates/freeze/src/types/dataframes/u256s.rs index 9e476892..e6feafa0 100644 --- a/crates/freeze/src/types/dataframes/u256s.rs +++ b/crates/freeze/src/types/dataframes/u256s.rs @@ -9,8 +9,36 @@ pub trait ToU256Series { &self, name: String, dtype: U256Type, - column_encoding: &ColumnEncoding, - ) -> Result; + config: &TableConfig, + ) -> Result; +} + +impl ToU256Series for OptionVec { + fn to_u256_series( + &self, + name: String, + dtype: U256Type, + config: &TableConfig, + ) -> Result { + match self { + OptionVec::Some(v) => v.to_u256_series(name, dtype, config), + OptionVec::Option(v) => v.to_u256_series(name, dtype, config), + } + } +} + +impl ToU256Series for OptionVec { + fn to_u256_series( + &self, + name: String, + dtype: U256Type, + config: &TableConfig, + ) -> Result { + match self { + OptionVec::Some(v) => v.to_u256_series(name, dtype, config), + OptionVec::Option(v) => v.to_u256_series(name, dtype, config), + } + } } impl ToU256Series for Vec { @@ -18,40 +46,42 @@ impl ToU256Series for Vec { &self, name: String, dtype: U256Type, - column_encoding: &ColumnEncoding, - ) -> Result { - let name = name + dtype.suffix().as_str(); - let name = name.as_str(); + config: &TableConfig, + ) -> Result { + let name = name + dtype.suffix(ColumnType::UInt256).as_str(); + let name = PlSmallStr::from_string(name); match dtype { - U256Type::Binary => { - let converted: Vec> = self.iter().map(|v| v.to_vec_u8()).collect(); - match column_encoding { - ColumnEncoding::Hex => Ok(Series::new(name, converted.to_vec_hex())), - ColumnEncoding::Binary => Ok(Series::new(name, converted)), + U256Type::Binary | U256Type::NamedBinary => { + let converted: Vec = self.iter().map(|v| v.to_vec_u8()).collect(); + match config.binary_type { + ColumnEncoding::Hex => { + Ok(Column::new(name, converted.to_vec_hex(config.hex_prefix))) + } + ColumnEncoding::Binary => Ok(Column::new(name, converted)), } } U256Type::String => { let converted: Vec = self.iter().map(|v| v.to_string()).collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::F32 => { let converted: Vec> = self.iter().map(|v| v.to_string().parse::().ok()).collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::F64 => { let converted: Vec> = self.iter().map(|v| v.to_string().parse::().ok()).collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::U32 => { let converted: Vec = self.iter().map(|v| v.wrapping_to::()).collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::U64 => { let converted: Vec = self.iter().map(|v| v.wrapping_to::()).collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::Decimal128 => { Err(CollectError::CollectError("DECIMAL128 not implemented".to_string())) @@ -65,48 +95,50 @@ impl ToU256Series for Vec> { &self, name: String, dtype: U256Type, - column_encoding: &ColumnEncoding, - ) -> Result { - let name = name + dtype.suffix().as_str(); - let name = name.as_str(); + config: &TableConfig, + ) -> Result { + let name = name + dtype.suffix(ColumnType::UInt256).as_str(); + let name = PlSmallStr::from_string(name); match dtype { - U256Type::Binary => { - let converted: Vec>> = + U256Type::Binary | U256Type::NamedBinary => { + let converted: Vec> = self.iter().map(|v| v.map(|x| x.to_vec_u8())).collect(); - match column_encoding { - ColumnEncoding::Hex => Ok(Series::new(name, converted.to_vec_hex())), - ColumnEncoding::Binary => Ok(Series::new(name, converted)), + match config.binary_type { + ColumnEncoding::Hex => { + Ok(Column::new(name, converted.to_vec_hex(config.hex_prefix))) + } + ColumnEncoding::Binary => Ok(Column::new(name, converted)), } } U256Type::String => { let converted: Vec> = self.iter().map(|v| v.map(|x| x.to_string())).collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::F32 => { let converted: Vec> = self .iter() .map(|v| v.map(|x| x.to_string().parse::().ok()).flatten()) .collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::F64 => { let converted: Vec> = self .iter() .map(|v| v.map(|x| x.to_string().parse::().ok()).flatten()) .collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::U32 => { let converted: Vec> = self.iter().map(|v| v.map(|x| x.wrapping_to::())).collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::U64 => { let converted: Vec> = self.iter().map(|v| v.map(|x| x.wrapping_to::())).collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::Decimal128 => { Err(CollectError::CollectError("DECIMAL128 not implemented".to_string())) @@ -120,40 +152,42 @@ impl ToU256Series for Vec { &self, name: String, dtype: U256Type, - column_encoding: &ColumnEncoding, - ) -> Result { - let name = name + dtype.suffix().as_str(); - let name = name.as_str(); + config: &TableConfig, + ) -> Result { + let name = name + dtype.suffix(ColumnType::Int256).as_str(); + let name = PlSmallStr::from_string(name); match dtype { - U256Type::Binary => { - let converted: Vec> = self.iter().map(|v| v.to_vec_u8()).collect(); - match column_encoding { - ColumnEncoding::Hex => Ok(Series::new(name, converted.to_vec_hex())), - ColumnEncoding::Binary => Ok(Series::new(name, converted)), + U256Type::Binary | U256Type::NamedBinary => { + let converted: Vec = self.iter().map(|v| v.to_vec_u8()).collect(); + match config.binary_type { + ColumnEncoding::Hex => { + Ok(Column::new(name, converted.to_vec_hex(config.hex_prefix))) + } + ColumnEncoding::Binary => Ok(Column::new(name, converted)), } } U256Type::String => { let converted: Vec = self.iter().map(|v| v.to_string()).collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::F32 => { let converted: Vec> = self.iter().map(|v| v.to_string().parse::().ok()).collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::F64 => { let converted: Vec> = self.iter().map(|v| v.to_string().parse::().ok()).collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::U32 => { let converted: Vec = self.iter().map(|v| v.as_u32()).collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::U64 => { let converted: Vec = self.iter().map(|v| v.as_u64()).collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::Decimal128 => { Err(CollectError::CollectError("DECIMAL128 not implemented".to_string())) @@ -167,48 +201,50 @@ impl ToU256Series for Vec> { &self, name: String, dtype: U256Type, - column_encoding: &ColumnEncoding, - ) -> Result { - let name = name + dtype.suffix().as_str(); - let name = name.as_str(); + config: &TableConfig, + ) -> Result { + let name = name + dtype.suffix(ColumnType::Int256).as_str(); + let name = PlSmallStr::from_string(name); match dtype { - U256Type::Binary => { - let converted: Vec>> = + U256Type::Binary | U256Type::NamedBinary => { + let converted: Vec> = self.iter().map(|v| v.map(|x| x.to_vec_u8())).collect(); - match column_encoding { - ColumnEncoding::Hex => Ok(Series::new(name, converted.to_vec_hex())), - ColumnEncoding::Binary => Ok(Series::new(name, converted)), + match config.binary_type { + ColumnEncoding::Hex => { + Ok(Column::new(name, converted.to_vec_hex(config.hex_prefix))) + } + ColumnEncoding::Binary => Ok(Column::new(name, converted)), } } U256Type::String => { let converted: Vec> = self.iter().map(|v| v.map(|x| x.to_string())).collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::F32 => { let converted: Vec> = self .iter() .map(|v| v.map(|x| x.to_string().parse::().ok()).flatten()) .collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::F64 => { let converted: Vec> = self .iter() .map(|v| v.map(|x| x.to_string().parse::().ok()).flatten()) .collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::U32 => { let converted: Vec> = self.iter().map(|v| v.map(|x| x.as_u32())).collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::U64 => { let converted: Vec> = self.iter().map(|v| v.map(|x| x.as_u64())).collect(); - Ok(Series::new(name, converted)) + Ok(Column::new(name, converted)) } U256Type::Decimal128 => { Err(CollectError::CollectError("DECIMAL128 not implemented".to_string())) diff --git a/crates/freeze/src/types/datatypes/datatype_macros.rs b/crates/freeze/src/types/datatypes/datatype_macros.rs index 00fc1cb4..6a6d3193 100644 --- a/crates/freeze/src/types/datatypes/datatype_macros.rs +++ b/crates/freeze/src/types/datatypes/datatype_macros.rs @@ -97,7 +97,7 @@ macro_rules! define_datatypes { } } - /// whether datatype can be collected by block + /// whether datatype can be collected by transaction pub fn can_collect_by_transaction(&self) -> bool { match *self { $(Datatype::$datatype => $datatype::can_collect_by_transaction(),)* diff --git a/crates/freeze/src/types/datatypes/multi.rs b/crates/freeze/src/types/datatypes/multi.rs index 9e2a28ac..3cce8111 100644 --- a/crates/freeze/src/types/datatypes/multi.rs +++ b/crates/freeze/src/types/datatypes/multi.rs @@ -62,6 +62,6 @@ impl MultiDatatype { /// name pub fn name(&self) -> String { - format!("{}", heck::AsSnakeCase(format!("{:?}", self))) + format!("{}", heck::AsSnakeCase(format!("{self:?}"))) } } diff --git a/crates/freeze/src/types/datatypes/scalar.rs b/crates/freeze/src/types/datatypes/scalar.rs index 6f86bd8e..ffd54710 100644 --- a/crates/freeze/src/types/datatypes/scalar.rs +++ b/crates/freeze/src/types/datatypes/scalar.rs @@ -68,6 +68,6 @@ impl std::str::FromStr for Datatype { fn from_str(s: &str) -> Result { let mut map = Datatype::alias_map()?; map.remove(s) - .ok_or_else(|| ParseError::ParseError(format!("no datatype matches input: {}", s))) + .ok_or_else(|| ParseError::ParseError(format!("no datatype matches input: {s}"))) } } diff --git a/crates/freeze/src/types/decoders/log_decoder.rs b/crates/freeze/src/types/decoders/log_decoder.rs index b107b60b..4e9efd1b 100644 --- a/crates/freeze/src/types/decoders/log_decoder.rs +++ b/crates/freeze/src/types/decoders/log_decoder.rs @@ -1,12 +1,8 @@ -use crate::{err, CollectError, ColumnEncoding, ToU256Series, U256Type}; use alloy::{ - dyn_abi::{DynSolValue, EventExt}, - hex::ToHexExt, - json_abi::Event, - primitives::{I256, U256}, + dyn_abi::{DynSolType, DynSolValue, EventExt}, + json_abi::{Event, EventParam}, rpc::types::Log, }; -use polars::prelude::*; /// container for log decoding context #[derive(Clone, Debug, PartialEq)] @@ -18,6 +14,14 @@ pub struct LogDecoder { pub event: Event, } +fn get_param_name(param: &EventParam, idx: usize) -> String { + if param.name.is_empty() { + format!("arg{idx}") + } else { + param.name.clone() + } +} + impl LogDecoder { /// create a new LogDecoder from an event signature /// ex: LogDecoder::new("event Transfer(address indexed from, address indexed to, uint256 @@ -26,8 +30,8 @@ impl LogDecoder { match Event::parse(&event_signature) { Ok(event) => Ok(Self { event, raw: event_signature.clone() }), Err(e) => { - let err = format!("incorrectly formatted event {} (expect something like event Transfer(address indexed from, address indexed to, uint256 amount) err: {}", event_signature, e); - eprintln!("{}", err); + let err = format!("incorrectly formatted event {event_signature} (expect something like event Transfer(address indexed from, address indexed to, uint256 amount) err: {e}"); + error!("{err}"); Err(err) } } @@ -35,7 +39,51 @@ impl LogDecoder { /// get field names of event inputs pub fn field_names(&self) -> Vec { - self.event.inputs.iter().map(|i| i.name.clone()).collect() + self.event + .inputs + .iter() + .enumerate() + .map(|(idx, param)| get_param_name(param, idx)) + .collect() + } + + /// get field names of indexed event inputs + pub fn indexed_names(&self) -> Vec { + self.event + .inputs + .iter() + .enumerate() + .filter_map( + |(idx, param)| if param.indexed { Some(get_param_name(param, idx)) } else { None }, + ) + .collect() + } + + /// get field names of non-indexed event inputs + pub fn body_names(&self) -> Vec { + self.event + .inputs + .iter() + .enumerate() + .filter_map( + |(idx, param)| if !param.indexed { Some(get_param_name(param, idx)) } else { None }, + ) + .collect() + } + + /// get field types of event inputs + pub fn field_types(&self) -> Vec { + self.event.inputs.iter().map(|i| DynSolType::parse(&i.ty).unwrap()).collect() + } + + /// get field names and types of event inputs + pub fn field_names_and_types(&self) -> Vec<(String, DynSolType)> { + self.event + .inputs + .iter() + .enumerate() + .map(|(idx, param)| (get_param_name(param, idx), DynSolType::parse(¶m.ty).unwrap())) + .collect() } /// converts from a log type to an abi token type @@ -62,8 +110,7 @@ impl LogDecoder { .collect(); for log in logs { - match self.event.decode_log_parts(log.topics().to_vec(), log.data().data.as_ref(), true) - { + match self.event.decode_log_parts(log.topics().to_vec(), log.data().data.as_ref()) { Ok(decoded) => { for (idx, param) in decoded.indexed.into_iter().enumerate() { map.entry(indexed_keys[idx].clone()).or_default().push(param); @@ -72,120 +119,9 @@ impl LogDecoder { map.entry(body_keys[idx].clone()).or_default().push(param); } } - Err(e) => eprintln!("error parsing log: {:?}", e), + Err(e) => error!("error parsing log: {e:?}"), } } map } - - /// data should never be mixed type, otherwise this will return inconsistent results - pub fn make_series( - &self, - name: String, - data: Vec, - chunk_len: usize, - u256_types: &[U256Type], - column_encoding: &ColumnEncoding, - ) -> Result, CollectError> { - // This is a smooth brain way of doing this, but I can't think of a better way right now - let mut ints: Vec = vec![]; - let mut uints: Vec = vec![]; - let mut u256s: Vec = vec![]; - let mut i256s: Vec = vec![]; - let mut bytes: Vec> = vec![]; - let mut hexes: Vec = vec![]; - let mut bools: Vec = vec![]; - let mut strings: Vec = vec![]; - // TODO: support array & tuple types - - for token in data { - match token { - DynSolValue::Address(a) => match column_encoding { - ColumnEncoding::Binary => bytes.push(a.to_vec()), - ColumnEncoding::Hex => hexes.push(format!("{:?}", a)), - }, - DynSolValue::FixedBytes(b, _) => match column_encoding { - ColumnEncoding::Binary => bytes.push(b.to_vec()), - ColumnEncoding::Hex => hexes.push(b.encode_hex()), - }, - DynSolValue::Bytes(b) => match column_encoding { - ColumnEncoding::Binary => bytes.push(b), - ColumnEncoding::Hex => hexes.push(b.encode_hex()), - }, - DynSolValue::Uint(i, size) => { - if size <= 64 { - uints.push(i.wrapping_to::()) - } else { - u256s.push(i) - } - } - DynSolValue::Int(i, size) => { - if size <= 64 { - ints.push(i.unchecked_into()); - } else { - i256s.push(i); - } - } - DynSolValue::Bool(b) => bools.push(b), - DynSolValue::String(s) => strings.push(s), - DynSolValue::Array(_) | DynSolValue::FixedArray(_) => {} - DynSolValue::Tuple(_) => {} - DynSolValue::Function(_) => {} - } - } - let mixed_length_err = format!("could not parse column {}, mixed type", name); - let mixed_length_err = mixed_length_err.as_str(); - - // check each vector, see if it contains any values, if it does, check if it's the same - // length as the input data and map to a series - let name = format!("event__{}", name); - if !ints.is_empty() { - Ok(vec![Series::new(name.as_str(), ints)]) - } else if !i256s.is_empty() { - let mut series_vec = Vec::new(); - for u256_type in u256_types.iter() { - series_vec.push(i256s.to_u256_series( - name.clone(), - u256_type.clone(), - column_encoding, - )?) - } - Ok(series_vec) - } else if !u256s.is_empty() { - let mut series_vec: Vec = Vec::new(); - for u256_type in u256_types.iter() { - series_vec.push(u256s.to_u256_series( - name.clone(), - u256_type.clone(), - column_encoding, - )?) - } - Ok(series_vec) - } else if !uints.is_empty() { - Ok(vec![Series::new(name.as_str(), uints)]) - } else if !bytes.is_empty() { - if bytes.len() != chunk_len { - return Err(err(mixed_length_err)) - } - Ok(vec![Series::new(name.as_str(), bytes)]) - } else if !hexes.is_empty() { - if hexes.len() != chunk_len { - return Err(err(mixed_length_err)) - } - Ok(vec![Series::new(name.as_str(), hexes)]) - } else if !bools.is_empty() { - if bools.len() != chunk_len { - return Err(err(mixed_length_err)) - } - Ok(vec![Series::new(name.as_str(), bools)]) - } else if !strings.is_empty() { - if strings.len() != chunk_len { - return Err(err(mixed_length_err)) - } - Ok(vec![Series::new(name.as_str(), strings)]) - } else { - // case where no data was passed - Ok(vec![Series::new(name.as_str(), vec![None::; chunk_len])]) - } - } } diff --git a/crates/freeze/src/types/errors.rs b/crates/freeze/src/types/errors.rs index fe3bae20..9b1031d0 100644 --- a/crates/freeze/src/types/errors.rs +++ b/crates/freeze/src/types/errors.rs @@ -109,6 +109,10 @@ pub enum ParseError { /// Parse url error #[error("Parsing url error: {0}")] ParseUrlError(url::ParseError), + + /// Parse jwt error + #[error("Parsing jwt error: {0}")] + ParseJwtError(String), } impl From for ParseError { diff --git a/crates/freeze/src/types/files.rs b/crates/freeze/src/types/files.rs index bfbca16d..0250298a 100644 --- a/crates/freeze/src/types/files.rs +++ b/crates/freeze/src/types/files.rs @@ -128,7 +128,7 @@ impl FileFormat { } /// Encoding for binary data in a column -#[derive(Clone, Eq, PartialEq, Debug)] +#[derive(Clone, Copy, Eq, PartialEq, Debug)] pub enum ColumnEncoding { /// Raw binary encoding Binary, diff --git a/crates/freeze/src/types/mod.rs b/crates/freeze/src/types/mod.rs index b0e163d6..6b861a19 100644 --- a/crates/freeze/src/types/mod.rs +++ b/crates/freeze/src/types/mod.rs @@ -10,7 +10,7 @@ pub mod sources; /// column data specification pub mod columns; -pub use columns::{ColumnData, Dataset, ToDataFrames}; +pub use columns::{ColumnData, Dataset, FromDataFrames, ToDataFrames}; /// partitions pub mod partitions; @@ -50,16 +50,16 @@ pub mod schemas; pub mod summaries; pub use chunks::{ - AddressChunk, BlockChunk, CallDataChunk, Chunk, ChunkData, ChunkStats, SlotChunk, Subchunk, - TopicChunk, TransactionChunk, + AddressChunk, BlockChunk, CallDataChunk, Chunk, ChunkData, ChunkStats, RawBytes, SlotChunk, + Subchunk, TopicChunk, TransactionChunk, }; -pub use conversions::{bytes_to_u32, ToVecHex, ToVecU8}; +pub use conversions::{bytes_to_u32, FromBinaryVec, ToVecHex, ToVecU8}; pub use dataframes::*; pub use datatypes::*; pub use files::{ColumnEncoding, FileFormat, FileOutput, SubDir}; pub use queries::{Query, QueryLabels, TimeDimension}; -pub use schemas::{ColumnType, SchemaFunctions, Schemas, Table, U256Type}; -pub use sources::{Fetcher, RateLimiter, Source, SourceLabels}; +pub use schemas::{ColumnType, SchemaFunctions, Schemas, Table, TableConfig, U256Type}; +pub use sources::{RateLimiter, Source, SourceLabels}; // pub(crate) use summaries::FreezeSummaryAgg; // pub use summaries::{FreezeChunkSummary, FreezeSummary}; pub use summaries::{print_all_datasets, print_dataset_info, FreezeSummary}; diff --git a/crates/freeze/src/types/partitions.rs b/crates/freeze/src/types/partitions.rs index 50487f38..86950540 100644 --- a/crates/freeze/src/types/partitions.rs +++ b/crates/freeze/src/types/partitions.rs @@ -114,7 +114,7 @@ impl std::fmt::Display for Dim { Dim::Topic2 => "topic2", Dim::Topic3 => "topic3", }; - write!(f, "{}", as_str) + write!(f, "{as_str}") } } diff --git a/crates/freeze/src/types/schemas.rs b/crates/freeze/src/types/schemas.rs index 54201ee8..7d049a72 100644 --- a/crates/freeze/src/types/schemas.rs +++ b/crates/freeze/src/types/schemas.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use crate::{err, CollectError, ColumnEncoding, Datatype, LogDecoder}; +use alloy::dyn_abi::DynSolType; use indexmap::{IndexMap, IndexSet}; use thiserror::Error; @@ -20,6 +21,20 @@ impl SchemaFunctions for HashMap { } } +/// type related config of table +#[derive(Clone, Debug, PartialEq)] +pub struct TableConfig { + /// representations to use for u256 columns + pub u256_types: Vec, + + /// representation to use for binary columns + pub binary_type: ColumnEncoding, + + /// whether to include hex prefix for hex columns + pub hex_prefix: bool, + // pub hex_upper: bool, +} + /// Schema for a particular table #[derive(Clone, Debug, PartialEq)] pub struct Table { @@ -31,11 +46,8 @@ pub struct Table { /// sort order for rows pub sort_columns: Option>, - /// representations to use for u256 columns - pub u256_types: Vec, - - /// representation to use for binary columns - pub binary_type: ColumnEncoding, + /// type config for table + pub config: TableConfig, /// log decoder for table pub log_decoder: Option, @@ -63,6 +75,10 @@ impl Table { pub enum U256Type { /// Binary representation Binary, + /// Binary representation, but with a variant name, + /// for U256, suffix would be _u256binary, + /// for I256, suffix would be _i256binary. + NamedBinary, /// String representation String, /// F32 representation @@ -79,9 +95,12 @@ pub enum U256Type { impl U256Type { /// convert U256Type to Columntype - pub fn to_columntype(&self) -> ColumnType { + pub fn to_columntype(&self, column_encoding: ColumnEncoding) -> ColumnType { match self { - U256Type::Binary => ColumnType::Binary, + U256Type::Binary | U256Type::NamedBinary => match column_encoding { + ColumnEncoding::Binary => ColumnType::Binary, + ColumnEncoding::Hex => ColumnType::Hex, + }, U256Type::String => ColumnType::String, U256Type::F32 => ColumnType::Float32, U256Type::F64 => ColumnType::Float64, @@ -92,9 +111,15 @@ impl U256Type { } /// get column name suffix of U256Type - pub fn suffix(&self) -> String { + pub fn suffix(&self, original_type: ColumnType) -> String { match self { U256Type::Binary => "_binary".to_string(), + U256Type::NamedBinary => match original_type { + ColumnType::UInt256 => "_u256binary".to_string(), + ColumnType::Int256 => "_i256binary".to_string(), + ColumnType::Binary => unreachable!("recursive binary type suffix"), + _ => format!("_{}binary", original_type.as_str()), + }, U256Type::String => "_string".to_string(), U256Type::F32 => "_f32".to_string(), U256Type::F64 => "_f64".to_string(), @@ -120,6 +145,8 @@ pub enum ColumnType { Int32, /// Int64 column type Int64, + /// I256 column type + Int256, /// Float32 column type Float32, /// Float64 column type @@ -135,6 +162,11 @@ pub enum ColumnType { } impl ColumnType { + /// check if column is UInt256 or Int256 + pub fn is_256(&self) -> bool { + matches!(self, ColumnType::UInt256 | ColumnType::Int256) + } + /// convert ColumnType to str pub fn as_str(&self) -> &'static str { match *self { @@ -144,6 +176,7 @@ impl ColumnType { ColumnType::UInt256 => "uint256", ColumnType::Int32 => "int32", ColumnType::Int64 => "int64", + ColumnType::Int256 => "int256", ColumnType::Float32 => "float32", ColumnType::Float64 => "float64", ColumnType::Decimal128 => "decimal128", @@ -152,6 +185,43 @@ impl ColumnType { ColumnType::Hex => "hex", } } + + /// Convert [`DynSolType`] to [`ColumnType`] + pub fn from_sol_type( + sol_type: &DynSolType, + binary_type: ColumnEncoding, + ) -> Result { + let result = match sol_type { + DynSolType::Address | DynSolType::Bytes | DynSolType::FixedBytes(_) => { + match binary_type { + ColumnEncoding::Binary => ColumnType::Binary, + ColumnEncoding::Hex => ColumnType::Hex, + } + } + DynSolType::Int(bits) => { + if *bits <= 64 { + ColumnType::Int64 + } else { + ColumnType::Int256 + } + } + DynSolType::Uint(bits) => { + if *bits <= 64 { + ColumnType::UInt64 + } else { + ColumnType::UInt256 + } + } + DynSolType::Bool => ColumnType::Boolean, + DynSolType::String => ColumnType::String, + DynSolType::Array(_) => return Err(SchemaError::InvalidSolType("Array")), + DynSolType::FixedArray(_, _) => return Err(SchemaError::InvalidSolType("FixedArray")), + DynSolType::Tuple(_) => return Err(SchemaError::InvalidSolType("Tuple")), + DynSolType::Function => return Err(SchemaError::InvalidSolType("Function")), + // _ => return Err(SchemaError::InvalidSolType("Unknown")), + }; + Ok(result) + } } /// Error related to Schemas @@ -159,16 +229,34 @@ impl ColumnType { pub enum SchemaError { /// Invalid column being operated on #[error("Invalid column")] - InvalidColumn, + InvalidColumn(String), + /// Error converting column type + #[error("Invalid column type, {0}")] + InvalidSolType(&'static str), + /// Conflict column names + #[error("Conflict column names: {0:?}")] + ConflictColumnNames(Vec), } impl Datatype { + /// get default table schema for a particular datatype + pub fn default_table_schema(&self, config: TableConfig) -> Table { + let column_types = + self.column_types().into_iter().map(|(k, v)| (k.to_string(), v)).collect(); + Table { + datatype: *self, + sort_columns: None, + columns: column_types, + config, + log_decoder: None, + } + } + /// get schema for a particular datatype #[allow(clippy::too_many_arguments)] pub fn table_schema( &self, - u256_types: &[U256Type], - binary_column_format: &ColumnEncoding, + config: TableConfig, include_columns: &Option>, exclude_columns: &Option>, columns: &Option>, @@ -176,8 +264,36 @@ impl Datatype { log_decoder: Option, ) -> Result { let column_types = self.column_types(); - let all_columns = column_types.keys().map(|k| k.to_string()).collect(); - let default_columns = self.default_columns(); + let mut additional_column_types = IndexMap::new(); + let mut all_columns: IndexSet<_> = column_types.keys().map(|k| k.to_string()).collect(); + let mut default_columns: Vec<_> = + self.default_columns().iter().map(|s| s.to_string()).collect(); + if let Some(log_decoder) = &log_decoder { + let event_names = log_decoder + .field_names() + .into_iter() + .map(|s| format!("event__{s}")) + .collect::>(); + default_columns.extend(event_names.clone()); + let expected_len = all_columns.len() + event_names.len(); + all_columns.extend(event_names.clone()); + if all_columns.len() != expected_len { + return Err(SchemaError::ConflictColumnNames(event_names.clone())); + } + let drop_names = [ + "topic1".to_string(), + "topic2".to_string(), + "topic3".to_string(), + "data".to_string(), + ]; + default_columns.retain(|i| !drop_names.contains(i)); + additional_column_types.extend( + log_decoder + .field_names_and_types() + .into_iter() + .map(|(name, ty)| (format!("event__{name}"), ty)), + ); + } let used_columns = compute_used_columns( all_columns, default_columns, @@ -187,28 +303,29 @@ impl Datatype { ); let mut columns = IndexMap::new(); for column in used_columns { - let mut ctype = column_types.get(column.as_str()).ok_or(SchemaError::InvalidColumn)?; - if (*binary_column_format == ColumnEncoding::Hex) & (ctype == &ColumnType::Binary) { - ctype = &ColumnType::Hex; + let mut ctype = match column_types.get(column.as_str()) { + Some(ctype) => *ctype, + None => { + let sol_type = additional_column_types + .get(column.as_str()) + .ok_or_else(|| SchemaError::InvalidColumn(column.clone()))?; + ColumnType::from_sol_type(sol_type, config.binary_type)? + } + }; + if config.binary_type == ColumnEncoding::Hex && ctype == ColumnType::Binary { + ctype = ColumnType::Hex; } - columns.insert((*column.clone()).to_string(), *ctype); + columns.insert((*column.clone()).to_string(), ctype); } - let schema = Table { - datatype: *self, - sort_columns: sort, - columns, - u256_types: u256_types.to_owned(), - binary_type: binary_column_format.clone(), - log_decoder, - }; + let schema = Table { datatype: *self, sort_columns: sort, columns, config, log_decoder }; Ok(schema) } } fn compute_used_columns( all_columns: IndexSet, - default_columns: Vec<&str>, + default_columns: Vec, include_columns: &Option>, exclude_columns: &Option>, columns: &Option>, @@ -222,13 +339,15 @@ fn compute_used_columns( let mut result_set = IndexSet::from_iter(default_columns.iter().map(|s| s.to_string())); if let Some(include) = include_columns { if (include.len() == 1) & include.contains(&"all".to_string()) { - return all_columns + result_set.clear(); + result_set.extend(all_columns.iter().cloned()); + } else { + // Permissively skip `include` columns that are not in this dataset (they might apply to + // other dataset) + result_set.extend(include.iter().cloned()); } - // Permissively skip `include` columns that are not in this dataset (they might apply to - // other dataset) - result_set.extend(include.iter().cloned()); - result_set = result_set.intersection(&all_columns).cloned().collect() } + result_set = result_set.intersection(&all_columns).cloned().collect(); if let Some(exclude) = exclude_columns { let exclude_set = IndexSet::::from_iter(exclude.iter().cloned()); result_set = result_set.difference(&exclude_set).cloned().collect() @@ -240,23 +359,25 @@ fn compute_used_columns( mod tests { use super::*; - fn get_u256_types() -> Vec { - vec![U256Type::Binary, U256Type::String, U256Type::F64] + fn get_config() -> TableConfig { + TableConfig { + u256_types: vec![U256Type::Binary, U256Type::String, U256Type::F64], + binary_type: ColumnEncoding::Hex, + hex_prefix: true, + } } #[test] fn test_table_schema_explicit_cols() { let cols = Some(vec!["block_number".to_string(), "block_hash".to_string()]); - let table = Datatype::Blocks - .table_schema(&get_u256_types(), &ColumnEncoding::Hex, &None, &None, &cols, None, None) - .unwrap(); + let table = + Datatype::Blocks.table_schema(get_config(), &None, &None, &cols, None, None).unwrap(); assert_eq!(vec!["block_number", "block_hash"], table.columns()); // "all" marker support let cols = Some(vec!["all".to_string()]); - let table = Datatype::Blocks - .table_schema(&get_u256_types(), &ColumnEncoding::Hex, &None, &None, &cols, None, None) - .unwrap(); + let table = + Datatype::Blocks.table_schema(get_config(), &None, &None, &cols, None, None).unwrap(); assert_eq!(21, table.columns().len()); assert!(table.columns().contains(&"block_hash")); assert!(table.columns().contains(&"transactions_root")); @@ -266,15 +387,7 @@ mod tests { fn test_table_schema_include_cols() { let inc_cols = Some(vec!["chain_id".to_string(), "receipts_root".to_string()]); let table = Datatype::Blocks - .table_schema( - &get_u256_types(), - &ColumnEncoding::Hex, - &inc_cols, - &None, - &None, - None, - None, - ) + .table_schema(get_config(), &inc_cols, &None, &None, None, None) .unwrap(); assert_eq!(9, table.columns().len()); assert_eq!(["chain_id", "receipts_root"], table.columns()[7..9]); @@ -282,15 +395,7 @@ mod tests { // Non-existing include is skipped let inc_cols = Some(vec!["chain_id".to_string(), "foo_bar".to_string()]); let table = Datatype::Blocks - .table_schema( - &get_u256_types(), - &ColumnEncoding::Hex, - &inc_cols, - &None, - &None, - None, - None, - ) + .table_schema(get_config(), &inc_cols, &None, &None, None, None) .unwrap(); assert_eq!(Some(&"chain_id"), table.columns().last()); assert!(!table.columns().contains(&"foo_bar")); @@ -298,15 +403,7 @@ mod tests { // "all" marker support let inc_cols = Some(vec!["all".to_string()]); let table = Datatype::Blocks - .table_schema( - &get_u256_types(), - &ColumnEncoding::Hex, - &inc_cols, - &None, - &None, - None, - None, - ) + .table_schema(get_config(), &inc_cols, &None, &None, None, None) .unwrap(); assert_eq!(21, table.columns().len()); assert!(table.columns().contains(&"block_hash")); @@ -316,24 +413,15 @@ mod tests { #[test] fn test_table_schema_exclude_cols() { // defaults - let table = Datatype::Blocks - .table_schema(&get_u256_types(), &ColumnEncoding::Hex, &None, &None, &None, None, None) - .unwrap(); + let table = + Datatype::Blocks.table_schema(get_config(), &None, &None, &None, None, None).unwrap(); assert_eq!(8, table.columns().len()); assert!(table.columns().contains(&"author")); assert!(table.columns().contains(&"extra_data")); let ex_cols = Some(vec!["author".to_string(), "extra_data".to_string()]); let table = Datatype::Blocks - .table_schema( - &get_u256_types(), - &ColumnEncoding::Hex, - &None, - &ex_cols, - &None, - None, - None, - ) + .table_schema(get_config(), &None, &ex_cols, &None, None, None) .unwrap(); assert_eq!(6, table.columns().len()); assert!(!table.columns().contains(&"author")); @@ -342,15 +430,7 @@ mod tests { // Non-existing exclude is ignored let ex_cols = Some(vec!["timestamp".to_string(), "foo_bar".to_string()]); let table = Datatype::Blocks - .table_schema( - &get_u256_types(), - &ColumnEncoding::Hex, - &None, - &ex_cols, - &None, - None, - None, - ) + .table_schema(get_config(), &None, &ex_cols, &None, None, None) .unwrap(); assert_eq!(7, table.columns().len()); assert!(!table.columns().contains(&"timestamp")); @@ -362,19 +442,64 @@ mod tests { let inc_cols = Some(vec!["chain_id".to_string(), "receipts_root".to_string()]); let ex_cols = Some(vec!["author".to_string(), "extra_data".to_string()]); let table = Datatype::Blocks + .table_schema(get_config(), &inc_cols, &ex_cols, &None, None, None) + .unwrap(); + assert!(!table.columns().contains(&"author")); + assert!(!table.columns().contains(&"extra_data")); + assert_eq!(7, table.columns().len()); + assert_eq!(["chain_id", "receipts_root"], table.columns()[5..7]); + } + + #[test] + fn test_table_schema_log_decoder() { + let table = Datatype::Logs .table_schema( - &get_u256_types(), - &ColumnEncoding::Hex, - &inc_cols, - &ex_cols, + get_config(), + &None, + &None, &None, None, + Some( + LogDecoder::new( + "Transfer(address indexed from, address indexed to, uint256 value)" + .to_string(), + ) + .unwrap(), + ), + ) + .unwrap(); + assert!(!table.columns().contains(&"topic1")); + assert!(!table.columns().contains(&"topic2")); + assert!(!table.columns().contains(&"topic3")); + assert!(!table.columns().contains(&"data")); + assert_eq!(table.columns().len(), 11); + assert_eq!(["event__from", "event__to", "event__value"], table.columns()[8..11]); + } + + #[test] + fn test_table_schema_log_decoder_include_exclude_cols() { + let inc_cols = vec!["topic1".to_string(), "data".to_string()]; + let ex_cols = vec!["event__arg0".to_string()]; + let table = Datatype::Logs + .table_schema( + get_config(), + &Some(inc_cols), + &Some(ex_cols), + &None, None, + Some( + LogDecoder::new( + "Transfer(address indexed,address indexed,uint256)".to_string(), + ) + .unwrap(), + ), ) .unwrap(); - assert!(!table.columns().contains(&"author")); - assert!(!table.columns().contains(&"extra_data")); - assert_eq!(7, table.columns().len()); - assert_eq!(["chain_id", "receipts_root"], table.columns()[5..7]); + assert!(table.columns().contains(&"topic1")); + assert!(!table.columns().contains(&"topic2")); + assert!(!table.columns().contains(&"topic3")); + assert!(table.columns().contains(&"data")); + assert_eq!(table.columns().len(), 12); + assert_eq!(["event__arg1", "event__arg2"], table.columns()[8..10]); } } diff --git a/crates/freeze/src/types/sources.rs b/crates/freeze/src/types/sources.rs index 04b5c69c..b5149968 100644 --- a/crates/freeze/src/types/sources.rs +++ b/crates/freeze/src/types/sources.rs @@ -5,25 +5,33 @@ use alloy::{ primitives::{Address, BlockNumber, Bytes, TxHash, B256, U256}, providers::{ ext::{DebugApi, TraceApi}, - Provider, ProviderBuilder, RootProvider, + DynProvider, Provider, ProviderBuilder, }, - rpc::types::{ - trace::{ - common::TraceResult, - geth::{ - AccountState, CallConfig, CallFrame, DefaultFrame, DiffMode, - GethDebugBuiltInTracerType, GethDebugTracerType, GethDebugTracingOptions, - GethTrace, PreStateConfig, PreStateFrame, - }, - parity::{ - LocalizedTransactionTrace, TraceResults, TraceResultsWithTransactionHash, TraceType, + rpc::{ + client::{ClientBuilder, RpcClient}, + types::{ + trace::{ + common::TraceResult, + geth::{ + AccountState, CallConfig, CallFrame, DefaultFrame, DiffMode, + GethDebugBuiltInTracerType, GethDebugTracerType, GethDebugTracingOptions, + GethTrace, PreStateConfig, PreStateFrame, + }, + parity::{ + LocalizedTransactionTrace, TraceResults, TraceResultsWithTransactionHash, + TraceType, + }, }, + Block, BlockTransactions, BlockTransactionsKind, Filter, Log, Transaction, + TransactionInput, TransactionReceipt, TransactionRequest, }, - Block, BlockTransactions, BlockTransactionsKind, Filter, Log, Transaction, - TransactionInput, TransactionReceipt, TransactionRequest, }, - transports::{http::reqwest::Url, BoxTransport, RpcError, TransportErrorKind}, + transports::{ + layers::RetryBackoffLayer, utils::guess_local_url, BoxTransport, IntoBoxTransport, + RpcError, TransportErrorKind, + }, }; +use alloy_transport_http::{AuthLayer, Http, HyperClient}; use governor::{ clock::DefaultClock, middleware::NoOpMiddleware, @@ -34,7 +42,7 @@ use tokio::{ task, }; -use crate::CollectError; +use crate::{CollectError, ParseError}; /// RateLimiter based on governor crate pub type RateLimiter = governor::RateLimiter; @@ -43,7 +51,7 @@ pub type RateLimiter = governor::RateLimiter, + pub provider: DynProvider, /// chain_id of network pub chain_id: u64, /// number of blocks per log request @@ -52,6 +60,8 @@ pub struct Source { pub max_concurrent_chunks: Option, /// Rpc Url pub rpc_url: String, + /// Optional JWT auth token for the RPC + pub jwt: Option, /// semaphore for controlling concurrency pub semaphore: Arc>, /// rate limiter for controlling request rate @@ -116,86 +126,252 @@ const DEFAULT_MAX_CONCURRENT_REQUESTS: u64 = 100; /// builder impl Source { /// initialize source - pub async fn init(rpc_url: Option) -> Result { - let rpc_url: String = parse_rpc_url(rpc_url); - let parsed_rpc_url: Url = rpc_url.parse().expect("rpc url is not valid"); - let provider = ProviderBuilder::new().on_http(parsed_rpc_url.clone()); - let chain_id = provider - .get_chain_id() - .await - .map_err(|_| CollectError::RPCError("could not get chain_id".to_string()))?; - - let rate_limiter = None; - let semaphore = None; - - let provider = ProviderBuilder::new().on_http(parsed_rpc_url); - - let source = Source { - provider: provider.boxed(), - chain_id, - inner_request_size: DEFAULT_INNER_REQUEST_SIZE, - max_concurrent_chunks: Some(DEFAULT_MAX_CONCURRENT_CHUNKS), - rpc_url, - labels: SourceLabels { - max_concurrent_requests: Some(DEFAULT_MAX_CONCURRENT_REQUESTS), - max_requests_per_second: Some(0), - max_retries: Some(DEFAULT_MAX_RETRIES), - initial_backoff: Some(DEFAULT_INTIAL_BACKOFF), - }, - rate_limiter: rate_limiter.into(), - semaphore: semaphore.into(), - }; + pub async fn new(rpc_url: String) -> Result { + SourceBuilder::new().rpc_url(rpc_url).build().await + } +} - Ok(source) +/// Normalizes a raw RPC endpoint string by ensuring it has a URI scheme +/// (http://) unless it already starts with http/https, ws/wss, or is an IPC path. +/// This is public so front-ends (CLI, Python bindings) can share identical +/// normalization logic. +pub(crate) fn normalize_rpc_url>(raw: S) -> String { + let raw = raw.as_ref(); + if raw.starts_with("http") || raw.starts_with("ws") || raw.ends_with(".ipc") { + raw.to_string() + } else { + format!("http://{}", raw) } +} - // /// set rate limit - // pub fn rate_limit(mut self, _requests_per_second: u64) -> Source { - // todo!(); - // } +/// Builder for `Source`. Keeps the `freeze` crate lightweight while allowing +/// richer construction logic (CLI, Python bindings, tests) to compose a +/// provider with concurrency & rate limiting concerns. +#[derive(Default, Debug)] +pub struct SourceBuilder { + rpc_url: Option, + provider: Option, + chain_id: Option, + inner_request_size: Option, + /// explicit None => unlimited + max_concurrent_chunks: Option, + semaphore: Option>>, + rate_limiter: Option>>, + jwt: Option, + labels: Option, + /// (max_retries, initial_backoff, compute_units_per_second) + retry: Option<(u32, u64, u64)>, } -fn parse_rpc_url(rpc_url: Option) -> String { - let mut url = match rpc_url { - Some(url) => url.clone(), - _ => match std::env::var("ETH_RPC_URL") { - Ok(url) => url, - Err(_e) => { - println!("must provide --rpc or set ETH_RPC_URL"); - std::process::exit(0); - } - }, +macro_rules! build_layered_client { + ($transport:expr, $($layer:ident $(? $([[$option:tt]])?)?),*) => { + build_layered_client!(@parse[] $transport, $([$(@option$($option)?)? $layer],)*) }; - if !url.starts_with("http") { - url = "http://".to_string() + url.as_str(); + (@parse[$($l:expr),*] $transport:expr, [@option $layer:ident], $($t:tt)*) => { + if let Some($layer) = $layer { + build_layered_client!(@parse[$($l,)* $layer] $transport, $($t)*) + } else { + build_layered_client!(@parse[$($l),*] $transport, $($t)*) + } + }; + (@parse[$($layer:expr),*] $transport:expr,) => { + build_layered_client!(@build $transport, $($layer,)*) + }; + (@build $transport:expr, $($layer:expr,)*) => {{ + let (transport, is_local) = $transport; + ClientBuilder::default() + $(.layer($layer))* + .transport(transport, is_local) + }}; +} + +impl SourceBuilder { + /// Create a fresh builder with no configuration. + pub fn new() -> Self { + Self { max_concurrent_chunks: Some(DEFAULT_MAX_CONCURRENT_CHUNKS), ..Self::default() } + } + + /// Provide an already constructed provider (overrides rpc_url if both set). + pub fn provider(mut self, provider: DynProvider) -> Self { + self.provider = Some(provider); + self + } + + /// Set the RPC url (used only if `provider` not supplied). + pub fn rpc_url(mut self, url: String) -> Self { + self.rpc_url = Some(normalize_rpc_url(url)); + self + } + + /// Override chain id instead of querying it from the remote node. + pub fn chain_id(mut self, chain_id: u64) -> Self { + self.chain_id = Some(chain_id); + self + } + + /// Set internal request batch size used for certain dataset fetch operations. + pub fn inner_request_size(mut self, size: u64) -> Self { + self.inner_request_size = Some(size); + self + } + + /// Limit number of dataset chunks processed concurrently (`None` => unlimited). + pub fn max_concurrent_chunks(mut self, m: Option) -> Self { + self.max_concurrent_chunks = m; + self + } + + /// Supply a custom semaphore controlling concurrent RPC requests. + pub fn semaphore(mut self, semaphore: Option) -> Self { + self.semaphore = Some(Arc::new(semaphore)); + self + } + + /// Supply a rate limiter gating outbound RPC calls. + pub fn rate_limiter(mut self, limiter: Option) -> Self { + self.rate_limiter = Some(Arc::new(limiter)); + self + } + + /// Attach an optional JWT token (currently stored for future use when auth headers become + /// available). + pub fn jwt(mut self, jwt: Option) -> Self { + self.jwt = jwt; + self + } + + /// Provide custom label metadata (non-functional; used for diagnostics / reporting). + pub fn labels(mut self, labels: SourceLabels) -> Self { + self.labels = Some(labels); + self + } + + /// Configure a retry policy layer to be attached to the underlying transport. + /// Parameters mirror `RetryBackoffLayer::new(max_retries, initial_backoff, + /// compute_units_per_second)`. + pub fn retry_policy( + mut self, + max_retries: u32, + initial_backoff: u64, + compute_units_per_second: u64, + ) -> Self { + self.retry = Some((max_retries, initial_backoff, compute_units_per_second)); + self + } + + fn build_http_transport(&self) -> Result<(BoxTransport, bool)> { + let rpc_url = self.rpc_url.as_deref().ok_or_else(|| { + CollectError::CollectError( + "SourceBuilder requires either provider or rpc_url".to_string(), + ) + })?; + let is_local = guess_local_url(rpc_url); + let rpc_url = + rpc_url.parse().map_err(|e| CollectError::ParseError(ParseError::ParseUrlError(e)))?; + + // Attach auth layer at the transport level if JWT provided + let http = if let Some(jwt) = self.jwt.as_deref() { + match jwt.parse() { + Ok(secret) => { + let layer = AuthLayer::new(secret); + // HyperClient::with_service(service) + build_http_jwt_client(layer, rpc_url) + } + Err(e) => { + return Err(CollectError::ParseError(ParseError::ParseJwtError(e.to_string()))); + } + } + } else { + Http::new(rpc_url).into_box_transport() + }; + + Ok((http, is_local)) + } + + fn build_client(&self) -> Result { + // Optional retry layer only (auth already applied at transport level) + let retry_layer = self.retry.map(|(max_r, initial_backoff, cu_ps)| { + RetryBackoffLayer::new(max_r, initial_backoff, cu_ps) + }); + let transport = self.build_http_transport()?; + let client = build_layered_client!(transport, retry_layer?); + Ok(client) + } + + /// Build the `Source`. This may perform network I/O to fetch `chain_id` + /// if it was not supplied. + pub async fn build(mut self) -> Result { + // Ensure we have a provider + if self.provider.is_none() { + let client = self.build_client()?; + let provider = ProviderBuilder::new().connect_client(client); + self.provider = Some(provider.erased()); + } + let provider = self.provider.expect("provider just ensured above"); + + // Resolve chain id if needed + if self.chain_id.is_none() { + let id = provider + .get_chain_id() + .await + .map_err(|_| CollectError::RPCError("could not get chain_id".to_string()))?; + self.chain_id = Some(id); + } + + // Defaults + let inner_request_size = self.inner_request_size.unwrap_or(DEFAULT_INNER_REQUEST_SIZE); + let labels = self.labels.unwrap_or(SourceLabels { + max_concurrent_requests: Some(DEFAULT_MAX_CONCURRENT_REQUESTS), + max_requests_per_second: Some(0), + max_retries: Some(DEFAULT_MAX_RETRIES), + initial_backoff: Some(DEFAULT_INTIAL_BACKOFF), + }); + + let semaphore = self.semaphore.unwrap_or_else(|| Arc::new(None)); + let rate_limiter = self.rate_limiter.unwrap_or_else(|| Arc::new(None)); + + Ok(Source { + provider, + chain_id: self.chain_id.expect("chain id ensured"), + inner_request_size, + max_concurrent_chunks: self.max_concurrent_chunks, + rpc_url: self.rpc_url.unwrap_or_else(|| "unknown".to_string()), + jwt: self.jwt, + semaphore, + rate_limiter, + labels, + }) + } +} + +/// Build a hyper-based transport that applies the provided `AuthLayer`. +/// We take ownership of the parsed URL so we can construct an `Http` transport +/// with the layered hyper client and return it as a `BoxTransport`. +pub fn build_http_jwt_client(layer: AuthLayer, url: url::Url) -> BoxTransport { + use alloy_transport_http::{ + hyper::body::Bytes, + hyper_util::{client::legacy::Client, rt::TokioExecutor}, }; - url + use http_body_util::Full; + + // Build a legacy hyper client (the underlying service) + let hyper_service = Client::builder(TokioExecutor::new()).build_http::>(); + + // Wrap the hyper service with the auth layer + let service = tower::ServiceBuilder::new().layer(layer).service(hyper_service); + + // Create an alloy HyperClient from the layered service and wrap it in an + // Http transport, then convert to a BoxTransport. + let hyper_client = HyperClient::with_service(service); + Http::with_client(hyper_client, url).into_box_transport() } -// builder - -// struct SourceBuilder { -// /// Shared provider for rpc data -// pub fetcher: Option>>>, -// /// chain_id of network -// pub chain_id: Option, -// /// number of blocks per log request -// pub inner_request_size: Option, -// /// Maximum chunks collected concurrently -// pub max_concurrent_chunks: Option, -// /// Rpc Url -// pub rpc_url: Option, -// /// Labels (these are non-functional) -// pub labels: Option, -// } - -// impl SourceBuilder { -// fn new(mut self) -> SourceBuilder { -// } - -// fn build(self) -> Source { -// } -// } +impl Source { + /// Start building a `Source` with `SourceBuilder`. + pub fn builder() -> SourceBuilder { + SourceBuilder::new() + } +} /// source labels (non-functional) #[derive(Clone, Debug, Default)] @@ -210,17 +386,6 @@ pub struct SourceLabels { pub initial_backoff: Option, } -/// Wrapper over `Provider

` that adds concurrency and rate limiting controls -#[derive(Debug)] -pub struct Fetcher

{ - /// provider data source - pub provider: RootProvider

, - /// semaphore for controlling concurrency - pub semaphore: Option, - /// rate limiter for controlling request rate - pub rate_limiter: Option, -} - type Result = ::core::result::Result; // impl Fetcher

{ @@ -238,9 +403,12 @@ impl Source { trace_types: Vec, ) -> Result> { let _permit = self.permit_request().await; - Self::map_err( - self.provider.trace_replay_block_transactions(block.into(), &trace_types).await, - ) + let trace_result = self + .provider + .trace_replay_block_transactions(block.into()) + .trace_types(trace_types) + .await; + Self::map_err(trace_result) } /// Get state diff traces of block @@ -298,7 +466,9 @@ impl Source { trace_types: Vec, ) -> Result { let _permit = self.permit_request().await; - Self::map_err(self.provider.trace_replay_transaction(tx_hash, &trace_types).await) + let trace_result = + self.provider.trace_replay_transaction(tx_hash).trace_types(trace_types).await; + Self::map_err(trace_result) } /// Get state diff traces of transaction @@ -348,7 +518,8 @@ impl Source { kind: BlockTransactionsKind, ) -> Result> { let _permit = self.permit_request().await; - Self::map_err(self.provider.get_block(block_num.into(), kind).await) + let block_result = self.provider.get_block(block_num.into()).kind(kind).await; + Self::map_err(block_result) } /// Gets the block with `block_hash` (transaction hashes only) @@ -358,7 +529,8 @@ impl Source { kind: BlockTransactionsKind, ) -> Result> { let _permit = self.permit_request().await; - Self::map_err(self.provider.get_block(block_hash.into(), kind).await) + let block_result = self.provider.get_block(block_hash.into()).kind(kind).await; + Self::map_err(block_result) } /// Returns all receipts for a block. @@ -398,7 +570,7 @@ impl Source { block_number: BlockNumber, ) -> Result { let _permit = self.permit_request().await; - Self::map_err(self.provider.call(&transaction).block(block_number.into()).await) + Self::map_err(self.provider.call(transaction).block(block_number.into()).await) } /// Returns traces for given call data @@ -411,10 +583,14 @@ impl Source { let _permit = self.permit_request().await; if let Some(bn) = block_number { return Self::map_err( - self.provider.trace_call(&transaction, &trace_type).block_id(bn.into()).await, + self.provider + .trace_call(&transaction) + .trace_types(trace_type.clone()) + .block_id(bn.into()) + .await, ); } - Self::map_err(self.provider.trace_call(&transaction, &trace_type).await) + Self::map_err(self.provider.trace_call(&transaction).trace_types(trace_type.clone()).await) } /// Get nonce of address @@ -495,7 +671,7 @@ impl Source { ..Default::default() }; let _permit = self.permit_request().await; - Self::map_err(self.provider.call(&transaction).block(block_number.into()).await) + Self::map_err(self.provider.call(transaction).block(block_number.into()).await) } /// Return output data of a contract call @@ -512,15 +688,18 @@ impl Source { ..Default::default() }; let _permit = self.permit_request().await; - if block_number.is_some() { + if let Some(bn) = block_number { Self::map_err( self.provider - .trace_call(&transaction, &trace_type) - .block_id(block_number.unwrap().into()) + .trace_call(&transaction) + .trace_types(trace_type.clone()) + .block_id(bn.into()) .await, ) } else { - Self::map_err(self.provider.trace_call(&transaction, &trace_type).await) + Self::map_err( + self.provider.trace_call(&transaction).trace_types(trace_type.clone()).await, + ) } } @@ -584,15 +763,13 @@ impl Source { GethTrace::JS(value) => calls.push(value), _ => { return Err(CollectError::CollectError(format!( - "invalid trace result in tx {:?}", - tx_hash + "invalid trace result in tx {tx_hash:?}" ))) } }, TraceResult::Error { error, tx_hash } => { return Err(CollectError::CollectError(format!( - "invalid trace result in tx {:?}: {}", - tx_hash, error + "invalid trace result in tx {tx_hash:?}: {error}" ))) } } @@ -617,15 +794,13 @@ impl Source { GethTrace::Default(frame) => calls.push(frame), _ => { return Err(CollectError::CollectError(format!( - "invalid trace result in tx {:?}", - tx_hash + "invalid trace result in tx {tx_hash:?}" ))) } }, TraceResult::Error { error, tx_hash } => { return Err(CollectError::CollectError(format!( - "inalid trace result in tx {:?}: {}", - tx_hash, error + "inalid trace result in tx {tx_hash:?}: {error}" ))); } } @@ -657,15 +832,13 @@ impl Source { GethTrace::NoopTracer(_) => {} _ => { return Err(CollectError::CollectError(format!( - "invalid trace result in tx {:?}", - tx_hash + "invalid trace result in tx {tx_hash:?}" ))) } }, TraceResult::Error { error, tx_hash } => { return Err(CollectError::CollectError(format!( - "invalid trace result in tx {:?}: {}", - tx_hash, error + "invalid trace result in tx {tx_hash:?}: {error}" ))); } } @@ -695,15 +868,13 @@ impl Source { GethTrace::PreStateTracer(PreStateFrame::Default(frame)) => calls.push(frame.0), _ => { return Err(CollectError::CollectError(format!( - "invalid trace result in tx {:?}", - tx_hash + "invalid trace result in tx {tx_hash:?}" ))) } }, TraceResult::Error { error, tx_hash } => { return Err(CollectError::CollectError(format!( - "invalid trace result in tx {:?}: {}", - tx_hash, error + "invalid trace result in tx {tx_hash:?}: {error}" ))); } } @@ -738,15 +909,13 @@ impl Source { GethTrace::CallTracer(frame) => calls.push(frame), _ => { return Err(CollectError::CollectError(format!( - "invalid trace result in tx {:?}", - tx_hash + "invalid trace result in tx {tx_hash:?}" ))) } }, TraceResult::Error { error, tx_hash } => { return Err(CollectError::CollectError(format!( - "invalid trace result in tx {:?}: {}", - tx_hash, error + "invalid trace result in tx {tx_hash:?}: {error}" ))); } } @@ -784,17 +953,15 @@ impl Source { diffs.push(diff); } _ => { - println!("{:?}", result); + println!("{result:?}"); return Err(CollectError::CollectError(format!( - "invalid trace result in tx {:?}", - tx_hash + "invalid trace result in tx {tx_hash:?}" ))); } }, TraceResult::Error { error, tx_hash } => { return Err(CollectError::CollectError(format!( - "invalid trace result in tx {:?}: {}", - tx_hash, error + "invalid trace result in tx {tx_hash:?}: {error}" ))); } } @@ -1012,3 +1179,62 @@ fn parse_geth_diff_object(map: serde_json::Map) -> Re Ok(DiffMode { pre, post }) } + +#[cfg(test)] +mod tests { + use super::*; + + // These tests assume an ETH_RPC_URL pointing to a dev node or that the URL is unreachable. + // For CI determinism, consider mocking provider once alloy offers an in-memory transport. + + #[tokio::test] + async fn builder_defaults_from_url() { + // Use an obviously invalid URL but with correct shape; build should fail only when chain_id + // fetch fails. If environment has ETH_RPC_URL set and reachable, this will exercise + // more. + let url = "http://localhost:8545".to_string(); + let build = Source::builder().rpc_url(url).build().await; + // We can't guarantee local node is up in test environment, so just assert we get some + // result (Ok or Err is acceptable). If Ok, validate some defaults. + if let Ok(source) = build { + assert_eq!(source.inner_request_size, 100, "default inner_request_size"); + assert_eq!(source.max_concurrent_chunks, Some(4)); + assert!(source.labels.max_retries.is_some()); + } + } + + #[tokio::test] + async fn builder_overrides() { + // This test will likely fail without a running node because chain_id fetch is required. + // Skip if no local node. + let url = "http://localhost:8545"; + let result = Source::builder() + .rpc_url(url.to_string()) + .inner_request_size(42) + .max_concurrent_chunks(Some(7)) + .labels(SourceLabels { + max_concurrent_requests: Some(10), + max_requests_per_second: Some(5), + max_retries: Some(3), + initial_backoff: Some(1), + }) + .build() + .await; + if let Ok(source) = result { + // if a node is available + assert_eq!(source.inner_request_size, 42); + assert_eq!(source.max_concurrent_chunks, Some(7)); + assert_eq!(source.labels.max_retries, Some(3)); + } + } + + #[tokio::test] + async fn builder_with_retry_policy() { + let url = "http://localhost:8545"; + let result = Source::builder().rpc_url(url.to_string()).retry_policy(2, 1, 0).build().await; + // Success depends on local node; if Ok, we at least exercised retry path. + if let Ok(source) = result { + assert_eq!(source.rpc_url, url); + } + } +} diff --git a/crates/freeze/src/types/summaries.rs b/crates/freeze/src/types/summaries.rs index f760c1d2..9ad292f5 100644 --- a/crates/freeze/src/types/summaries.rs +++ b/crates/freeze/src/types/summaries.rs @@ -5,8 +5,8 @@ use colored::Colorize; use thousands::Separable; use crate::{ - chunks::chunk_ops::ValueToString, ChunkData, ChunkStats, CollectError, ColumnType, Datatype, - Dim, ExecutionEnv, FileOutput, MetaDatatype, MultiDatatype, Partition, Query, Source, Table, + chunks::chunk_ops::ValueToString, ChunkData, ChunkStats, CollectError, Datatype, Dim, + ExecutionEnv, FileOutput, MetaDatatype, MultiDatatype, Partition, Query, Source, Table, }; use std::path::PathBuf; @@ -52,7 +52,7 @@ pub fn print_all_datasets() { println!(); print_header("dataset group names"); for datatype in MultiDatatype::variants().iter() { - let name = heck::AsSnakeCase(format!("{:?}", datatype)).to_string(); + let name = heck::AsSnakeCase(format!("{datatype:?}")).to_string(); let subtypes = datatype.datatypes().iter().map(|dt| dt.name()).collect::>().join(", "); print_bullet(name, subtypes) @@ -74,7 +74,7 @@ pub fn print_dataset_info(datatype: Datatype, schema: &Table) { let required_parameters = datatype .required_parameters() .iter() - .map(|x| format!("{}", x)) + .map(|x| format!("{x}")) .collect::>() .join(", "); let required_parameters = @@ -84,7 +84,7 @@ pub fn print_dataset_info(datatype: Datatype, schema: &Table) { let optional_parameters = datatype .optional_parameters() .iter() - .map(|x| format!("{}", x)) + .map(|x| format!("{x}")) .collect::>() .join(", "); let optional_parameters = @@ -113,21 +113,21 @@ pub fn print_dataset_info(datatype: Datatype, schema: &Table) { pub(crate) fn print_header>(header: A) { let header_str = header.as_ref().white().bold(); let underline = "─".repeat(header_str.len()).truecolor(TITLE_R, TITLE_G, TITLE_B); - println!("{}", header_str); - println!("{}", underline); + println!("{header_str}"); + println!("{underline}"); } pub(crate) fn print_header_error>(header: A) { let header_str = header.as_ref().white().bold(); let underline = "─".repeat(header_str.len()).truecolor(ERROR_R, ERROR_G, ERROR_B); - println!("{}", header_str); - println!("{}", underline); + println!("{header_str}"); + println!("{underline}"); } fn print_bullet_key>(key: A) { let bullet_str = "- ".truecolor(TITLE_R, TITLE_G, TITLE_B); let key_str = key.as_ref().white().bold(); - println!("{}{}", bullet_str, key_str); + println!("{bullet_str}{key_str}"); } fn print_bullet, B: AsRef>(key: A, value: B) { @@ -135,14 +135,14 @@ fn print_bullet, B: AsRef>(key: A, value: B) { let key_str = key.as_ref().white().bold(); let value_str = value.as_ref().truecolor(170, 170, 170); let colon_str = ": ".truecolor(TITLE_R, TITLE_G, TITLE_B); - println!("{}{}{}{}", bullet_str, key_str, colon_str, value_str); + println!("{bullet_str}{key_str}{colon_str}{value_str}"); } fn print_bullet_parenthetical, B: AsRef>(key: A, value: B) { let bullet_str = "- ".truecolor(TITLE_R, TITLE_G, TITLE_B); let key_str = key.as_ref().white().bold(); let value_str = value.as_ref().truecolor(170, 170, 170); - println!("{}{} ({})", bullet_str, key_str, value_str); + println!("{bullet_str}{key_str} ({value_str})"); } fn print_bullet_indent, B: AsRef>(key: A, value: B, indent: usize) { @@ -318,7 +318,7 @@ fn print_chunk( ) { if dim_stats.total_values == 1 { print_bullet_indent( - format!("{}", dim), + format!("{dim}"), dim_stats.min_value_to_string().unwrap_or("none".to_string()), 4, ); @@ -333,13 +333,13 @@ fn print_chunk( ); match align { - Some(true) => text = format!("{} align=yes", text), - Some(false) => text = format!("{} align=no", text), + Some(true) => text = format!("{text} align=yes"), + Some(false) => text = format!("{text} align=no"), None => {} } if let Some(reorg_buffer) = reorg_buffer { - text = format!("{} reorg_buffer={}", text, reorg_buffer); + text = format!("{text} reorg_buffer={reorg_buffer}"); }; print_bullet_indent(dim.plural_name(), text, 4) } @@ -372,11 +372,11 @@ fn print_schema(name: &Datatype, schema: &Table) { print_header("schema for ".to_string() + name.name().as_str()); for column in schema.columns() { if let Some(column_type) = schema.column_type(column) { - if column_type == ColumnType::UInt256 { - for uint256_type in schema.u256_types.iter() { + if column_type.is_256() { + for uint256_type in schema.config.u256_types.iter() { print_bullet( - column.to_owned() + uint256_type.suffix().as_str(), - uint256_type.to_columntype().as_str(), + column.to_owned() + uint256_type.suffix(column_type).as_str(), + uint256_type.to_columntype(schema.config.binary_type).as_str(), ); } } else { @@ -394,7 +394,7 @@ fn print_schema(name: &Datatype, schema: &Table) { name.column_types().keys().copied().filter(|x| !schema.has_column(x)).collect::>(); let other_columns = if other_columns.is_empty() { "[none]".to_string() } else { other_columns.join(", ") }; - println!("\nother available columns: {}", other_columns); + println!("\nother available columns: {other_columns}"); } pub(crate) fn print_cryo_conclusion( @@ -430,7 +430,7 @@ pub(crate) fn print_cryo_conclusion( *error_counts.entry(error.to_string()).or_insert(0) += 1; } for (error, count) in error_counts.iter().take(10) { - println!("- {} ({}x)", error, count); + println!("- {error} ({count}x)"); } if error_counts.len() > 10 { println!("...") @@ -449,7 +449,7 @@ pub(crate) fn print_cryo_conclusion( let seconds = duration.as_secs(); let millis = duration.subsec_millis(); let total_time = (seconds as f64) + (duration.subsec_nanos() as f64) / 1e9; - let duration_string = format!("{}.{:03} seconds", seconds, millis); + let duration_string = format!("{seconds}.{millis:03} seconds"); print_header("collection summary"); print_bullet("total duration", duration_string); @@ -579,8 +579,7 @@ fn format_float(number: f64) -> String { return format!("{}.0", int_part.separate_with_commas()) } - let frac_str = - format!("{:0>width$}", frac_part, width = decimal_places).trim_end_matches('0').to_string(); + let frac_str = format!("{frac_part:0>decimal_places$}").trim_end_matches('0').to_string(); format!("{}.{}", int_part.separate_with_commas(), frac_str) } diff --git a/crates/freeze/tests/from_dataframes.rs b/crates/freeze/tests/from_dataframes.rs new file mode 100644 index 00000000..6a2856c1 --- /dev/null +++ b/crates/freeze/tests/from_dataframes.rs @@ -0,0 +1,338 @@ +use alloy::primitives::{I256, U256}; +use cryo_freeze::*; +use cryo_to_df::FromDataFrames; +use polars::prelude::*; +use std::collections::HashMap; + +#[derive(Default, FromDataFrames, Debug)] +pub struct Blocks { + pub n_rows: u64, + pub field1: Vec, + pub field2: Vec, + pub chain_id: Vec, +} + +#[derive(Default, FromDataFrames, Debug)] +pub struct Balances { + pub n_rows: u64, + pub value_u256: Vec, + pub value_i256: Vec, + pub optional_u256: Vec>, + pub optional_i256: Vec>, + pub chain_id: Vec, +} + +#[derive(Default, FromDataFrames, Debug)] +pub struct BalanceReads { + pub n_rows: u64, + pub fallback_u256: Vec, + pub fallback_i256: Vec, + pub chain_id: Vec, +} + +#[test] +fn test_from_dataframes_derive() { + test_from_dataframes().unwrap(); +} + +#[test] +fn test_u256_i256_binary_columns() { + test_u256_i256_from_dataframes().unwrap(); +} + +#[test] +fn test_binary_column_fallback() { + test_binary_fallback().unwrap(); +} + +#[test] +fn test_option_vec_error_handling() { + test_option_vec_errors().unwrap(); +} + +#[test] +fn test_from_binary_vec_trait() { + test_from_binary_vec().unwrap(); +} + +fn get_config() -> TableConfig { + TableConfig { + u256_types: vec![U256Type::Binary, U256Type::String, U256Type::F64], + binary_type: ColumnEncoding::Hex, + hex_prefix: true, + } +} + +#[allow(dead_code)] +pub fn test_from_dataframes() -> Result<(), Box> { + println!("Testing FromDataFrames derive macro..."); + + // Create test data + let field1_data = vec![1u32, 2, 3]; + let field2_data = vec!["a".to_string(), "b".to_string(), "c".to_string()]; + let chain_id_data = vec![1u64, 1, 1]; + + // Create DataFrame + let df = DataFrame::new(vec![ + Column::new("field1".into(), field1_data.clone()), + Column::new("field2".into(), field2_data.clone()), + Column::new("chain_id".into(), chain_id_data.clone()), + ])?; + + // Create input for parse_dfs (using an existing datatype) + let mut dfs = HashMap::new(); + let mut schemas = HashMap::new(); + dfs.insert(Datatype::Blocks, df); + schemas.insert(Datatype::Blocks, Datatype::Blocks.default_table_schema(get_config())); + + let mut result = Blocks::default(); + // Call parse_dfs + result.parse_dfs(dfs, &schemas)?; + + println!("Result n_rows: {}", result.n_rows); + println!("Result field1: {:?}", result.field1); + println!("Result field2: {:?}", result.field2); + println!("Result chain_id: {:?}", result.chain_id); + + assert_eq!(result.n_rows, 3); + assert_eq!(result.field1, field1_data); + assert_eq!(result.field2, field2_data); + assert_eq!(result.chain_id, chain_id_data); + + println!("FromDataFrames derive macro works correctly!"); + Ok(()) +} + +#[allow(dead_code)] +pub fn test_u256_i256_from_dataframes() -> Result<(), Box> { + println!("Testing U256/I256 FromDataFrames with binary columns..."); + + // Create test U256/I256 values + let u256_val = U256::from(12345u64); + let i256_val = I256::from_raw(U256::from(67890u64)); + let i256_negative = I256::try_from(-12345i64).unwrap(); + + // Convert to binary data (32 bytes each) + let u256_binary = u256_val.to_be_bytes_vec(); + let i256_binary = i256_val.to_be_bytes::<32>().to_vec(); + let i256_negative_binary = i256_negative.to_be_bytes::<32>().to_vec(); + + println!("U256 binary length: {}", u256_binary.len()); + println!("I256 binary length: {}", i256_binary.len()); + println!("I256 negative binary length: {}", i256_negative_binary.len()); + + let chain_id_data = vec![1u64, 1]; + + // Create DataFrame with binary columns using the naming convention + let df = DataFrame::new(vec![ + Column::new("value_u256_u256binary".into(), vec![u256_binary.clone(), u256_binary.clone()]), + Column::new("value_i256_i256binary".into(), vec![i256_binary.clone(), i256_binary.clone()]), + Column::new("optional_u256_u256binary".into(), vec![Some(u256_binary.clone()), None]), + Column::new("optional_i256_i256binary".into(), vec![Some(i256_binary.clone()), None]), + Column::new("chain_id".into(), chain_id_data.clone()), + ])?; + + // Create input for parse_dfs + let mut dfs = HashMap::new(); + let mut schemas = HashMap::new(); + dfs.insert(Datatype::Balances, df); + schemas.insert(Datatype::Balances, Datatype::Balances.default_table_schema(get_config())); + + // Call parse_dfs + let mut result = Balances::default(); + result.parse_dfs(dfs, &schemas)?; + + println!("Result n_rows: {}", result.n_rows); + println!("Result value_u256: {:?}", result.value_u256); + println!("Result value_i256: {:?}", result.value_i256); + println!("Result optional_u256: {:?}", result.optional_u256); + println!("Result optional_i256: {:?}", result.optional_i256); + + assert_eq!(result.n_rows, 2); + assert_eq!(result.value_u256, vec![u256_val, u256_val]); + assert_eq!(result.value_i256, vec![i256_val, i256_val]); + assert_eq!(result.optional_u256, vec![Some(u256_val), None]); + assert_eq!(result.optional_i256, vec![Some(i256_val), None]); + assert_eq!(result.chain_id, chain_id_data); + + println!("U256/I256 FromDataFrames works correctly!"); + Ok(()) +} + +#[allow(dead_code)] +pub fn test_negative_i256_from_dataframes() -> Result<(), Box> { + println!("Testing negative I256 FromDataFrames with binary columns..."); + + // Create test I256 values including negative + let i256_positive = I256::try_from(12345i64).unwrap(); + let i256_negative = I256::try_from(-67890i64).unwrap(); + + // Convert to binary data (32 bytes each) + let i256_positive_binary = i256_positive.to_be_bytes::<32>().to_vec(); + let i256_negative_binary = i256_negative.to_be_bytes::<32>().to_vec(); + + println!("I256 positive binary length: {}", i256_positive_binary.len()); + println!("I256 negative binary length: {}", i256_negative_binary.len()); + + let chain_id_data = vec![1u64, 2]; + + // Create DataFrame with binary columns + let df = DataFrame::new(vec![ + Column::new( + "value_i256_i256binary".into(), + vec![i256_positive_binary.clone(), i256_negative_binary.clone()], + ), + Column::new("chain_id".into(), chain_id_data.clone()), + ])?; + + // Create input for parse_dfs + let mut dfs = HashMap::new(); + let mut schemas = HashMap::new(); + dfs.insert(Datatype::BalanceDiffs, df); + schemas + .insert(Datatype::BalanceDiffs, Datatype::BalanceDiffs.default_table_schema(get_config())); + + // Test the conversion + let mut result = BalanceDiffs::default(); + result.parse_dfs(dfs, &schemas)?; + + // Verify the values + assert_eq!(result.value_i256.len(), 2); + assert_eq!(result.value_i256[0], i256_positive); + assert_eq!(result.value_i256[1], i256_negative); + assert_eq!(result.chain_id, chain_id_data); + + println!("Negative I256 FromDataFrames works correctly!"); + Ok(()) +} + +#[derive(Default, FromDataFrames)] +struct BalanceDiffs { + pub n_rows: u64, + value_i256: Vec, + chain_id: Vec, +} + +#[allow(dead_code)] +pub fn test_binary_fallback() -> Result<(), Box> { + println!("Testing binary column name fallback behavior..."); + + // Create test U256/I256 values + let u256_val = U256::from(99999u64); + let i256_val = I256::from_raw(U256::from(88888u64)); + + // Convert to binary data (32 bytes each) + let u256_binary = u256_val.to_be_bytes_vec(); + let i256_binary = i256_val.to_be_bytes::<32>().to_vec(); + + println!("Testing fallback to _binary columns..."); + + let chain_id_data = vec![1u64]; + + // Create DataFrame with ONLY _binary columns (no _u256binary or _i256binary) + // This should test the fallback behavior + let df = DataFrame::new(vec![ + Column::new("fallback_u256_binary".into(), vec![u256_binary.clone()]), + Column::new("fallback_i256_binary".into(), vec![i256_binary.clone()]), + Column::new("chain_id".into(), chain_id_data.clone()), + ])?; + + // Create input for parse_dfs + let mut dfs = HashMap::new(); + let mut schemas = HashMap::new(); + dfs.insert(Datatype::BalanceReads, df); + schemas + .insert(Datatype::BalanceReads, Datatype::BalanceReads.default_table_schema(get_config())); + + // Call parse_dfs - this should successfully use the _binary fallback columns + let mut result = BalanceReads::default(); + result.parse_dfs(dfs, &schemas)?; + + println!("Result n_rows: {}", result.n_rows); + println!("Result fallback_u256: {:?}", result.fallback_u256); + println!("Result fallback_i256: {:?}", result.fallback_i256); + + assert_eq!(result.n_rows, 1); + assert_eq!(result.fallback_u256, vec![u256_val]); + assert_eq!(result.fallback_i256, vec![i256_val]); + assert_eq!(result.chain_id, chain_id_data); + + println!("Binary column fallback works correctly!"); + Ok(()) +} + +#[allow(dead_code)] +pub fn test_option_vec_errors() -> Result<(), Box> { + println!("Testing OptionVec error handling..."); + + // Test that OptionVec with None values fails when converting to Vec + use cryo_freeze::OptionVec; + + // Create an OptionVec with Some values - should succeed + let option_vec_some = OptionVec::Some(vec![1u32, 2, 3]); + let result: Result, _> = option_vec_some.try_into(); + assert!(result.is_ok()); + assert_eq!(result.unwrap(), vec![1u32, 2, 3]); + + // Create an OptionVec with None values - should fail when converting to Vec + let option_vec_with_none = OptionVec::Option(vec![Some(1u32), None, Some(3)]); + let result: Result, _> = option_vec_with_none.try_into(); + assert!(result.is_err()); + + // But should succeed when converting to Vec> + let option_vec_with_none = OptionVec::Option(vec![Some(1u32), None, Some(3)]); + let result: Result>, _> = option_vec_with_none.try_into(); + assert!(result.is_ok()); + assert_eq!(result.unwrap(), vec![Some(1u32), None, Some(3)]); + + println!("OptionVec error handling works correctly!"); + Ok(()) +} + +#[allow(dead_code)] +pub fn test_from_binary_vec() -> Result<(), Box> { + println!("Testing FromBinaryVec trait..."); + + use cryo_freeze::FromBinaryVec; + + // Create test U256 binary data + let u256_val = U256::from(12345u64); + let u256_binary = u256_val.to_be_bytes_vec(); + + // Test Vec - should succeed when all values are present + let data_complete = vec![Some(u256_binary.clone()), Some(u256_binary.clone())]; + let result: Result, _> = Vec::from_binary_vec(data_complete); + assert!(result.is_ok()); + let values = result.unwrap(); + assert_eq!(values.len(), 2); + assert_eq!(values[0], u256_val); + assert_eq!(values[1], u256_val); + + // Test Vec - should fail when there's a None value + let data_with_none = vec![Some(u256_binary.clone()), None]; + let result: Result, _> = Vec::from_binary_vec(data_with_none); + assert!(result.is_err()); + + // Test Vec> - should succeed even with None values + let data_with_none = vec![Some(u256_binary.clone()), None, Some(u256_binary.clone())]; + let result: Result>, _> = Vec::from_binary_vec(data_with_none); + assert!(result.is_ok()); + let values = result.unwrap(); + assert_eq!(values.len(), 3); + assert_eq!(values[0], Some(u256_val)); + assert_eq!(values[1], None); + assert_eq!(values[2], Some(u256_val)); + + // Test I256 as well + let i256_val = I256::from_raw(U256::from(67890u64)); + let i256_binary = i256_val.to_be_bytes::<32>().to_vec(); + + let data_i256 = vec![Some(i256_binary.clone())]; + let result: Result, _> = Vec::from_binary_vec(data_i256); + assert!(result.is_ok()); + let values = result.unwrap(); + assert_eq!(values[0], i256_val); + + println!("FromBinaryVec trait works correctly!"); + Ok(()) +} diff --git a/crates/python/Cargo.toml b/crates/python/Cargo.toml index 6b968d71..d7558cdb 100644 --- a/crates/python/Cargo.toml +++ b/crates/python/Cargo.toml @@ -18,10 +18,14 @@ crate-type = ["cdylib"] cryo_cli = { workspace = true } cryo_freeze = { workspace = true } polars = { workspace = true } +polars-python = { workspace = true } pyo3 = { workspace = true } -pyo3-asyncio = { workspace = true } +pyo3-async-runtimes = { workspace = true } pyo3-polars = { workspace = true } tokio = { workspace = true } [build-dependencies] pyo3-build-config = { workspace = true } + +[features] +extension-module = ["pyo3/extension-module"] diff --git a/crates/python/rust/collect_adapter.rs b/crates/python/rust/collect_adapter.rs index d17fa26b..6d959e0e 100644 --- a/crates/python/rust/collect_adapter.rs +++ b/crates/python/rust/collect_adapter.rs @@ -1,6 +1,6 @@ use polars::prelude::*; +use polars_python::PyDataFrame; use pyo3::{exceptions::PyTypeError, prelude::*}; -use pyo3_polars::PyDataFrame; use cryo_cli::{parse_args, Args}; use cryo_freeze::collect; @@ -21,9 +21,11 @@ use cryo_freeze::collect; columns = None, u256_types = None, hex = false, + hex_prefix = true, sort = None, exclude_failed = false, rpc = None, + jwt = None, network_name = None, requests_per_second = None, max_concurrent_requests = None, @@ -83,9 +85,11 @@ pub fn _collect( columns: Option>, u256_types: Option>, hex: bool, + hex_prefix: bool, sort: Option>, exclude_failed: bool, rpc: Option, + jwt: Option, network_name: Option, requests_per_second: Option, max_concurrent_requests: Option, @@ -127,11 +131,11 @@ pub fn _collect( verbose: bool, no_verbose: bool, event_signature: Option, -) -> PyResult<&PyAny> { +) -> PyResult> { if let Some(command) = command { - pyo3_asyncio::tokio::future_into_py(py, async move { + pyo3_async_runtimes::tokio::future_into_py(py, async move { match run_execute(command).await { - Ok(df) => Ok(PyDataFrame(df)), + Ok(df) => Ok(PyDataFrame { df: df.into() }), Err(_e) => Err(PyErr::new::("failed")), } }) @@ -149,9 +153,11 @@ pub fn _collect( columns, u256_types, hex, + no_hex_prefix: !hex_prefix, sort, exclude_failed, rpc, + jwt, network_name, requests_per_second, max_concurrent_requests, @@ -194,33 +200,33 @@ pub fn _collect( no_verbose, event_signature, }; - pyo3_asyncio::tokio::future_into_py(py, async move { + pyo3_async_runtimes::tokio::future_into_py(py, async move { match run_collect(args).await { // Ok(df) => Ok(Python::with_gil(|py| py.None())), - Ok(df) => Ok(PyDataFrame(df)), + Ok(df) => Ok(PyDataFrame { df: df.into() }), Err(_e) => Err(PyErr::new::("failed")), } }) } else { - return Err(PyErr::new::("must specify datatype or command")) + Err(PyErr::new::("must specify datatype or command")) } } async fn run_collect(args: Args) -> PolarsResult { let (query, source, _sink, _env) = match parse_args(&args).await { Ok(opts) => opts, - Err(e) => panic!("error parsing opts {:?}", e), + Err(e) => panic!("error parsing opts {e:?}"), }; match collect(query.into(), source.into()).await { Ok(df) => Ok(df), - Err(e) => panic!("error collecting {:?}", e), + Err(e) => panic!("error collecting {e:?}"), } } async fn run_execute(command: String) -> PolarsResult { let args = match cryo_cli::parse_str(command.as_str()).await { Ok(opts) => opts, - Err(e) => panic!("error parsing opts {:?}", e), + Err(e) => panic!("error parsing opts {e:?}"), }; run_collect(args).await } diff --git a/crates/python/rust/freeze_adapter.rs b/crates/python/rust/freeze_adapter.rs index f40317a2..2d2eeb9e 100644 --- a/crates/python/rust/freeze_adapter.rs +++ b/crates/python/rust/freeze_adapter.rs @@ -18,9 +18,11 @@ use cryo_cli::{run, Args}; columns = None, u256_types = None, hex = false, + hex_prefix = true, sort = None, exclude_failed = false, rpc = None, + jwt = None, network_name = None, requests_per_second = None, max_concurrent_requests = None, @@ -80,9 +82,11 @@ pub fn _freeze( columns: Option>, u256_types: Option>, hex: bool, + hex_prefix: bool, sort: Option>, exclude_failed: bool, rpc: Option, + jwt: Option, network_name: Option, requests_per_second: Option, max_concurrent_requests: Option, @@ -124,7 +128,7 @@ pub fn _freeze( verbose: bool, no_verbose: bool, event_signature: Option, -) -> PyResult<&PyAny> { +) -> PyResult> { if let Some(command) = command { freeze_command(py, command) } else if let Some(datatype) = datatype { @@ -141,9 +145,11 @@ pub fn _freeze( columns, u256_types, hex, + no_hex_prefix: !hex_prefix, sort, exclude_failed, rpc, + jwt, network_name, requests_per_second, max_concurrent_requests, @@ -187,7 +193,7 @@ pub fn _freeze( event_signature, }; - pyo3_asyncio::tokio::future_into_py(py, async move { + pyo3_async_runtimes::tokio::future_into_py(py, async move { match run(args).await { Ok(Some(result)) => Python::with_gil(|py| { // let paths = PyDict::new(py); @@ -199,25 +205,25 @@ pub fn _freeze( // let paths = paths.to_object(py); let dict = [ - ("n_completed".to_string(), result.completed.len().into_py(py)), - ("n_skipped".to_string(), result.skipped.len().into_py(py)), - ("n_errored".to_string(), result.errored.len().into_py(py)), + ("n_completed".to_string(), result.completed.len()), + ("n_skipped".to_string(), result.skipped.len()), + ("n_errored".to_string(), result.errored.len()), // ("paths".to_string(), paths), ] - .into_py_dict(py); - Ok(dict.to_object(py)) + .into_py_dict(py)?; + Ok(dict.unbind().into_any()) }), Ok(None) => Ok(Python::with_gil(|py| py.None())), _ => Err(PyErr::new::("failed")), } }) } else { - return Err(PyErr::new::("must specify datatypes or command")) + Err(PyErr::new::("must specify datatypes or command")) } } -fn freeze_command(py: Python<'_>, command: String) -> PyResult<&PyAny> { - pyo3_asyncio::tokio::future_into_py(py, async move { +fn freeze_command(py: Python<'_>, command: String) -> PyResult> { + pyo3_async_runtimes::tokio::future_into_py(py, async move { let args = cryo_cli::parse_str(command.as_str()).await.expect("could not parse inputs"); match run(args).await { Ok(Some(result)) => Python::with_gil(|py| { @@ -230,13 +236,13 @@ fn freeze_command(py: Python<'_>, command: String) -> PyResult<&PyAny> { // let paths = paths.to_object(py); let dict = [ - ("n_completed".to_string(), result.completed.len().into_py(py)), - ("n_skipped".to_string(), result.skipped.len().into_py(py)), - ("n_errored".to_string(), result.errored.len().into_py(py)), + ("n_completed".to_string(), result.completed.len()), + ("n_skipped".to_string(), result.skipped.len()), + ("n_errored".to_string(), result.errored.len()), // ("paths".to_string(), paths), ] - .into_py_dict(py); - Ok(dict.to_object(py)) + .into_py_dict(py)?; + Ok(dict.unbind().into_any()) }), Ok(None) => Ok(Python::with_gil(|py| py.None())), _ => Err(PyErr::new::("failed")), diff --git a/crates/python/rust/lib.rs b/crates/python/rust/lib.rs index 6eea1dc6..08eeae56 100644 --- a/crates/python/rust/lib.rs +++ b/crates/python/rust/lib.rs @@ -13,7 +13,7 @@ fn sum_as_string(a: usize, b: usize) -> PyResult { /// A Python module implemented in Rust. #[pymodule] #[pyo3(name = "_cryo_rust")] -fn cryo_rust(_py: Python, m: &PyModule) -> PyResult<()> { +fn cryo_rust(_py: Python, m: &Bound) -> PyResult<()> { m.add_function(wrap_pyfunction!(sum_as_string, m)?)?; m.add_function(wrap_pyfunction!(freeze_adapter::_freeze, m)?)?; m.add_function(wrap_pyfunction!(collect_adapter::_collect, m)?)?; diff --git a/crates/to_df/Cargo.toml b/crates/to_df/Cargo.toml index 19058dc1..1565dff0 100644 --- a/crates/to_df/Cargo.toml +++ b/crates/to_df/Cargo.toml @@ -14,6 +14,6 @@ proc-macro = true [dependencies] indexmap = { workspace = true } -syn = { version = "1.0", features = ["full"] } +syn = { version = "2.0", features = ["full"] } quote = "1.0" proc-macro2 = "1.0" diff --git a/crates/to_df/src/lib.rs b/crates/to_df/src/lib.rs index 6ab93323..e12ab35e 100644 --- a/crates/to_df/src/lib.rs +++ b/crates/to_df/src/lib.rs @@ -3,173 +3,137 @@ extern crate proc_macro; use proc_macro::TokenStream; use proc_macro2::Span; use quote::quote; -use syn::{parse_macro_input, ItemStruct}; +use syn::{parse_macro_input, parse_str, ItemStruct}; -/// implements ToDataFrames and ColumnData for struct -#[proc_macro_attribute] -pub fn to_df(attrs: TokenStream, input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as ItemStruct); +struct ToDataFramesMetaParams { + flatten: Option, +} - // parse input args - let attrs = parse_macro_input!(attrs as syn::AttributeArgs); - let datatypes: Vec<_> = attrs - .into_iter() - .map(|arg| { - if let syn::NestedMeta::Meta(syn::Meta::Path(path)) = arg { - path - } else { - panic!("Expected Meta::Path"); - } - }) - .collect(); - if datatypes.is_empty() { - panic!("At least one datatype must be specified"); +impl ToDataFramesMetaParams { + fn parse_attributes(attrs: &[syn::Attribute]) -> syn::Result { + let mut flatten = None; + + for attr in attrs.iter().filter(|a| a.path().is_ident("to_df")) { + attr.parse_nested_meta(|meta| { + // get path from #[to_df(flatten = "")] + if meta.path.is_ident("flatten") { + let lit = meta.value()?.parse::()?; + flatten = Some(lit.value()); + } + Ok(()) + })?; + } + + Ok(ToDataFramesMetaParams { flatten }) } +} + +/// Implements ToDataFrames and ColumnData for struct. +/// +/// Usage: +/// ```no_run +/// # use cryo_to_df::ToDataFrames; +/// # type DynSolValue = u64; +/// # pub mod cryo_freeze { +/// # pub mod indexmap { pub use std::collections::BTreeMap as IndexMap; } +/// # pub mod polars { +/// # pub mod prelude { +/// # pub struct DataFrame; impl DataFrame { pub fn new(_: T) -> Result { Ok(Self) } } +/// # pub struct Column; +/// # } +/// # } +/// # use polars::prelude::*; +/// # use std::collections::HashMap; +/// # pub enum ColumnType { Boolean, UInt32, UInt64, UInt256, Int32, Int64, Float32, Float64, String, Binary } +/// # pub enum CollectError { PolarsError(()) } +/// # #[derive(Hash, PartialEq, Eq)] +/// # pub enum Datatype { MyStruct } +/// # pub struct Table; impl Table { pub fn columns(&self) -> Vec<&'static str> { vec![] } } +/// # pub trait SortableDataFrame { fn sort_by_schema(self, schema: &Table) -> Self; } +/// # impl SortableDataFrame for Result { fn sort_by_schema(self, schema: &Table) -> Self { self } } +/// # #[macro_export] +/// # macro_rules! with_column_impl { ($cols:expr, $name:expr, $value:expr, $schema:expr) => {let _: Vec = $cols;}; } +/// # pub use with_column_impl as with_column; +/// # pub use with_column_impl as with_column_primitive; +/// # pub trait ColumnData { +/// # fn column_types() -> indexmap::IndexMap<&'static str, ColumnType>; +/// # } +/// # pub trait ToDataFrames: Sized { +/// # fn create_dfs(self, schemas: &HashMap, chain_id: u64) -> Result, CollectError>; +/// # } +/// # } +/// use cryo_freeze::*; +/// use polars::prelude::*; +/// +/// #[derive(ToDataFrames)] +/// struct MyStruct { +/// n_rows: u64, +/// field1: Vec, +/// field2: Vec, +/// #[to_df(flatten = "extract_others")] +/// others: indexmap::IndexMap>, +/// chain_id: Vec, +/// } +/// +/// fn extract_others( +/// cols: &mut Vec, +/// name: &str, +/// values: indexmap::IndexMap>, +/// n_rows: usize, +/// schema: &Table, +/// ) -> Result<(), CollectError> { +/// todo!() +/// } +/// ``` +#[proc_macro_derive(ToDataFrames, attributes(to_df))] +pub fn to_data_frames(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as ItemStruct); let name = &input.ident; + let datatype = quote!(Datatype::#name); + let datatype_str = name.to_string(); + let field_names_and_types: Vec<_> = - input.clone().fields.into_iter().map(|f| (f.ident.unwrap(), f.ty)).collect(); + input.fields.iter().map(|f| (f.ident.clone().unwrap(), f.ty.clone())).collect(); let field_processing: Vec<_> = field_names_and_types .iter() - .filter(|(name, _)| format!("{}", quote!(#name)) != "n_rows") - .filter(|(_, value)| format!("{}", quote!(#value)).starts_with("Vec")) + .filter(|(name, _)| quote!(#name).to_string() != "n_rows") + .filter(|(_, value)| quote!(#value).to_string().starts_with("Vec")) .filter(|(name, _)| name != "chain_id") .map(|(name, ty)| { let macro_name = match quote!(#ty).to_string().as_str() { - "Vec < Vec < u8 > >" => syn::Ident::new("with_series_binary", Span::call_site()), - "Vec < Option < Vec < u8 > > >" => { - syn::Ident::new("with_series_binary", Span::call_site()) - } - "Vec < U256 >" => syn::Ident::new("with_series_u256", Span::call_site()), - "Vec < Option < U256 > >" => { - syn::Ident::new("with_series_option_u256", Span::call_site()) - } - _ => syn::Ident::new("with_series", Span::call_site()), + "Vec < u32 >" | "Vec < u64 >" => "with_column_primitive", + "Vec < i32 >" | "Vec < i64 >" => "with_column_primitive", + "Vec < f32 >" | "Vec < f64 >" => "with_column_primitive", + _ => "with_column", }; - let field_name_str = format!("{}", quote!(#name)); + let macro_name = syn::Ident::new(macro_name, Span::call_site()); + let field_name_str = quote!(#name).to_string(); quote! { #macro_name!(cols, #field_name_str, self.#name, schema); } }) .collect(); - let has_event_cols = !field_names_and_types + let mut flatten_field = None; + let event_code = input + .fields .iter() - .filter(|(name, _)| name == "event_cols") - .collect::>() - .is_empty(); - let event_code = if has_event_cols { - // Generate the tokens for the event processing code - quote! { - let decoder = schema.log_decoder.clone(); - let u256_types: Vec<_> = schema.u256_types.clone().into_iter().collect(); - if let Some(decoder) = decoder { - - fn create_empty_u256_columns( - cols: &mut Vec, - name: &str, - u256_types: &[U256Type], - column_encoding: &ColumnEncoding - ) { - for u256_type in u256_types.iter() { - let full_name = name.to_string() + u256_type.suffix().as_str(); - let full_name = full_name.as_str(); - - match u256_type { - U256Type::Binary => { - match column_encoding { - ColumnEncoding::Binary => { - cols.push(Series::new(full_name, Vec::>::new())) - }, - ColumnEncoding::Hex => { - cols.push(Series::new(full_name, Vec::::new())) - }, - } - }, - U256Type::String => cols.push(Series::new(full_name, Vec::::new())), - U256Type::F32 => cols.push(Series::new(full_name, Vec::::new())), - U256Type::F64 => cols.push(Series::new(full_name, Vec::::new())), - U256Type::U32 => cols.push(Series::new(full_name, Vec::::new())), - U256Type::U64 => cols.push(Series::new(full_name, Vec::::new())), - U256Type::Decimal128 => cols.push(Series::new(full_name, Vec::>::new())), - } - } - } - - // Write columns even if there are no values decoded - indicates empty dataframe - let chunk_len = self.n_rows; - if self.event_cols.is_empty() { - for param in decoder.event.inputs.iter() { - let name = "event__".to_string() + param.name.as_str(); - let name = name.as_str(); - let ty = DynSolType::parse(¶m.ty).unwrap(); - match ty { - DynSolType::Address => { - match schema.binary_type { - ColumnEncoding::Binary => cols.push(Series::new(name, Vec::>::new())), - ColumnEncoding::Hex => cols.push(Series::new(name, Vec::::new())), - } - }, - DynSolType::Bytes => { - match schema.binary_type { - ColumnEncoding::Binary => cols.push(Series::new(name, Vec::>::new())), - ColumnEncoding::Hex => cols.push(Series::new(name, Vec::::new())), - } - }, - DynSolType::Int(bits) => { - if bits <= 64 { - cols.push(Series::new(name, Vec::::new())) - } else { - create_empty_u256_columns(&mut cols, name, &u256_types, &schema.binary_type) - } - }, - DynSolType::Uint(bits) => { - if bits <= 64 { - cols.push(Series::new(name, Vec::::new())) - } else { - create_empty_u256_columns(&mut cols, name, &u256_types, &schema.binary_type) - } - }, - DynSolType::Bool => cols.push(Series::new(name, Vec::::new())), - DynSolType::String => cols.push(Series::new(name, Vec::::new())), - DynSolType::Array(_) => return Err(err("could not generate Array column")), - DynSolType::FixedBytes(_) => return Err(err("could not generate FixedBytes column")), - DynSolType::FixedArray(_, _) => return Err(err("could not generate FixedArray column")), - DynSolType::Tuple(_) => return Err(err("could not generate Tuple column")), - DynSolType::Function => return Err(err("could not generate Function column")), - _ => (), - } - } - } else { - for (name, data) in self.event_cols { - let series_vec = decoder.make_series( - name, - data, - chunk_len as usize, - &u256_types, - &schema.binary_type, - ); - match series_vec { - Ok(s) => { - cols.extend(s); - } - Err(e) => eprintln!("error creating frame: {}", e), /* TODO: see how best - * to - * bubble up error */ - } - } - } - - let drop_names = vec!["topic1".to_string(), "topic2".to_string(), "topic3".to_string(), "data".to_string()]; - cols.retain(|c| !drop_names.contains(&c.name().to_string())); + .find_map(|f| { + let params = ToDataFramesMetaParams::parse_attributes(&f.attrs).unwrap(); + params.flatten.map(|s| (f, s)) + }) + .map(|(field, flatten)| { + let expr = parse_str::(&flatten).unwrap(); + let field_name = field.ident.as_ref().unwrap(); + let field_name_str = field_name.to_string(); + flatten_field = Some(field_name_str.clone()); + quote! { + #expr(&mut cols, #field_name_str, self.#field_name, self.n_rows as usize, schema)?; } - } - } else { - // Generate an empty set of tokens if has_event_cols is false - quote! {} - }; + }); fn map_type_to_column_type(ty: &syn::Type) -> Option { match quote!(#ty).to_string().as_str() { @@ -179,10 +143,12 @@ pub fn to_df(attrs: TokenStream, input: TokenStream) -> TokenStream { "Vec < U256 >" => Some(quote! { ColumnType::UInt256 }), "Vec < i32 >" => Some(quote! { ColumnType::Int32 }), "Vec < i64 >" => Some(quote! { ColumnType::Int64 }), + "Vec < I256 >" => Some(quote! { ColumnType::Int256 }), "Vec < f32 >" => Some(quote! { ColumnType::Float32 }), "Vec < f64 >" => Some(quote! { ColumnType::Float64 }), "Vec < String >" => Some(quote! { ColumnType::String }), "Vec < Vec < u8 > >" => Some(quote! { ColumnType::Binary }), + "Vec < RawBytes >" => Some(quote! { ColumnType::Binary }), "Vec < Option < bool > >" => Some(quote! { ColumnType::Boolean }), "Vec < Option < u32 > >" => Some(quote! { ColumnType::UInt32 }), @@ -190,54 +156,47 @@ pub fn to_df(attrs: TokenStream, input: TokenStream) -> TokenStream { "Vec < Option < U256 > >" => Some(quote! { ColumnType::UInt256 }), "Vec < Option < i32 > >" => Some(quote! { ColumnType::Int32 }), "Vec < Option < i64 > >" => Some(quote! { ColumnType::Int64 }), + "Vec < Option < I256 > >" => Some(quote! { ColumnType::Int256 }), "Vec < Option < f32 > >" => Some(quote! { ColumnType::Float32 }), "Vec < Option < f64 > >" => Some(quote! { ColumnType::Float64 }), "Vec < Option < String > >" => Some(quote! { ColumnType::String }), "Vec < Option < Vec < u8 > > >" => Some(quote! { ColumnType::Binary }), + "Vec < Option < RawBytes > >" => Some(quote! { ColumnType::Binary }), _ => None, // _ => quote! {ColumnType::Binary}, } } - let datatype_str = - datatypes[0].segments.iter().map(|seg| seg.ident.to_string()).collect::>(); - let datatype_str = datatype_str.iter().last().unwrap(); - let mut column_types = Vec::new(); for (name, ty) in field_names_and_types.iter() { if let Some(column_type) = map_type_to_column_type(ty) { let field_name_str = format!("{}", quote!(#name)); column_types.push(quote! { (#field_name_str, #column_type) }); - } else if name != "n_rows" && name != "event_cols" { - println!("invalid column type for {name} in table {}", datatype_str); + } else if name != "n_rows" && + (flatten_field.is_none() || name != flatten_field.as_deref().unwrap()) + { + println!("invalid column type for {name} in table {datatype_str}"); } } let expanded = quote! { - #input - impl ToDataFrames for #name { fn create_dfs( self, schemas: &std::collections::HashMap, chain_id: u64, - ) -> R> { - let datatypes = vec![#(#datatypes),*]; - let datatype = if datatypes.len() == 1 { - datatypes[0] - } else { - panic!("improper datatypes for single schema") - }; + ) -> Result, CollectError> { + let datatype = #datatype; let schema = schemas.get(&datatype).expect("schema not provided"); let mut cols = Vec::with_capacity(schema.columns().len()); #(#field_processing)* if self.chain_id.len() == 0 { - with_series!(cols, "chain_id", vec![chain_id; self.n_rows as usize], schema); + with_column!(cols, "chain_id", vec![chain_id; self.n_rows as usize], schema); } else { - with_series!(cols, "chain_id", self.chain_id, schema); + with_column!(cols, "chain_id", self.chain_id, schema); } #event_code @@ -261,3 +220,137 @@ pub fn to_df(attrs: TokenStream, input: TokenStream) -> TokenStream { expanded.into() } + +/// Implements FromDataFrames for struct. +/// +/// Usage: +/// ```no_run +/// # use cryo_to_df::FromDataFrames; +/// # pub mod cryo_freeze { +/// # pub mod polars { +/// # pub mod prelude { +/// # pub enum PolarsError { ColumnNotFound(String) } +/// # pub struct DataFrame; +/// # impl DataFrame { +/// # pub fn column(&self, name: &str) -> Result<&Series, ()> { Ok(&Series) } +/// # pub fn height(&self) -> usize { 0 } +/// # } +/// # pub struct Series; +/// # impl Series { +/// # pub fn u32(&self) -> Result>, ()> { Ok(vec![]) } +/// # pub fn u64(&self) -> Result>, ()> { Ok(vec![]) } +/// # pub fn str(&self) -> Result>, ()> { Ok(vec![]) } +/// # } +/// # } +/// # } +/// # use polars::prelude::*; +/// # use std::collections::HashMap; +/// # pub enum CollectError { PolarsError(PolarsError) } +/// # #[derive(Hash, PartialEq, Eq)] +/// # pub enum Datatype { MyStruct } +/// # pub struct Table; impl Table { pub fn columns(&self) -> Vec<&'static str> { vec![] } } +/// # #[macro_export] +/// # macro_rules! parse_column_impl { ($df:expr, $name:expr, $ty:ident, $value:expr, $schema:expr) => {}; } +/// # pub use parse_column_impl as parse_column; +/// # pub use parse_column_impl as parse_column_primitive; +/// # pub trait FromDataFrames: Sized { +/// # fn parse_dfs(&mut self, dfs: HashMap, schemas: &HashMap) -> Result<&mut Self, CollectError>; +/// # } +/// # } +/// use cryo_freeze::*; +/// use polars::prelude::*; +/// +/// #[derive(FromDataFrames)] +/// struct MyStruct { +/// n_rows: u64, +/// field1: Vec, +/// field2: Vec, +/// chain_id: Vec, +/// } +/// ``` +#[proc_macro_derive(FromDataFrames, attributes(to_df))] +pub fn from_data_frames(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as ItemStruct); + + let name = &input.ident; + + let datatype = quote!(Datatype::#name); + + let field_names_and_types: Vec<_> = + input.fields.iter().map(|f| (f.ident.clone().unwrap(), f.ty.clone())).collect(); + + // Generate field population code using the new parse_column macros + let field_population: Vec<_> = field_names_and_types + .iter() + .filter(|(name, _)| quote!(#name).to_string() != "n_rows") + .filter(|(_, value)| quote!(#value).to_string().starts_with("Vec")) + .map(|(name, ty)| { + let field_name_str = quote!(#name).to_string(); + match quote!(#ty).to_string().as_str() { + "Vec < u32 >" | "Vec < Option < u32 > >" => quote! { + parse_column_primitive!(df, #field_name_str, u32, self.#name, schema); + }, + "Vec < u64 >" | "Vec < Option < u64 > >" => quote! { + parse_column_primitive!(df, #field_name_str, u64, self.#name, schema); + }, + "Vec < i32 >" | "Vec < Option < i32 > >" => quote! { + parse_column_primitive!(df, #field_name_str, i32, self.#name, schema); + }, + "Vec < i64 >" | "Vec < Option < i64 > >" => quote! { + parse_column_primitive!(df, #field_name_str, i64, self.#name, schema); + }, + "Vec < f32 >" | "Vec < Option < f32 > >" => quote! { + parse_column_primitive!(df, #field_name_str, f32, self.#name, schema); + }, + "Vec < f64 >" | "Vec < Option < f64 > >" => quote! { + parse_column_primitive!(df, #field_name_str, f64, self.#name, schema); + }, + "Vec < String >" | "Vec < Option < String > >" => quote! { + parse_column_primitive!(df, #field_name_str, str, self.#name, schema); + }, + "Vec < bool >" | "Vec < Option < bool > >" => quote! { + parse_column_primitive!(df, #field_name_str, bool, self.#name, schema); + }, + // Handle U256/I256 types with binary column name fallback + "Vec < U256 >" | "Vec < Option < U256 > >" => quote! { + parse_column!(df, #field_name_str, U256, self.#name, schema); + }, + "Vec < I256 >" | "Vec < Option < I256 > >" => quote! { + parse_column!(df, #field_name_str, I256, self.#name, schema); + }, + "Vec < RawBytes >" | "Vec < Option < RawBytes > >" => quote! { + parse_column_primitive!(df, #field_name_str, binary, self.#name, schema); + }, + _ => quote! { + // Handle unsupported types - for now, just set to default + result.#name = vec![]; + }, + } + }) + .collect(); + + let expanded = quote! { + impl FromDataFrames for #name { + fn parse_dfs( + &mut self, + dfs: std::collections::HashMap, + schemas: &std::collections::HashMap, + ) -> Result<&mut Self, CollectError> { + let datatype = #datatype; + let schema = schemas.get(&datatype).expect("schema not provided"); + + let df = dfs.get(&datatype).ok_or_else(|| { + CollectError::PolarsError(polars::prelude::PolarsError::ColumnNotFound("dataframe not found".into())) + })?; + + self.n_rows = df.height() as u64; + + #(#field_population)* + + Ok(self) + } + } + }; + + expanded.into() +}