├── .dockerignore ├── .github ├── dependabot.yml └── workflows │ ├── audit.yml │ ├── lint.yml │ ├── release.yml │ └── test.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── config └── config.json ├── db └── tests │ └── test.sql ├── docker-compose.yml ├── docs └── openapi.spec ├── rust-toolchain.toml ├── rustfmt.toml ├── scripts ├── import_mock_data.sh ├── start.sh └── stop.sh ├── src ├── bin │ └── main.rs ├── cache.rs ├── consts.rs ├── db │ ├── mod.rs │ ├── models │ │ ├── batch.rs │ │ ├── block.rs │ │ ├── chunk.rs │ │ └── mod.rs │ └── queries │ │ ├── batch_query.rs │ │ ├── block_query.rs │ │ ├── chunk_query.rs │ │ └── mod.rs ├── lib.rs ├── open_api │ ├── apis.rs │ ├── mod.rs │ ├── objects │ │ ├── batch.rs │ │ ├── block.rs │ │ ├── chunk.rs │ │ └── mod.rs │ └── responses │ │ ├── batch_response.rs │ │ ├── batches_response.rs │ │ ├── blocks_response.rs │ │ ├── chunks_response.rs │ │ ├── last_batch_indexes_response.rs │ │ ├── mod.rs │ │ └── search_response.rs └── settings.rs └── third-parties └── scroll └── database └── migrate └── migrations ├── 00001_l1_message.sql ├── 00002_l1_block.sql ├── 00003_l2_block.sql ├── 00004_chunk.sql ├── 00005_batch.sql └── 00006_prover_task.sql /.dockerignore: -------------------------------------------------------------------------------- 1 | docs 2 | third-parties/* -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: weekly 7 | # Disable updates 8 | open-pull-requests-limit: 0 9 | -------------------------------------------------------------------------------- /.github/workflows/audit.yml: -------------------------------------------------------------------------------- 1 | name: Security Audit 2 | 3 | on: 4 | push: 5 | branches: 6 | - alpha 7 | - develop 8 | paths: 9 | - Cargo.lock 10 | pull_request: 11 | types: [synchronize, opened, reopened, ready_for_review] 12 | branches: 13 | - alpha 14 | - develop 15 | paths: 16 | - Cargo.lock 17 | 18 | jobs: 19 | security-audit: 20 | if: | 21 | github.event.pull_request.draft == false || 22 | github.event.action == 'ready_for_review' 23 | name: security-audit 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v2 27 | - uses: actions-rs/toolchain@v1 28 | with: 29 | override: true 30 | profile: minimal 31 | toolchain: nightly-2022-07-26 32 | - uses: Swatinem/rust-cache@v1 33 | # - run: | 34 | # cargo install cargo-audit 35 | # cargo audit \ 36 | # --deny warnings \ 37 | # --ignore RUSTSEC-2020-0071 \ 38 | # --ignore RUSTSEC-2023-0033 \ 39 | # --ignore RUSTSEC-2023-0034 \ 40 | # --ignore RUSTSEC-2023-0052 41 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: 6 | - alpha 7 | - develop 8 | pull_request: 9 | types: [synchronize, opened, reopened, ready_for_review] 10 | branches: 11 | - alpha 12 | - develop 13 | 14 | jobs: 15 | fmt: 16 | if: | 17 | github.event.pull_request.draft == false || 18 | github.event.action == 'ready_for_review' 19 | name: fmt 20 | runs-on: ubuntu-latest 21 | steps: 22 | - uses: actions/checkout@v2 23 | - uses: actions-rs/toolchain@v1 24 | with: 25 | components: rustfmt 26 | override: true 27 | profile: minimal 28 | toolchain: nightly-2022-07-26 29 | - uses: Swatinem/rust-cache@v1 30 | - run: | 31 | cargo build --release 32 | cargo fmt --all -- --check 33 | 34 | clippy: 35 | if: | 36 | github.event.pull_request.draft == false || 37 | github.event.action == 'ready_for_review' 38 | name: clippy 39 | runs-on: ubuntu-latest 40 | steps: 41 | - uses: actions/checkout@v2 42 | - uses: actions-rs/toolchain@v1 43 | with: 44 | components: clippy 45 | override: true 46 | profile: minimal 47 | toolchain: nightly-2022-07-26 48 | - uses: Swatinem/rust-cache@v1 49 | - run: cargo clippy -- -D warnings 50 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Build and publish docker image 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*.*.*' 7 | 8 | env: 9 | AWS_REGION: us-west-2 10 | 11 | jobs: 12 | build: 13 | name: Clone, Build, Publish 14 | runs-on: ubuntu-latest 15 | steps: 16 | 17 | - name: Check out repository 18 | uses: actions/checkout@v2 19 | 20 | - name: Set up QEMU 21 | uses: docker/setup-qemu-action@v2 22 | 23 | - name: Set up Docker Buildx 24 | uses: docker/setup-buildx-action@v2 25 | 26 | - name: Login to Dockerhub 27 | uses: docker/login-action@v2 28 | with: 29 | username: ${{ secrets.DOCKERHUB_USERNAME }} 30 | password: ${{ secrets.DOCKERHUB_TOKEN }} 31 | 32 | # build and push to aws ecr 33 | - name: Configure AWS credentials 34 | uses: aws-actions/configure-aws-credentials@v4 35 | with: 36 | aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} 37 | aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 38 | aws-region: ${{ env.AWS_REGION }} 39 | 40 | - name: Login to Amazon ECR 41 | id: login-ecr 42 | uses: aws-actions/amazon-ecr-login@v2 43 | 44 | - name: Build image 45 | id: build 46 | env: 47 | ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} 48 | ECR_REPOSITORY: rollup-explorer-backend 49 | IMAGE_TAG: ${{ github.ref_name }} 50 | uses: docker/build-push-action@v3 51 | with: 52 | platforms: linux/amd64,linux/arm64 53 | push: true 54 | tags: | 55 | ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }} 56 | ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.ECR_REPOSITORY }}:latest 57 | ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }} 58 | ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:latest 59 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Unit Test 2 | 3 | on: 4 | push: 5 | branches: 6 | - alpha 7 | - develop 8 | pull_request: 9 | types: [synchronize, opened, reopened, ready_for_review] 10 | branches: 11 | - alpha 12 | - develop 13 | 14 | jobs: 15 | unit-test: 16 | if: | 17 | github.event.pull_request.draft == false || 18 | github.event.action == 'ready_for_review' 19 | name: unit-test 20 | runs-on: ubuntu-latest 21 | steps: 22 | - uses: actions/checkout@v2 23 | - uses: actions-rs/toolchain@v1 24 | with: 25 | override: true 26 | profile: minimal 27 | toolchain: nightly-2022-07-26 28 | - uses: Swatinem/rust-cache@v1 29 | - uses: taiki-e/install-action@nextest 30 | - run: cargo nextest run --all 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | /docker-data 4 | /target 5 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.21.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "aead" 22 | version = "0.5.2" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" 25 | dependencies = [ 26 | "crypto-common", 27 | "generic-array", 28 | ] 29 | 30 | [[package]] 31 | name = "aes" 32 | version = "0.8.2" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" 35 | dependencies = [ 36 | "cfg-if", 37 | "cipher", 38 | "cpufeatures", 39 | ] 40 | 41 | [[package]] 42 | name = "aes-gcm" 43 | version = "0.10.1" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" 46 | dependencies = [ 47 | "aead", 48 | "aes", 49 | "cipher", 50 | "ctr", 51 | "ghash", 52 | "subtle", 53 | ] 54 | 55 | [[package]] 56 | name = "ahash" 57 | version = "0.7.6" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" 60 | dependencies = [ 61 | "getrandom", 62 | "once_cell", 63 | "version_check", 64 | ] 65 | 66 | [[package]] 67 | name = "ahash" 68 | version = "0.8.3" 69 | source = "registry+https://github.com/rust-lang/crates.io-index" 70 | checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" 71 | dependencies = [ 72 | "cfg-if", 73 | "once_cell", 74 | "version_check", 75 | ] 76 | 77 | [[package]] 78 | name = "aho-corasick" 79 | version = "0.7.20" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" 82 | dependencies = [ 83 | "memchr", 84 | ] 85 | 86 | [[package]] 87 | name = "android-tzdata" 88 | version = "0.1.1" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" 91 | 92 | [[package]] 93 | name = "android_system_properties" 94 | version = "0.1.5" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 97 | dependencies = [ 98 | "libc", 99 | ] 100 | 101 | [[package]] 102 | name = "anyhow" 103 | version = "1.0.71" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" 106 | 107 | [[package]] 108 | name = "arrayvec" 109 | version = "0.7.2" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" 112 | 113 | [[package]] 114 | name = "async-trait" 115 | version = "0.1.68" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" 118 | dependencies = [ 119 | "proc-macro2", 120 | "quote", 121 | "syn 2.0.13", 122 | ] 123 | 124 | [[package]] 125 | name = "atoi" 126 | version = "1.0.0" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" 129 | dependencies = [ 130 | "num-traits", 131 | ] 132 | 133 | [[package]] 134 | name = "autocfg" 135 | version = "1.1.0" 136 | source = "registry+https://github.com/rust-lang/crates.io-index" 137 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 138 | 139 | [[package]] 140 | name = "backtrace" 141 | version = "0.3.69" 142 | source = "registry+https://github.com/rust-lang/crates.io-index" 143 | checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" 144 | dependencies = [ 145 | "addr2line", 146 | "cc", 147 | "cfg-if", 148 | "libc", 149 | "miniz_oxide", 150 | "object", 151 | "rustc-demangle", 152 | ] 153 | 154 | [[package]] 155 | name = "base64" 156 | version = "0.13.1" 157 | source = "registry+https://github.com/rust-lang/crates.io-index" 158 | checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" 159 | 160 | [[package]] 161 | name = "base64" 162 | version = "0.21.0" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" 165 | 166 | [[package]] 167 | name = "bitflags" 168 | version = "1.3.2" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 171 | 172 | [[package]] 173 | name = "block-buffer" 174 | version = "0.10.4" 175 | source = "registry+https://github.com/rust-lang/crates.io-index" 176 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 177 | dependencies = [ 178 | "generic-array", 179 | ] 180 | 181 | [[package]] 182 | name = "borsh" 183 | version = "0.10.3" 184 | source = "registry+https://github.com/rust-lang/crates.io-index" 185 | checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" 186 | dependencies = [ 187 | "borsh-derive", 188 | "hashbrown 0.13.2", 189 | ] 190 | 191 | [[package]] 192 | name = "borsh-derive" 193 | version = "0.10.3" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" 196 | dependencies = [ 197 | "borsh-derive-internal", 198 | "borsh-schema-derive-internal", 199 | "proc-macro-crate 0.1.5", 200 | "proc-macro2", 201 | "syn 1.0.109", 202 | ] 203 | 204 | [[package]] 205 | name = "borsh-derive-internal" 206 | version = "0.10.3" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" 209 | dependencies = [ 210 | "proc-macro2", 211 | "quote", 212 | "syn 1.0.109", 213 | ] 214 | 215 | [[package]] 216 | name = "borsh-schema-derive-internal" 217 | version = "0.10.3" 218 | source = "registry+https://github.com/rust-lang/crates.io-index" 219 | checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" 220 | dependencies = [ 221 | "proc-macro2", 222 | "quote", 223 | "syn 1.0.109", 224 | ] 225 | 226 | [[package]] 227 | name = "bumpalo" 228 | version = "3.12.0" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" 231 | 232 | [[package]] 233 | name = "bytecheck" 234 | version = "0.6.10" 235 | source = "registry+https://github.com/rust-lang/crates.io-index" 236 | checksum = "13fe11640a23eb24562225322cd3e452b93a3d4091d62fab69c70542fcd17d1f" 237 | dependencies = [ 238 | "bytecheck_derive", 239 | "ptr_meta", 240 | "simdutf8", 241 | ] 242 | 243 | [[package]] 244 | name = "bytecheck_derive" 245 | version = "0.6.10" 246 | source = "registry+https://github.com/rust-lang/crates.io-index" 247 | checksum = "e31225543cb46f81a7e224762764f4a6a0f097b1db0b175f69e8065efaa42de5" 248 | dependencies = [ 249 | "proc-macro2", 250 | "quote", 251 | "syn 1.0.109", 252 | ] 253 | 254 | [[package]] 255 | name = "byteorder" 256 | version = "1.4.3" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 259 | 260 | [[package]] 261 | name = "bytes" 262 | version = "1.4.0" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" 265 | 266 | [[package]] 267 | name = "cc" 268 | version = "1.0.79" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" 271 | 272 | [[package]] 273 | name = "cfg-if" 274 | version = "1.0.0" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 277 | 278 | [[package]] 279 | name = "chrono" 280 | version = "0.4.26" 281 | source = "registry+https://github.com/rust-lang/crates.io-index" 282 | checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" 283 | dependencies = [ 284 | "android-tzdata", 285 | "iana-time-zone", 286 | "js-sys", 287 | "num-traits", 288 | "serde", 289 | "time 0.1.45", 290 | "wasm-bindgen", 291 | "winapi", 292 | ] 293 | 294 | [[package]] 295 | name = "cipher" 296 | version = "0.4.4" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" 299 | dependencies = [ 300 | "crypto-common", 301 | "inout", 302 | ] 303 | 304 | [[package]] 305 | name = "codespan-reporting" 306 | version = "0.11.1" 307 | source = "registry+https://github.com/rust-lang/crates.io-index" 308 | checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" 309 | dependencies = [ 310 | "termcolor", 311 | "unicode-width", 312 | ] 313 | 314 | [[package]] 315 | name = "config" 316 | version = "0.13.3" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" 319 | dependencies = [ 320 | "async-trait", 321 | "json5", 322 | "lazy_static", 323 | "nom", 324 | "pathdiff", 325 | "ron", 326 | "rust-ini", 327 | "serde", 328 | "serde_json", 329 | "toml", 330 | "yaml-rust", 331 | ] 332 | 333 | [[package]] 334 | name = "convert_case" 335 | version = "0.4.0" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" 338 | 339 | [[package]] 340 | name = "cookie" 341 | version = "0.17.0" 342 | source = "registry+https://github.com/rust-lang/crates.io-index" 343 | checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" 344 | dependencies = [ 345 | "aes-gcm", 346 | "base64 0.21.0", 347 | "hkdf", 348 | "hmac", 349 | "percent-encoding", 350 | "rand", 351 | "sha2", 352 | "subtle", 353 | "time 0.3.20", 354 | "version_check", 355 | ] 356 | 357 | [[package]] 358 | name = "core-foundation-sys" 359 | version = "0.8.4" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" 362 | 363 | [[package]] 364 | name = "cpufeatures" 365 | version = "0.2.6" 366 | source = "registry+https://github.com/rust-lang/crates.io-index" 367 | checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" 368 | dependencies = [ 369 | "libc", 370 | ] 371 | 372 | [[package]] 373 | name = "crc" 374 | version = "3.0.1" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" 377 | dependencies = [ 378 | "crc-catalog", 379 | ] 380 | 381 | [[package]] 382 | name = "crc-catalog" 383 | version = "2.2.0" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" 386 | 387 | [[package]] 388 | name = "crossbeam-channel" 389 | version = "0.5.8" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" 392 | dependencies = [ 393 | "cfg-if", 394 | "crossbeam-utils", 395 | ] 396 | 397 | [[package]] 398 | name = "crossbeam-queue" 399 | version = "0.3.8" 400 | source = "registry+https://github.com/rust-lang/crates.io-index" 401 | checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" 402 | dependencies = [ 403 | "cfg-if", 404 | "crossbeam-utils", 405 | ] 406 | 407 | [[package]] 408 | name = "crossbeam-utils" 409 | version = "0.8.15" 410 | source = "registry+https://github.com/rust-lang/crates.io-index" 411 | checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" 412 | dependencies = [ 413 | "cfg-if", 414 | ] 415 | 416 | [[package]] 417 | name = "crypto-common" 418 | version = "0.1.6" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 421 | dependencies = [ 422 | "generic-array", 423 | "rand_core", 424 | "typenum", 425 | ] 426 | 427 | [[package]] 428 | name = "ctr" 429 | version = "0.9.2" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" 432 | dependencies = [ 433 | "cipher", 434 | ] 435 | 436 | [[package]] 437 | name = "cxx" 438 | version = "1.0.94" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" 441 | dependencies = [ 442 | "cc", 443 | "cxxbridge-flags", 444 | "cxxbridge-macro", 445 | "link-cplusplus", 446 | ] 447 | 448 | [[package]] 449 | name = "cxx-build" 450 | version = "1.0.94" 451 | source = "registry+https://github.com/rust-lang/crates.io-index" 452 | checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" 453 | dependencies = [ 454 | "cc", 455 | "codespan-reporting", 456 | "once_cell", 457 | "proc-macro2", 458 | "quote", 459 | "scratch", 460 | "syn 2.0.13", 461 | ] 462 | 463 | [[package]] 464 | name = "cxxbridge-flags" 465 | version = "1.0.94" 466 | source = "registry+https://github.com/rust-lang/crates.io-index" 467 | checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" 468 | 469 | [[package]] 470 | name = "cxxbridge-macro" 471 | version = "1.0.94" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" 474 | dependencies = [ 475 | "proc-macro2", 476 | "quote", 477 | "syn 2.0.13", 478 | ] 479 | 480 | [[package]] 481 | name = "darling" 482 | version = "0.14.4" 483 | source = "registry+https://github.com/rust-lang/crates.io-index" 484 | checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" 485 | dependencies = [ 486 | "darling_core", 487 | "darling_macro", 488 | ] 489 | 490 | [[package]] 491 | name = "darling_core" 492 | version = "0.14.4" 493 | source = "registry+https://github.com/rust-lang/crates.io-index" 494 | checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" 495 | dependencies = [ 496 | "fnv", 497 | "ident_case", 498 | "proc-macro2", 499 | "quote", 500 | "strsim", 501 | "syn 1.0.109", 502 | ] 503 | 504 | [[package]] 505 | name = "darling_macro" 506 | version = "0.14.4" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" 509 | dependencies = [ 510 | "darling_core", 511 | "quote", 512 | "syn 1.0.109", 513 | ] 514 | 515 | [[package]] 516 | name = "derive_more" 517 | version = "0.99.17" 518 | source = "registry+https://github.com/rust-lang/crates.io-index" 519 | checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" 520 | dependencies = [ 521 | "convert_case", 522 | "proc-macro2", 523 | "quote", 524 | "rustc_version", 525 | "syn 1.0.109", 526 | ] 527 | 528 | [[package]] 529 | name = "digest" 530 | version = "0.10.6" 531 | source = "registry+https://github.com/rust-lang/crates.io-index" 532 | checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" 533 | dependencies = [ 534 | "block-buffer", 535 | "crypto-common", 536 | "subtle", 537 | ] 538 | 539 | [[package]] 540 | name = "dirs" 541 | version = "4.0.0" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" 544 | dependencies = [ 545 | "dirs-sys", 546 | ] 547 | 548 | [[package]] 549 | name = "dirs-sys" 550 | version = "0.3.7" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" 553 | dependencies = [ 554 | "libc", 555 | "redox_users", 556 | "winapi", 557 | ] 558 | 559 | [[package]] 560 | name = "dlv-list" 561 | version = "0.3.0" 562 | source = "registry+https://github.com/rust-lang/crates.io-index" 563 | checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" 564 | 565 | [[package]] 566 | name = "dotenvy" 567 | version = "0.15.7" 568 | source = "registry+https://github.com/rust-lang/crates.io-index" 569 | checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" 570 | 571 | [[package]] 572 | name = "either" 573 | version = "1.8.1" 574 | source = "registry+https://github.com/rust-lang/crates.io-index" 575 | checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" 576 | 577 | [[package]] 578 | name = "encoding_rs" 579 | version = "0.8.32" 580 | source = "registry+https://github.com/rust-lang/crates.io-index" 581 | checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" 582 | dependencies = [ 583 | "cfg-if", 584 | ] 585 | 586 | [[package]] 587 | name = "errno" 588 | version = "0.3.1" 589 | source = "registry+https://github.com/rust-lang/crates.io-index" 590 | checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" 591 | dependencies = [ 592 | "errno-dragonfly", 593 | "libc", 594 | "windows-sys 0.48.0", 595 | ] 596 | 597 | [[package]] 598 | name = "errno-dragonfly" 599 | version = "0.1.2" 600 | source = "registry+https://github.com/rust-lang/crates.io-index" 601 | checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" 602 | dependencies = [ 603 | "cc", 604 | "libc", 605 | ] 606 | 607 | [[package]] 608 | name = "event-listener" 609 | version = "2.5.3" 610 | source = "registry+https://github.com/rust-lang/crates.io-index" 611 | checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" 612 | 613 | [[package]] 614 | name = "fastrand" 615 | version = "1.9.0" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" 618 | dependencies = [ 619 | "instant", 620 | ] 621 | 622 | [[package]] 623 | name = "fnv" 624 | version = "1.0.7" 625 | source = "registry+https://github.com/rust-lang/crates.io-index" 626 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 627 | 628 | [[package]] 629 | name = "form_urlencoded" 630 | version = "1.1.0" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" 633 | dependencies = [ 634 | "percent-encoding", 635 | ] 636 | 637 | [[package]] 638 | name = "futures" 639 | version = "0.3.28" 640 | source = "registry+https://github.com/rust-lang/crates.io-index" 641 | checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" 642 | dependencies = [ 643 | "futures-channel", 644 | "futures-core", 645 | "futures-executor", 646 | "futures-io", 647 | "futures-sink", 648 | "futures-task", 649 | "futures-util", 650 | ] 651 | 652 | [[package]] 653 | name = "futures-channel" 654 | version = "0.3.28" 655 | source = "registry+https://github.com/rust-lang/crates.io-index" 656 | checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" 657 | dependencies = [ 658 | "futures-core", 659 | "futures-sink", 660 | ] 661 | 662 | [[package]] 663 | name = "futures-core" 664 | version = "0.3.28" 665 | source = "registry+https://github.com/rust-lang/crates.io-index" 666 | checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" 667 | 668 | [[package]] 669 | name = "futures-executor" 670 | version = "0.3.28" 671 | source = "registry+https://github.com/rust-lang/crates.io-index" 672 | checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" 673 | dependencies = [ 674 | "futures-core", 675 | "futures-task", 676 | "futures-util", 677 | ] 678 | 679 | [[package]] 680 | name = "futures-intrusive" 681 | version = "0.4.2" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" 684 | dependencies = [ 685 | "futures-core", 686 | "lock_api", 687 | "parking_lot 0.11.2", 688 | ] 689 | 690 | [[package]] 691 | name = "futures-io" 692 | version = "0.3.28" 693 | source = "registry+https://github.com/rust-lang/crates.io-index" 694 | checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" 695 | 696 | [[package]] 697 | name = "futures-macro" 698 | version = "0.3.28" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" 701 | dependencies = [ 702 | "proc-macro2", 703 | "quote", 704 | "syn 2.0.13", 705 | ] 706 | 707 | [[package]] 708 | name = "futures-sink" 709 | version = "0.3.28" 710 | source = "registry+https://github.com/rust-lang/crates.io-index" 711 | checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" 712 | 713 | [[package]] 714 | name = "futures-task" 715 | version = "0.3.28" 716 | source = "registry+https://github.com/rust-lang/crates.io-index" 717 | checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" 718 | 719 | [[package]] 720 | name = "futures-util" 721 | version = "0.3.28" 722 | source = "registry+https://github.com/rust-lang/crates.io-index" 723 | checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" 724 | dependencies = [ 725 | "futures-channel", 726 | "futures-core", 727 | "futures-io", 728 | "futures-macro", 729 | "futures-sink", 730 | "futures-task", 731 | "memchr", 732 | "pin-project-lite", 733 | "pin-utils", 734 | "slab", 735 | ] 736 | 737 | [[package]] 738 | name = "generic-array" 739 | version = "0.14.7" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 742 | dependencies = [ 743 | "typenum", 744 | "version_check", 745 | ] 746 | 747 | [[package]] 748 | name = "getrandom" 749 | version = "0.2.9" 750 | source = "registry+https://github.com/rust-lang/crates.io-index" 751 | checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" 752 | dependencies = [ 753 | "cfg-if", 754 | "libc", 755 | "wasi 0.11.0+wasi-snapshot-preview1", 756 | ] 757 | 758 | [[package]] 759 | name = "ghash" 760 | version = "0.5.0" 761 | source = "registry+https://github.com/rust-lang/crates.io-index" 762 | checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" 763 | dependencies = [ 764 | "opaque-debug", 765 | "polyval", 766 | ] 767 | 768 | [[package]] 769 | name = "gimli" 770 | version = "0.28.0" 771 | source = "registry+https://github.com/rust-lang/crates.io-index" 772 | checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" 773 | 774 | [[package]] 775 | name = "h2" 776 | version = "0.3.16" 777 | source = "registry+https://github.com/rust-lang/crates.io-index" 778 | checksum = "5be7b54589b581f624f566bf5d8eb2bab1db736c51528720b6bd36b96b55924d" 779 | dependencies = [ 780 | "bytes", 781 | "fnv", 782 | "futures-core", 783 | "futures-sink", 784 | "futures-util", 785 | "http", 786 | "indexmap", 787 | "slab", 788 | "tokio", 789 | "tokio-util", 790 | "tracing", 791 | ] 792 | 793 | [[package]] 794 | name = "hashbrown" 795 | version = "0.12.3" 796 | source = "registry+https://github.com/rust-lang/crates.io-index" 797 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 798 | dependencies = [ 799 | "ahash 0.7.6", 800 | ] 801 | 802 | [[package]] 803 | name = "hashbrown" 804 | version = "0.13.2" 805 | source = "registry+https://github.com/rust-lang/crates.io-index" 806 | checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" 807 | dependencies = [ 808 | "ahash 0.8.3", 809 | ] 810 | 811 | [[package]] 812 | name = "hashlink" 813 | version = "0.8.1" 814 | source = "registry+https://github.com/rust-lang/crates.io-index" 815 | checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa" 816 | dependencies = [ 817 | "hashbrown 0.12.3", 818 | ] 819 | 820 | [[package]] 821 | name = "headers" 822 | version = "0.3.8" 823 | source = "registry+https://github.com/rust-lang/crates.io-index" 824 | checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" 825 | dependencies = [ 826 | "base64 0.13.1", 827 | "bitflags", 828 | "bytes", 829 | "headers-core", 830 | "http", 831 | "httpdate", 832 | "mime", 833 | "sha1", 834 | ] 835 | 836 | [[package]] 837 | name = "headers-core" 838 | version = "0.2.0" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" 841 | dependencies = [ 842 | "http", 843 | ] 844 | 845 | [[package]] 846 | name = "heck" 847 | version = "0.4.1" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 850 | dependencies = [ 851 | "unicode-segmentation", 852 | ] 853 | 854 | [[package]] 855 | name = "hermit-abi" 856 | version = "0.2.6" 857 | source = "registry+https://github.com/rust-lang/crates.io-index" 858 | checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" 859 | dependencies = [ 860 | "libc", 861 | ] 862 | 863 | [[package]] 864 | name = "hermit-abi" 865 | version = "0.3.1" 866 | source = "registry+https://github.com/rust-lang/crates.io-index" 867 | checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" 868 | 869 | [[package]] 870 | name = "hex" 871 | version = "0.4.3" 872 | source = "registry+https://github.com/rust-lang/crates.io-index" 873 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 874 | 875 | [[package]] 876 | name = "hkdf" 877 | version = "0.12.3" 878 | source = "registry+https://github.com/rust-lang/crates.io-index" 879 | checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" 880 | dependencies = [ 881 | "hmac", 882 | ] 883 | 884 | [[package]] 885 | name = "hmac" 886 | version = "0.12.1" 887 | source = "registry+https://github.com/rust-lang/crates.io-index" 888 | checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" 889 | dependencies = [ 890 | "digest", 891 | ] 892 | 893 | [[package]] 894 | name = "http" 895 | version = "0.2.9" 896 | source = "registry+https://github.com/rust-lang/crates.io-index" 897 | checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" 898 | dependencies = [ 899 | "bytes", 900 | "fnv", 901 | "itoa", 902 | ] 903 | 904 | [[package]] 905 | name = "http-body" 906 | version = "0.4.5" 907 | source = "registry+https://github.com/rust-lang/crates.io-index" 908 | checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 909 | dependencies = [ 910 | "bytes", 911 | "http", 912 | "pin-project-lite", 913 | ] 914 | 915 | [[package]] 916 | name = "httparse" 917 | version = "1.8.0" 918 | source = "registry+https://github.com/rust-lang/crates.io-index" 919 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 920 | 921 | [[package]] 922 | name = "httpdate" 923 | version = "1.0.2" 924 | source = "registry+https://github.com/rust-lang/crates.io-index" 925 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" 926 | 927 | [[package]] 928 | name = "hyper" 929 | version = "0.14.25" 930 | source = "registry+https://github.com/rust-lang/crates.io-index" 931 | checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899" 932 | dependencies = [ 933 | "bytes", 934 | "futures-channel", 935 | "futures-core", 936 | "futures-util", 937 | "h2", 938 | "http", 939 | "http-body", 940 | "httparse", 941 | "httpdate", 942 | "itoa", 943 | "pin-project-lite", 944 | "socket2 0.4.9", 945 | "tokio", 946 | "tower-service", 947 | "tracing", 948 | "want", 949 | ] 950 | 951 | [[package]] 952 | name = "iana-time-zone" 953 | version = "0.1.56" 954 | source = "registry+https://github.com/rust-lang/crates.io-index" 955 | checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" 956 | dependencies = [ 957 | "android_system_properties", 958 | "core-foundation-sys", 959 | "iana-time-zone-haiku", 960 | "js-sys", 961 | "wasm-bindgen", 962 | "windows", 963 | ] 964 | 965 | [[package]] 966 | name = "iana-time-zone-haiku" 967 | version = "0.1.1" 968 | source = "registry+https://github.com/rust-lang/crates.io-index" 969 | checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" 970 | dependencies = [ 971 | "cxx", 972 | "cxx-build", 973 | ] 974 | 975 | [[package]] 976 | name = "ident_case" 977 | version = "1.0.1" 978 | source = "registry+https://github.com/rust-lang/crates.io-index" 979 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 980 | 981 | [[package]] 982 | name = "idna" 983 | version = "0.3.0" 984 | source = "registry+https://github.com/rust-lang/crates.io-index" 985 | checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" 986 | dependencies = [ 987 | "unicode-bidi", 988 | "unicode-normalization", 989 | ] 990 | 991 | [[package]] 992 | name = "indexmap" 993 | version = "1.9.3" 994 | source = "registry+https://github.com/rust-lang/crates.io-index" 995 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 996 | dependencies = [ 997 | "autocfg", 998 | "hashbrown 0.12.3", 999 | ] 1000 | 1001 | [[package]] 1002 | name = "inout" 1003 | version = "0.1.3" 1004 | source = "registry+https://github.com/rust-lang/crates.io-index" 1005 | checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" 1006 | dependencies = [ 1007 | "generic-array", 1008 | ] 1009 | 1010 | [[package]] 1011 | name = "instant" 1012 | version = "0.1.12" 1013 | source = "registry+https://github.com/rust-lang/crates.io-index" 1014 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 1015 | dependencies = [ 1016 | "cfg-if", 1017 | ] 1018 | 1019 | [[package]] 1020 | name = "io-lifetimes" 1021 | version = "1.0.10" 1022 | source = "registry+https://github.com/rust-lang/crates.io-index" 1023 | checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" 1024 | dependencies = [ 1025 | "hermit-abi 0.3.1", 1026 | "libc", 1027 | "windows-sys 0.48.0", 1028 | ] 1029 | 1030 | [[package]] 1031 | name = "itertools" 1032 | version = "0.10.5" 1033 | source = "registry+https://github.com/rust-lang/crates.io-index" 1034 | checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" 1035 | dependencies = [ 1036 | "either", 1037 | ] 1038 | 1039 | [[package]] 1040 | name = "itoa" 1041 | version = "1.0.6" 1042 | source = "registry+https://github.com/rust-lang/crates.io-index" 1043 | checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" 1044 | 1045 | [[package]] 1046 | name = "js-sys" 1047 | version = "0.3.64" 1048 | source = "registry+https://github.com/rust-lang/crates.io-index" 1049 | checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" 1050 | dependencies = [ 1051 | "wasm-bindgen", 1052 | ] 1053 | 1054 | [[package]] 1055 | name = "json5" 1056 | version = "0.4.1" 1057 | source = "registry+https://github.com/rust-lang/crates.io-index" 1058 | checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" 1059 | dependencies = [ 1060 | "pest", 1061 | "pest_derive", 1062 | "serde", 1063 | ] 1064 | 1065 | [[package]] 1066 | name = "lazy_static" 1067 | version = "1.4.0" 1068 | source = "registry+https://github.com/rust-lang/crates.io-index" 1069 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 1070 | 1071 | [[package]] 1072 | name = "libc" 1073 | version = "0.2.148" 1074 | source = "registry+https://github.com/rust-lang/crates.io-index" 1075 | checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" 1076 | 1077 | [[package]] 1078 | name = "link-cplusplus" 1079 | version = "1.0.8" 1080 | source = "registry+https://github.com/rust-lang/crates.io-index" 1081 | checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" 1082 | dependencies = [ 1083 | "cc", 1084 | ] 1085 | 1086 | [[package]] 1087 | name = "linked-hash-map" 1088 | version = "0.5.6" 1089 | source = "registry+https://github.com/rust-lang/crates.io-index" 1090 | checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" 1091 | 1092 | [[package]] 1093 | name = "linux-raw-sys" 1094 | version = "0.3.1" 1095 | source = "registry+https://github.com/rust-lang/crates.io-index" 1096 | checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" 1097 | 1098 | [[package]] 1099 | name = "lock_api" 1100 | version = "0.4.9" 1101 | source = "registry+https://github.com/rust-lang/crates.io-index" 1102 | checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" 1103 | dependencies = [ 1104 | "autocfg", 1105 | "scopeguard", 1106 | ] 1107 | 1108 | [[package]] 1109 | name = "log" 1110 | version = "0.4.19" 1111 | source = "registry+https://github.com/rust-lang/crates.io-index" 1112 | checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" 1113 | 1114 | [[package]] 1115 | name = "matchers" 1116 | version = "0.1.0" 1117 | source = "registry+https://github.com/rust-lang/crates.io-index" 1118 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" 1119 | dependencies = [ 1120 | "regex-automata", 1121 | ] 1122 | 1123 | [[package]] 1124 | name = "md-5" 1125 | version = "0.10.5" 1126 | source = "registry+https://github.com/rust-lang/crates.io-index" 1127 | checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" 1128 | dependencies = [ 1129 | "digest", 1130 | ] 1131 | 1132 | [[package]] 1133 | name = "memchr" 1134 | version = "2.5.0" 1135 | source = "registry+https://github.com/rust-lang/crates.io-index" 1136 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 1137 | 1138 | [[package]] 1139 | name = "mime" 1140 | version = "0.3.17" 1141 | source = "registry+https://github.com/rust-lang/crates.io-index" 1142 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 1143 | 1144 | [[package]] 1145 | name = "minimal-lexical" 1146 | version = "0.2.1" 1147 | source = "registry+https://github.com/rust-lang/crates.io-index" 1148 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 1149 | 1150 | [[package]] 1151 | name = "miniz_oxide" 1152 | version = "0.7.1" 1153 | source = "registry+https://github.com/rust-lang/crates.io-index" 1154 | checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" 1155 | dependencies = [ 1156 | "adler", 1157 | ] 1158 | 1159 | [[package]] 1160 | name = "mio" 1161 | version = "0.8.6" 1162 | source = "registry+https://github.com/rust-lang/crates.io-index" 1163 | checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" 1164 | dependencies = [ 1165 | "libc", 1166 | "log", 1167 | "wasi 0.11.0+wasi-snapshot-preview1", 1168 | "windows-sys 0.45.0", 1169 | ] 1170 | 1171 | [[package]] 1172 | name = "multer" 1173 | version = "2.1.0" 1174 | source = "registry+https://github.com/rust-lang/crates.io-index" 1175 | checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" 1176 | dependencies = [ 1177 | "bytes", 1178 | "encoding_rs", 1179 | "futures-util", 1180 | "http", 1181 | "httparse", 1182 | "log", 1183 | "memchr", 1184 | "mime", 1185 | "spin 0.9.8", 1186 | "tokio", 1187 | "version_check", 1188 | ] 1189 | 1190 | [[package]] 1191 | name = "nom" 1192 | version = "7.1.3" 1193 | source = "registry+https://github.com/rust-lang/crates.io-index" 1194 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 1195 | dependencies = [ 1196 | "memchr", 1197 | "minimal-lexical", 1198 | ] 1199 | 1200 | [[package]] 1201 | name = "nu-ansi-term" 1202 | version = "0.46.0" 1203 | source = "registry+https://github.com/rust-lang/crates.io-index" 1204 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" 1205 | dependencies = [ 1206 | "overload", 1207 | "winapi", 1208 | ] 1209 | 1210 | [[package]] 1211 | name = "num-bigint" 1212 | version = "0.4.3" 1213 | source = "registry+https://github.com/rust-lang/crates.io-index" 1214 | checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" 1215 | dependencies = [ 1216 | "autocfg", 1217 | "num-integer", 1218 | "num-traits", 1219 | ] 1220 | 1221 | [[package]] 1222 | name = "num-integer" 1223 | version = "0.1.45" 1224 | source = "registry+https://github.com/rust-lang/crates.io-index" 1225 | checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" 1226 | dependencies = [ 1227 | "autocfg", 1228 | "num-traits", 1229 | ] 1230 | 1231 | [[package]] 1232 | name = "num-traits" 1233 | version = "0.2.15" 1234 | source = "registry+https://github.com/rust-lang/crates.io-index" 1235 | checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" 1236 | dependencies = [ 1237 | "autocfg", 1238 | ] 1239 | 1240 | [[package]] 1241 | name = "num_cpus" 1242 | version = "1.15.0" 1243 | source = "registry+https://github.com/rust-lang/crates.io-index" 1244 | checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" 1245 | dependencies = [ 1246 | "hermit-abi 0.2.6", 1247 | "libc", 1248 | ] 1249 | 1250 | [[package]] 1251 | name = "object" 1252 | version = "0.32.1" 1253 | source = "registry+https://github.com/rust-lang/crates.io-index" 1254 | checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" 1255 | dependencies = [ 1256 | "memchr", 1257 | ] 1258 | 1259 | [[package]] 1260 | name = "once_cell" 1261 | version = "1.17.1" 1262 | source = "registry+https://github.com/rust-lang/crates.io-index" 1263 | checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" 1264 | 1265 | [[package]] 1266 | name = "opaque-debug" 1267 | version = "0.3.0" 1268 | source = "registry+https://github.com/rust-lang/crates.io-index" 1269 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 1270 | 1271 | [[package]] 1272 | name = "opentelemetry" 1273 | version = "0.20.0" 1274 | source = "registry+https://github.com/rust-lang/crates.io-index" 1275 | checksum = "9591d937bc0e6d2feb6f71a559540ab300ea49955229c347a517a28d27784c54" 1276 | dependencies = [ 1277 | "opentelemetry_api", 1278 | "opentelemetry_sdk", 1279 | ] 1280 | 1281 | [[package]] 1282 | name = "opentelemetry-prometheus" 1283 | version = "0.13.0" 1284 | source = "registry+https://github.com/rust-lang/crates.io-index" 1285 | checksum = "c7d81bc254e2d572120363a2b16cdb0d715d301b5789be0cfc26ad87e4e10e53" 1286 | dependencies = [ 1287 | "once_cell", 1288 | "opentelemetry_api", 1289 | "opentelemetry_sdk", 1290 | "prometheus", 1291 | "protobuf", 1292 | ] 1293 | 1294 | [[package]] 1295 | name = "opentelemetry_api" 1296 | version = "0.20.0" 1297 | source = "registry+https://github.com/rust-lang/crates.io-index" 1298 | checksum = "8a81f725323db1b1206ca3da8bb19874bbd3f57c3bcd59471bfb04525b265b9b" 1299 | dependencies = [ 1300 | "futures-channel", 1301 | "futures-util", 1302 | "indexmap", 1303 | "js-sys", 1304 | "once_cell", 1305 | "pin-project-lite", 1306 | "thiserror", 1307 | "urlencoding", 1308 | ] 1309 | 1310 | [[package]] 1311 | name = "opentelemetry_sdk" 1312 | version = "0.20.0" 1313 | source = "registry+https://github.com/rust-lang/crates.io-index" 1314 | checksum = "fa8e705a0612d48139799fcbaba0d4a90f06277153e43dd2bdc16c6f0edd8026" 1315 | dependencies = [ 1316 | "async-trait", 1317 | "crossbeam-channel", 1318 | "futures-channel", 1319 | "futures-executor", 1320 | "futures-util", 1321 | "once_cell", 1322 | "opentelemetry_api", 1323 | "ordered-float", 1324 | "percent-encoding", 1325 | "rand", 1326 | "regex", 1327 | "thiserror", 1328 | ] 1329 | 1330 | [[package]] 1331 | name = "ordered-float" 1332 | version = "3.9.1" 1333 | source = "registry+https://github.com/rust-lang/crates.io-index" 1334 | checksum = "2a54938017eacd63036332b4ae5c8a49fc8c0c1d6d629893057e4f13609edd06" 1335 | dependencies = [ 1336 | "num-traits", 1337 | ] 1338 | 1339 | [[package]] 1340 | name = "ordered-multimap" 1341 | version = "0.4.3" 1342 | source = "registry+https://github.com/rust-lang/crates.io-index" 1343 | checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" 1344 | dependencies = [ 1345 | "dlv-list", 1346 | "hashbrown 0.12.3", 1347 | ] 1348 | 1349 | [[package]] 1350 | name = "overload" 1351 | version = "0.1.1" 1352 | source = "registry+https://github.com/rust-lang/crates.io-index" 1353 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" 1354 | 1355 | [[package]] 1356 | name = "parking_lot" 1357 | version = "0.11.2" 1358 | source = "registry+https://github.com/rust-lang/crates.io-index" 1359 | checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" 1360 | dependencies = [ 1361 | "instant", 1362 | "lock_api", 1363 | "parking_lot_core 0.8.6", 1364 | ] 1365 | 1366 | [[package]] 1367 | name = "parking_lot" 1368 | version = "0.12.1" 1369 | source = "registry+https://github.com/rust-lang/crates.io-index" 1370 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 1371 | dependencies = [ 1372 | "lock_api", 1373 | "parking_lot_core 0.9.7", 1374 | ] 1375 | 1376 | [[package]] 1377 | name = "parking_lot_core" 1378 | version = "0.8.6" 1379 | source = "registry+https://github.com/rust-lang/crates.io-index" 1380 | checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" 1381 | dependencies = [ 1382 | "cfg-if", 1383 | "instant", 1384 | "libc", 1385 | "redox_syscall 0.2.16", 1386 | "smallvec", 1387 | "winapi", 1388 | ] 1389 | 1390 | [[package]] 1391 | name = "parking_lot_core" 1392 | version = "0.9.7" 1393 | source = "registry+https://github.com/rust-lang/crates.io-index" 1394 | checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" 1395 | dependencies = [ 1396 | "cfg-if", 1397 | "libc", 1398 | "redox_syscall 0.2.16", 1399 | "smallvec", 1400 | "windows-sys 0.45.0", 1401 | ] 1402 | 1403 | [[package]] 1404 | name = "paste" 1405 | version = "1.0.12" 1406 | source = "registry+https://github.com/rust-lang/crates.io-index" 1407 | checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" 1408 | 1409 | [[package]] 1410 | name = "pathdiff" 1411 | version = "0.2.1" 1412 | source = "registry+https://github.com/rust-lang/crates.io-index" 1413 | checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" 1414 | 1415 | [[package]] 1416 | name = "percent-encoding" 1417 | version = "2.2.0" 1418 | source = "registry+https://github.com/rust-lang/crates.io-index" 1419 | checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" 1420 | 1421 | [[package]] 1422 | name = "pest" 1423 | version = "2.5.7" 1424 | source = "registry+https://github.com/rust-lang/crates.io-index" 1425 | checksum = "7b1403e8401ad5dedea73c626b99758535b342502f8d1e361f4a2dd952749122" 1426 | dependencies = [ 1427 | "thiserror", 1428 | "ucd-trie", 1429 | ] 1430 | 1431 | [[package]] 1432 | name = "pest_derive" 1433 | version = "2.5.7" 1434 | source = "registry+https://github.com/rust-lang/crates.io-index" 1435 | checksum = "be99c4c1d2fc2769b1d00239431d711d08f6efedcecb8b6e30707160aee99c15" 1436 | dependencies = [ 1437 | "pest", 1438 | "pest_generator", 1439 | ] 1440 | 1441 | [[package]] 1442 | name = "pest_generator" 1443 | version = "2.5.7" 1444 | source = "registry+https://github.com/rust-lang/crates.io-index" 1445 | checksum = "e56094789873daa36164de2e822b3888c6ae4b4f9da555a1103587658c805b1e" 1446 | dependencies = [ 1447 | "pest", 1448 | "pest_meta", 1449 | "proc-macro2", 1450 | "quote", 1451 | "syn 2.0.13", 1452 | ] 1453 | 1454 | [[package]] 1455 | name = "pest_meta" 1456 | version = "2.5.7" 1457 | source = "registry+https://github.com/rust-lang/crates.io-index" 1458 | checksum = "6733073c7cff3d8459fda0e42f13a047870242aed8b509fe98000928975f359e" 1459 | dependencies = [ 1460 | "once_cell", 1461 | "pest", 1462 | "sha2", 1463 | ] 1464 | 1465 | [[package]] 1466 | name = "pin-project-lite" 1467 | version = "0.2.13" 1468 | source = "registry+https://github.com/rust-lang/crates.io-index" 1469 | checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" 1470 | 1471 | [[package]] 1472 | name = "pin-utils" 1473 | version = "0.1.0" 1474 | source = "registry+https://github.com/rust-lang/crates.io-index" 1475 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1476 | 1477 | [[package]] 1478 | name = "poem" 1479 | version = "1.3.58" 1480 | source = "registry+https://github.com/rust-lang/crates.io-index" 1481 | checksum = "ebc7ae19f3e791ae8108b08801abb3708d64d3a16490c720e0b81040cae87b5d" 1482 | dependencies = [ 1483 | "async-trait", 1484 | "bytes", 1485 | "chrono", 1486 | "cookie", 1487 | "futures-util", 1488 | "headers", 1489 | "http", 1490 | "hyper", 1491 | "mime", 1492 | "multer", 1493 | "opentelemetry", 1494 | "opentelemetry-prometheus", 1495 | "parking_lot 0.12.1", 1496 | "percent-encoding", 1497 | "pin-project-lite", 1498 | "poem-derive", 1499 | "prometheus", 1500 | "quick-xml 0.30.0", 1501 | "regex", 1502 | "rfc7239", 1503 | "serde", 1504 | "serde_json", 1505 | "serde_urlencoded", 1506 | "serde_yaml", 1507 | "smallvec", 1508 | "tempfile", 1509 | "thiserror", 1510 | "time 0.3.20", 1511 | "tokio", 1512 | "tokio-metrics", 1513 | "tokio-stream", 1514 | "tokio-util", 1515 | "tracing", 1516 | ] 1517 | 1518 | [[package]] 1519 | name = "poem-derive" 1520 | version = "1.3.58" 1521 | source = "registry+https://github.com/rust-lang/crates.io-index" 1522 | checksum = "2550a0bce7273b278894ef3ccc5a6869e7031b6870042f3cc6826ed9faa980a6" 1523 | dependencies = [ 1524 | "proc-macro-crate 1.3.1", 1525 | "proc-macro2", 1526 | "quote", 1527 | "syn 2.0.13", 1528 | ] 1529 | 1530 | [[package]] 1531 | name = "poem-openapi" 1532 | version = "2.0.27" 1533 | source = "registry+https://github.com/rust-lang/crates.io-index" 1534 | checksum = "3e26f78b6195ea1b7a16f46bda1961c598e5a66912f2aa1b8b7a2f395aebb9fc" 1535 | dependencies = [ 1536 | "base64 0.21.0", 1537 | "bytes", 1538 | "chrono", 1539 | "derive_more", 1540 | "futures-util", 1541 | "mime", 1542 | "num-traits", 1543 | "poem", 1544 | "poem-openapi-derive", 1545 | "quick-xml 0.26.0", 1546 | "regex", 1547 | "rust_decimal", 1548 | "serde", 1549 | "serde_json", 1550 | "serde_urlencoded", 1551 | "serde_yaml", 1552 | "thiserror", 1553 | "tokio", 1554 | ] 1555 | 1556 | [[package]] 1557 | name = "poem-openapi-derive" 1558 | version = "2.0.27" 1559 | source = "registry+https://github.com/rust-lang/crates.io-index" 1560 | checksum = "88c3e2975c930dc72c024e75b230c3b6058fb3a746d5739b83aa8f28ab1a42d4" 1561 | dependencies = [ 1562 | "darling", 1563 | "http", 1564 | "indexmap", 1565 | "mime", 1566 | "proc-macro-crate 1.3.1", 1567 | "proc-macro2", 1568 | "quote", 1569 | "regex", 1570 | "syn 1.0.109", 1571 | "thiserror", 1572 | ] 1573 | 1574 | [[package]] 1575 | name = "polyval" 1576 | version = "0.6.0" 1577 | source = "registry+https://github.com/rust-lang/crates.io-index" 1578 | checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6" 1579 | dependencies = [ 1580 | "cfg-if", 1581 | "cpufeatures", 1582 | "opaque-debug", 1583 | "universal-hash", 1584 | ] 1585 | 1586 | [[package]] 1587 | name = "ppv-lite86" 1588 | version = "0.2.17" 1589 | source = "registry+https://github.com/rust-lang/crates.io-index" 1590 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 1591 | 1592 | [[package]] 1593 | name = "proc-macro-crate" 1594 | version = "0.1.5" 1595 | source = "registry+https://github.com/rust-lang/crates.io-index" 1596 | checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" 1597 | dependencies = [ 1598 | "toml", 1599 | ] 1600 | 1601 | [[package]] 1602 | name = "proc-macro-crate" 1603 | version = "1.3.1" 1604 | source = "registry+https://github.com/rust-lang/crates.io-index" 1605 | checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" 1606 | dependencies = [ 1607 | "once_cell", 1608 | "toml_edit", 1609 | ] 1610 | 1611 | [[package]] 1612 | name = "proc-macro2" 1613 | version = "1.0.56" 1614 | source = "registry+https://github.com/rust-lang/crates.io-index" 1615 | checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" 1616 | dependencies = [ 1617 | "unicode-ident", 1618 | ] 1619 | 1620 | [[package]] 1621 | name = "prometheus" 1622 | version = "0.13.3" 1623 | source = "registry+https://github.com/rust-lang/crates.io-index" 1624 | checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" 1625 | dependencies = [ 1626 | "cfg-if", 1627 | "fnv", 1628 | "lazy_static", 1629 | "memchr", 1630 | "parking_lot 0.12.1", 1631 | "protobuf", 1632 | "thiserror", 1633 | ] 1634 | 1635 | [[package]] 1636 | name = "protobuf" 1637 | version = "2.28.0" 1638 | source = "registry+https://github.com/rust-lang/crates.io-index" 1639 | checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" 1640 | 1641 | [[package]] 1642 | name = "ptr_meta" 1643 | version = "0.1.4" 1644 | source = "registry+https://github.com/rust-lang/crates.io-index" 1645 | checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" 1646 | dependencies = [ 1647 | "ptr_meta_derive", 1648 | ] 1649 | 1650 | [[package]] 1651 | name = "ptr_meta_derive" 1652 | version = "0.1.4" 1653 | source = "registry+https://github.com/rust-lang/crates.io-index" 1654 | checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" 1655 | dependencies = [ 1656 | "proc-macro2", 1657 | "quote", 1658 | "syn 1.0.109", 1659 | ] 1660 | 1661 | [[package]] 1662 | name = "quick-xml" 1663 | version = "0.26.0" 1664 | source = "registry+https://github.com/rust-lang/crates.io-index" 1665 | checksum = "7f50b1c63b38611e7d4d7f68b82d3ad0cc71a2ad2e7f61fc10f1328d917c93cd" 1666 | dependencies = [ 1667 | "memchr", 1668 | "serde", 1669 | ] 1670 | 1671 | [[package]] 1672 | name = "quick-xml" 1673 | version = "0.30.0" 1674 | source = "registry+https://github.com/rust-lang/crates.io-index" 1675 | checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" 1676 | dependencies = [ 1677 | "memchr", 1678 | "serde", 1679 | ] 1680 | 1681 | [[package]] 1682 | name = "quote" 1683 | version = "1.0.26" 1684 | source = "registry+https://github.com/rust-lang/crates.io-index" 1685 | checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" 1686 | dependencies = [ 1687 | "proc-macro2", 1688 | ] 1689 | 1690 | [[package]] 1691 | name = "rand" 1692 | version = "0.8.5" 1693 | source = "registry+https://github.com/rust-lang/crates.io-index" 1694 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1695 | dependencies = [ 1696 | "libc", 1697 | "rand_chacha", 1698 | "rand_core", 1699 | ] 1700 | 1701 | [[package]] 1702 | name = "rand_chacha" 1703 | version = "0.3.1" 1704 | source = "registry+https://github.com/rust-lang/crates.io-index" 1705 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1706 | dependencies = [ 1707 | "ppv-lite86", 1708 | "rand_core", 1709 | ] 1710 | 1711 | [[package]] 1712 | name = "rand_core" 1713 | version = "0.6.4" 1714 | source = "registry+https://github.com/rust-lang/crates.io-index" 1715 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1716 | dependencies = [ 1717 | "getrandom", 1718 | ] 1719 | 1720 | [[package]] 1721 | name = "redox_syscall" 1722 | version = "0.2.16" 1723 | source = "registry+https://github.com/rust-lang/crates.io-index" 1724 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" 1725 | dependencies = [ 1726 | "bitflags", 1727 | ] 1728 | 1729 | [[package]] 1730 | name = "redox_syscall" 1731 | version = "0.3.5" 1732 | source = "registry+https://github.com/rust-lang/crates.io-index" 1733 | checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" 1734 | dependencies = [ 1735 | "bitflags", 1736 | ] 1737 | 1738 | [[package]] 1739 | name = "redox_users" 1740 | version = "0.4.3" 1741 | source = "registry+https://github.com/rust-lang/crates.io-index" 1742 | checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" 1743 | dependencies = [ 1744 | "getrandom", 1745 | "redox_syscall 0.2.16", 1746 | "thiserror", 1747 | ] 1748 | 1749 | [[package]] 1750 | name = "regex" 1751 | version = "1.7.3" 1752 | source = "registry+https://github.com/rust-lang/crates.io-index" 1753 | checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" 1754 | dependencies = [ 1755 | "aho-corasick", 1756 | "memchr", 1757 | "regex-syntax", 1758 | ] 1759 | 1760 | [[package]] 1761 | name = "regex-automata" 1762 | version = "0.1.10" 1763 | source = "registry+https://github.com/rust-lang/crates.io-index" 1764 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 1765 | dependencies = [ 1766 | "regex-syntax", 1767 | ] 1768 | 1769 | [[package]] 1770 | name = "regex-syntax" 1771 | version = "0.6.29" 1772 | source = "registry+https://github.com/rust-lang/crates.io-index" 1773 | checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" 1774 | 1775 | [[package]] 1776 | name = "rend" 1777 | version = "0.4.0" 1778 | source = "registry+https://github.com/rust-lang/crates.io-index" 1779 | checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" 1780 | dependencies = [ 1781 | "bytecheck", 1782 | ] 1783 | 1784 | [[package]] 1785 | name = "rfc7239" 1786 | version = "0.1.0" 1787 | source = "registry+https://github.com/rust-lang/crates.io-index" 1788 | checksum = "087317b3cf7eb481f13bd9025d729324b7cd068d6f470e2d76d049e191f5ba47" 1789 | dependencies = [ 1790 | "uncased", 1791 | ] 1792 | 1793 | [[package]] 1794 | name = "ring" 1795 | version = "0.16.20" 1796 | source = "registry+https://github.com/rust-lang/crates.io-index" 1797 | checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" 1798 | dependencies = [ 1799 | "cc", 1800 | "libc", 1801 | "once_cell", 1802 | "spin 0.5.2", 1803 | "untrusted", 1804 | "web-sys", 1805 | "winapi", 1806 | ] 1807 | 1808 | [[package]] 1809 | name = "rkyv" 1810 | version = "0.7.41" 1811 | source = "registry+https://github.com/rust-lang/crates.io-index" 1812 | checksum = "21499ed91807f07ae081880aabb2ccc0235e9d88011867d984525e9a4c3cfa3e" 1813 | dependencies = [ 1814 | "bytecheck", 1815 | "hashbrown 0.12.3", 1816 | "ptr_meta", 1817 | "rend", 1818 | "rkyv_derive", 1819 | "seahash", 1820 | ] 1821 | 1822 | [[package]] 1823 | name = "rkyv_derive" 1824 | version = "0.7.41" 1825 | source = "registry+https://github.com/rust-lang/crates.io-index" 1826 | checksum = "ac1c672430eb41556291981f45ca900a0239ad007242d1cb4b4167af842db666" 1827 | dependencies = [ 1828 | "proc-macro2", 1829 | "quote", 1830 | "syn 1.0.109", 1831 | ] 1832 | 1833 | [[package]] 1834 | name = "rollup_explorer" 1835 | version = "0.1.0" 1836 | dependencies = [ 1837 | "anyhow", 1838 | "chrono", 1839 | "config", 1840 | "dotenvy", 1841 | "futures", 1842 | "lazy_static", 1843 | "log", 1844 | "poem", 1845 | "poem-openapi", 1846 | "prometheus", 1847 | "rust_decimal", 1848 | "serde", 1849 | "serde_json", 1850 | "sqlx", 1851 | "tokio", 1852 | "tracing-subscriber", 1853 | ] 1854 | 1855 | [[package]] 1856 | name = "ron" 1857 | version = "0.7.1" 1858 | source = "registry+https://github.com/rust-lang/crates.io-index" 1859 | checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" 1860 | dependencies = [ 1861 | "base64 0.13.1", 1862 | "bitflags", 1863 | "serde", 1864 | ] 1865 | 1866 | [[package]] 1867 | name = "rust-ini" 1868 | version = "0.18.0" 1869 | source = "registry+https://github.com/rust-lang/crates.io-index" 1870 | checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" 1871 | dependencies = [ 1872 | "cfg-if", 1873 | "ordered-multimap", 1874 | ] 1875 | 1876 | [[package]] 1877 | name = "rust_decimal" 1878 | version = "1.30.0" 1879 | source = "registry+https://github.com/rust-lang/crates.io-index" 1880 | checksum = "d0446843641c69436765a35a5a77088e28c2e6a12da93e84aa3ab1cd4aa5a042" 1881 | dependencies = [ 1882 | "arrayvec", 1883 | "borsh", 1884 | "bytecheck", 1885 | "byteorder", 1886 | "bytes", 1887 | "num-traits", 1888 | "rand", 1889 | "rkyv", 1890 | "serde", 1891 | "serde_json", 1892 | ] 1893 | 1894 | [[package]] 1895 | name = "rustc-demangle" 1896 | version = "0.1.23" 1897 | source = "registry+https://github.com/rust-lang/crates.io-index" 1898 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 1899 | 1900 | [[package]] 1901 | name = "rustc_version" 1902 | version = "0.4.0" 1903 | source = "registry+https://github.com/rust-lang/crates.io-index" 1904 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 1905 | dependencies = [ 1906 | "semver", 1907 | ] 1908 | 1909 | [[package]] 1910 | name = "rustix" 1911 | version = "0.37.11" 1912 | source = "registry+https://github.com/rust-lang/crates.io-index" 1913 | checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77" 1914 | dependencies = [ 1915 | "bitflags", 1916 | "errno", 1917 | "io-lifetimes", 1918 | "libc", 1919 | "linux-raw-sys", 1920 | "windows-sys 0.48.0", 1921 | ] 1922 | 1923 | [[package]] 1924 | name = "rustls" 1925 | version = "0.20.8" 1926 | source = "registry+https://github.com/rust-lang/crates.io-index" 1927 | checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" 1928 | dependencies = [ 1929 | "log", 1930 | "ring", 1931 | "sct", 1932 | "webpki", 1933 | ] 1934 | 1935 | [[package]] 1936 | name = "rustls-pemfile" 1937 | version = "1.0.2" 1938 | source = "registry+https://github.com/rust-lang/crates.io-index" 1939 | checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" 1940 | dependencies = [ 1941 | "base64 0.21.0", 1942 | ] 1943 | 1944 | [[package]] 1945 | name = "ryu" 1946 | version = "1.0.13" 1947 | source = "registry+https://github.com/rust-lang/crates.io-index" 1948 | checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" 1949 | 1950 | [[package]] 1951 | name = "scopeguard" 1952 | version = "1.1.0" 1953 | source = "registry+https://github.com/rust-lang/crates.io-index" 1954 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1955 | 1956 | [[package]] 1957 | name = "scratch" 1958 | version = "1.0.5" 1959 | source = "registry+https://github.com/rust-lang/crates.io-index" 1960 | checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" 1961 | 1962 | [[package]] 1963 | name = "sct" 1964 | version = "0.7.0" 1965 | source = "registry+https://github.com/rust-lang/crates.io-index" 1966 | checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" 1967 | dependencies = [ 1968 | "ring", 1969 | "untrusted", 1970 | ] 1971 | 1972 | [[package]] 1973 | name = "seahash" 1974 | version = "4.1.0" 1975 | source = "registry+https://github.com/rust-lang/crates.io-index" 1976 | checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" 1977 | 1978 | [[package]] 1979 | name = "semver" 1980 | version = "1.0.17" 1981 | source = "registry+https://github.com/rust-lang/crates.io-index" 1982 | checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" 1983 | 1984 | [[package]] 1985 | name = "serde" 1986 | version = "1.0.164" 1987 | source = "registry+https://github.com/rust-lang/crates.io-index" 1988 | checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" 1989 | dependencies = [ 1990 | "serde_derive", 1991 | ] 1992 | 1993 | [[package]] 1994 | name = "serde_derive" 1995 | version = "1.0.164" 1996 | source = "registry+https://github.com/rust-lang/crates.io-index" 1997 | checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" 1998 | dependencies = [ 1999 | "proc-macro2", 2000 | "quote", 2001 | "syn 2.0.13", 2002 | ] 2003 | 2004 | [[package]] 2005 | name = "serde_json" 2006 | version = "1.0.99" 2007 | source = "registry+https://github.com/rust-lang/crates.io-index" 2008 | checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" 2009 | dependencies = [ 2010 | "itoa", 2011 | "ryu", 2012 | "serde", 2013 | ] 2014 | 2015 | [[package]] 2016 | name = "serde_urlencoded" 2017 | version = "0.7.1" 2018 | source = "registry+https://github.com/rust-lang/crates.io-index" 2019 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 2020 | dependencies = [ 2021 | "form_urlencoded", 2022 | "itoa", 2023 | "ryu", 2024 | "serde", 2025 | ] 2026 | 2027 | [[package]] 2028 | name = "serde_yaml" 2029 | version = "0.9.21" 2030 | source = "registry+https://github.com/rust-lang/crates.io-index" 2031 | checksum = "d9d684e3ec7de3bf5466b32bd75303ac16f0736426e5a4e0d6e489559ce1249c" 2032 | dependencies = [ 2033 | "indexmap", 2034 | "itoa", 2035 | "ryu", 2036 | "serde", 2037 | "unsafe-libyaml", 2038 | ] 2039 | 2040 | [[package]] 2041 | name = "sha1" 2042 | version = "0.10.5" 2043 | source = "registry+https://github.com/rust-lang/crates.io-index" 2044 | checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" 2045 | dependencies = [ 2046 | "cfg-if", 2047 | "cpufeatures", 2048 | "digest", 2049 | ] 2050 | 2051 | [[package]] 2052 | name = "sha2" 2053 | version = "0.10.6" 2054 | source = "registry+https://github.com/rust-lang/crates.io-index" 2055 | checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" 2056 | dependencies = [ 2057 | "cfg-if", 2058 | "cpufeatures", 2059 | "digest", 2060 | ] 2061 | 2062 | [[package]] 2063 | name = "sharded-slab" 2064 | version = "0.1.4" 2065 | source = "registry+https://github.com/rust-lang/crates.io-index" 2066 | checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" 2067 | dependencies = [ 2068 | "lazy_static", 2069 | ] 2070 | 2071 | [[package]] 2072 | name = "signal-hook-registry" 2073 | version = "1.4.1" 2074 | source = "registry+https://github.com/rust-lang/crates.io-index" 2075 | checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" 2076 | dependencies = [ 2077 | "libc", 2078 | ] 2079 | 2080 | [[package]] 2081 | name = "simdutf8" 2082 | version = "0.1.4" 2083 | source = "registry+https://github.com/rust-lang/crates.io-index" 2084 | checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" 2085 | 2086 | [[package]] 2087 | name = "slab" 2088 | version = "0.4.8" 2089 | source = "registry+https://github.com/rust-lang/crates.io-index" 2090 | checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" 2091 | dependencies = [ 2092 | "autocfg", 2093 | ] 2094 | 2095 | [[package]] 2096 | name = "smallvec" 2097 | version = "1.10.0" 2098 | source = "registry+https://github.com/rust-lang/crates.io-index" 2099 | checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" 2100 | 2101 | [[package]] 2102 | name = "socket2" 2103 | version = "0.4.9" 2104 | source = "registry+https://github.com/rust-lang/crates.io-index" 2105 | checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" 2106 | dependencies = [ 2107 | "libc", 2108 | "winapi", 2109 | ] 2110 | 2111 | [[package]] 2112 | name = "socket2" 2113 | version = "0.5.4" 2114 | source = "registry+https://github.com/rust-lang/crates.io-index" 2115 | checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" 2116 | dependencies = [ 2117 | "libc", 2118 | "windows-sys 0.48.0", 2119 | ] 2120 | 2121 | [[package]] 2122 | name = "spin" 2123 | version = "0.5.2" 2124 | source = "registry+https://github.com/rust-lang/crates.io-index" 2125 | checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" 2126 | 2127 | [[package]] 2128 | name = "spin" 2129 | version = "0.9.8" 2130 | source = "registry+https://github.com/rust-lang/crates.io-index" 2131 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 2132 | 2133 | [[package]] 2134 | name = "sqlformat" 2135 | version = "0.2.1" 2136 | source = "registry+https://github.com/rust-lang/crates.io-index" 2137 | checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e" 2138 | dependencies = [ 2139 | "itertools", 2140 | "nom", 2141 | "unicode_categories", 2142 | ] 2143 | 2144 | [[package]] 2145 | name = "sqlx" 2146 | version = "0.6.3" 2147 | source = "registry+https://github.com/rust-lang/crates.io-index" 2148 | checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188" 2149 | dependencies = [ 2150 | "sqlx-core", 2151 | "sqlx-macros", 2152 | ] 2153 | 2154 | [[package]] 2155 | name = "sqlx-core" 2156 | version = "0.6.3" 2157 | source = "registry+https://github.com/rust-lang/crates.io-index" 2158 | checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" 2159 | dependencies = [ 2160 | "ahash 0.7.6", 2161 | "atoi", 2162 | "base64 0.13.1", 2163 | "bitflags", 2164 | "byteorder", 2165 | "bytes", 2166 | "chrono", 2167 | "crc", 2168 | "crossbeam-queue", 2169 | "dirs", 2170 | "dotenvy", 2171 | "either", 2172 | "event-listener", 2173 | "futures-channel", 2174 | "futures-core", 2175 | "futures-intrusive", 2176 | "futures-util", 2177 | "hashlink", 2178 | "hex", 2179 | "hkdf", 2180 | "hmac", 2181 | "indexmap", 2182 | "itoa", 2183 | "libc", 2184 | "log", 2185 | "md-5", 2186 | "memchr", 2187 | "num-bigint", 2188 | "once_cell", 2189 | "paste", 2190 | "percent-encoding", 2191 | "rand", 2192 | "rust_decimal", 2193 | "rustls", 2194 | "rustls-pemfile", 2195 | "serde", 2196 | "serde_json", 2197 | "sha1", 2198 | "sha2", 2199 | "smallvec", 2200 | "sqlformat", 2201 | "sqlx-rt", 2202 | "stringprep", 2203 | "thiserror", 2204 | "tokio-stream", 2205 | "url", 2206 | "webpki-roots", 2207 | "whoami", 2208 | ] 2209 | 2210 | [[package]] 2211 | name = "sqlx-macros" 2212 | version = "0.6.3" 2213 | source = "registry+https://github.com/rust-lang/crates.io-index" 2214 | checksum = "9966e64ae989e7e575b19d7265cb79d7fc3cbbdf179835cb0d716f294c2049c9" 2215 | dependencies = [ 2216 | "dotenvy", 2217 | "either", 2218 | "heck", 2219 | "once_cell", 2220 | "proc-macro2", 2221 | "quote", 2222 | "sha2", 2223 | "sqlx-core", 2224 | "sqlx-rt", 2225 | "syn 1.0.109", 2226 | "url", 2227 | ] 2228 | 2229 | [[package]] 2230 | name = "sqlx-rt" 2231 | version = "0.6.3" 2232 | source = "registry+https://github.com/rust-lang/crates.io-index" 2233 | checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024" 2234 | dependencies = [ 2235 | "once_cell", 2236 | "tokio", 2237 | "tokio-rustls", 2238 | ] 2239 | 2240 | [[package]] 2241 | name = "stringprep" 2242 | version = "0.1.2" 2243 | source = "registry+https://github.com/rust-lang/crates.io-index" 2244 | checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" 2245 | dependencies = [ 2246 | "unicode-bidi", 2247 | "unicode-normalization", 2248 | ] 2249 | 2250 | [[package]] 2251 | name = "strsim" 2252 | version = "0.10.0" 2253 | source = "registry+https://github.com/rust-lang/crates.io-index" 2254 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 2255 | 2256 | [[package]] 2257 | name = "subtle" 2258 | version = "2.4.1" 2259 | source = "registry+https://github.com/rust-lang/crates.io-index" 2260 | checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" 2261 | 2262 | [[package]] 2263 | name = "syn" 2264 | version = "1.0.109" 2265 | source = "registry+https://github.com/rust-lang/crates.io-index" 2266 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 2267 | dependencies = [ 2268 | "proc-macro2", 2269 | "quote", 2270 | "unicode-ident", 2271 | ] 2272 | 2273 | [[package]] 2274 | name = "syn" 2275 | version = "2.0.13" 2276 | source = "registry+https://github.com/rust-lang/crates.io-index" 2277 | checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" 2278 | dependencies = [ 2279 | "proc-macro2", 2280 | "quote", 2281 | "unicode-ident", 2282 | ] 2283 | 2284 | [[package]] 2285 | name = "tempfile" 2286 | version = "3.5.0" 2287 | source = "registry+https://github.com/rust-lang/crates.io-index" 2288 | checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" 2289 | dependencies = [ 2290 | "cfg-if", 2291 | "fastrand", 2292 | "redox_syscall 0.3.5", 2293 | "rustix", 2294 | "windows-sys 0.45.0", 2295 | ] 2296 | 2297 | [[package]] 2298 | name = "termcolor" 2299 | version = "1.2.0" 2300 | source = "registry+https://github.com/rust-lang/crates.io-index" 2301 | checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" 2302 | dependencies = [ 2303 | "winapi-util", 2304 | ] 2305 | 2306 | [[package]] 2307 | name = "thiserror" 2308 | version = "1.0.40" 2309 | source = "registry+https://github.com/rust-lang/crates.io-index" 2310 | checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" 2311 | dependencies = [ 2312 | "thiserror-impl", 2313 | ] 2314 | 2315 | [[package]] 2316 | name = "thiserror-impl" 2317 | version = "1.0.40" 2318 | source = "registry+https://github.com/rust-lang/crates.io-index" 2319 | checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" 2320 | dependencies = [ 2321 | "proc-macro2", 2322 | "quote", 2323 | "syn 2.0.13", 2324 | ] 2325 | 2326 | [[package]] 2327 | name = "thread_local" 2328 | version = "1.1.7" 2329 | source = "registry+https://github.com/rust-lang/crates.io-index" 2330 | checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" 2331 | dependencies = [ 2332 | "cfg-if", 2333 | "once_cell", 2334 | ] 2335 | 2336 | [[package]] 2337 | name = "time" 2338 | version = "0.1.45" 2339 | source = "registry+https://github.com/rust-lang/crates.io-index" 2340 | checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" 2341 | dependencies = [ 2342 | "libc", 2343 | "wasi 0.10.0+wasi-snapshot-preview1", 2344 | "winapi", 2345 | ] 2346 | 2347 | [[package]] 2348 | name = "time" 2349 | version = "0.3.20" 2350 | source = "registry+https://github.com/rust-lang/crates.io-index" 2351 | checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" 2352 | dependencies = [ 2353 | "itoa", 2354 | "serde", 2355 | "time-core", 2356 | "time-macros", 2357 | ] 2358 | 2359 | [[package]] 2360 | name = "time-core" 2361 | version = "0.1.0" 2362 | source = "registry+https://github.com/rust-lang/crates.io-index" 2363 | checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" 2364 | 2365 | [[package]] 2366 | name = "time-macros" 2367 | version = "0.2.8" 2368 | source = "registry+https://github.com/rust-lang/crates.io-index" 2369 | checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" 2370 | dependencies = [ 2371 | "time-core", 2372 | ] 2373 | 2374 | [[package]] 2375 | name = "tinyvec" 2376 | version = "1.6.0" 2377 | source = "registry+https://github.com/rust-lang/crates.io-index" 2378 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 2379 | dependencies = [ 2380 | "tinyvec_macros", 2381 | ] 2382 | 2383 | [[package]] 2384 | name = "tinyvec_macros" 2385 | version = "0.1.1" 2386 | source = "registry+https://github.com/rust-lang/crates.io-index" 2387 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 2388 | 2389 | [[package]] 2390 | name = "tokio" 2391 | version = "1.32.0" 2392 | source = "registry+https://github.com/rust-lang/crates.io-index" 2393 | checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" 2394 | dependencies = [ 2395 | "backtrace", 2396 | "bytes", 2397 | "libc", 2398 | "mio", 2399 | "num_cpus", 2400 | "parking_lot 0.12.1", 2401 | "pin-project-lite", 2402 | "signal-hook-registry", 2403 | "socket2 0.5.4", 2404 | "tokio-macros", 2405 | "windows-sys 0.48.0", 2406 | ] 2407 | 2408 | [[package]] 2409 | name = "tokio-macros" 2410 | version = "2.1.0" 2411 | source = "registry+https://github.com/rust-lang/crates.io-index" 2412 | checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" 2413 | dependencies = [ 2414 | "proc-macro2", 2415 | "quote", 2416 | "syn 2.0.13", 2417 | ] 2418 | 2419 | [[package]] 2420 | name = "tokio-metrics" 2421 | version = "0.3.0" 2422 | source = "registry+https://github.com/rust-lang/crates.io-index" 2423 | checksum = "d4b2fc67d5dec41db679b9b052eb572269616926040b7831e32c8a152df77b84" 2424 | dependencies = [ 2425 | "futures-util", 2426 | "pin-project-lite", 2427 | "tokio", 2428 | "tokio-stream", 2429 | ] 2430 | 2431 | [[package]] 2432 | name = "tokio-rustls" 2433 | version = "0.23.4" 2434 | source = "registry+https://github.com/rust-lang/crates.io-index" 2435 | checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" 2436 | dependencies = [ 2437 | "rustls", 2438 | "tokio", 2439 | "webpki", 2440 | ] 2441 | 2442 | [[package]] 2443 | name = "tokio-stream" 2444 | version = "0.1.12" 2445 | source = "registry+https://github.com/rust-lang/crates.io-index" 2446 | checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313" 2447 | dependencies = [ 2448 | "futures-core", 2449 | "pin-project-lite", 2450 | "tokio", 2451 | ] 2452 | 2453 | [[package]] 2454 | name = "tokio-util" 2455 | version = "0.7.7" 2456 | source = "registry+https://github.com/rust-lang/crates.io-index" 2457 | checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" 2458 | dependencies = [ 2459 | "bytes", 2460 | "futures-core", 2461 | "futures-sink", 2462 | "pin-project-lite", 2463 | "tokio", 2464 | "tracing", 2465 | ] 2466 | 2467 | [[package]] 2468 | name = "toml" 2469 | version = "0.5.11" 2470 | source = "registry+https://github.com/rust-lang/crates.io-index" 2471 | checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" 2472 | dependencies = [ 2473 | "serde", 2474 | ] 2475 | 2476 | [[package]] 2477 | name = "toml_datetime" 2478 | version = "0.6.1" 2479 | source = "registry+https://github.com/rust-lang/crates.io-index" 2480 | checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" 2481 | 2482 | [[package]] 2483 | name = "toml_edit" 2484 | version = "0.19.8" 2485 | source = "registry+https://github.com/rust-lang/crates.io-index" 2486 | checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" 2487 | dependencies = [ 2488 | "indexmap", 2489 | "toml_datetime", 2490 | "winnow", 2491 | ] 2492 | 2493 | [[package]] 2494 | name = "tower-service" 2495 | version = "0.3.2" 2496 | source = "registry+https://github.com/rust-lang/crates.io-index" 2497 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 2498 | 2499 | [[package]] 2500 | name = "tracing" 2501 | version = "0.1.37" 2502 | source = "registry+https://github.com/rust-lang/crates.io-index" 2503 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 2504 | dependencies = [ 2505 | "cfg-if", 2506 | "pin-project-lite", 2507 | "tracing-attributes", 2508 | "tracing-core", 2509 | ] 2510 | 2511 | [[package]] 2512 | name = "tracing-attributes" 2513 | version = "0.1.23" 2514 | source = "registry+https://github.com/rust-lang/crates.io-index" 2515 | checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" 2516 | dependencies = [ 2517 | "proc-macro2", 2518 | "quote", 2519 | "syn 1.0.109", 2520 | ] 2521 | 2522 | [[package]] 2523 | name = "tracing-core" 2524 | version = "0.1.30" 2525 | source = "registry+https://github.com/rust-lang/crates.io-index" 2526 | checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" 2527 | dependencies = [ 2528 | "once_cell", 2529 | "valuable", 2530 | ] 2531 | 2532 | [[package]] 2533 | name = "tracing-log" 2534 | version = "0.1.3" 2535 | source = "registry+https://github.com/rust-lang/crates.io-index" 2536 | checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" 2537 | dependencies = [ 2538 | "lazy_static", 2539 | "log", 2540 | "tracing-core", 2541 | ] 2542 | 2543 | [[package]] 2544 | name = "tracing-subscriber" 2545 | version = "0.3.17" 2546 | source = "registry+https://github.com/rust-lang/crates.io-index" 2547 | checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" 2548 | dependencies = [ 2549 | "matchers", 2550 | "nu-ansi-term", 2551 | "once_cell", 2552 | "regex", 2553 | "sharded-slab", 2554 | "smallvec", 2555 | "thread_local", 2556 | "tracing", 2557 | "tracing-core", 2558 | "tracing-log", 2559 | ] 2560 | 2561 | [[package]] 2562 | name = "try-lock" 2563 | version = "0.2.4" 2564 | source = "registry+https://github.com/rust-lang/crates.io-index" 2565 | checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" 2566 | 2567 | [[package]] 2568 | name = "typenum" 2569 | version = "1.16.0" 2570 | source = "registry+https://github.com/rust-lang/crates.io-index" 2571 | checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" 2572 | 2573 | [[package]] 2574 | name = "ucd-trie" 2575 | version = "0.1.5" 2576 | source = "registry+https://github.com/rust-lang/crates.io-index" 2577 | checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" 2578 | 2579 | [[package]] 2580 | name = "uncased" 2581 | version = "0.9.7" 2582 | source = "registry+https://github.com/rust-lang/crates.io-index" 2583 | checksum = "09b01702b0fd0b3fadcf98e098780badda8742d4f4a7676615cad90e8ac73622" 2584 | dependencies = [ 2585 | "version_check", 2586 | ] 2587 | 2588 | [[package]] 2589 | name = "unicode-bidi" 2590 | version = "0.3.13" 2591 | source = "registry+https://github.com/rust-lang/crates.io-index" 2592 | checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" 2593 | 2594 | [[package]] 2595 | name = "unicode-ident" 2596 | version = "1.0.8" 2597 | source = "registry+https://github.com/rust-lang/crates.io-index" 2598 | checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" 2599 | 2600 | [[package]] 2601 | name = "unicode-normalization" 2602 | version = "0.1.22" 2603 | source = "registry+https://github.com/rust-lang/crates.io-index" 2604 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 2605 | dependencies = [ 2606 | "tinyvec", 2607 | ] 2608 | 2609 | [[package]] 2610 | name = "unicode-segmentation" 2611 | version = "1.10.1" 2612 | source = "registry+https://github.com/rust-lang/crates.io-index" 2613 | checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" 2614 | 2615 | [[package]] 2616 | name = "unicode-width" 2617 | version = "0.1.10" 2618 | source = "registry+https://github.com/rust-lang/crates.io-index" 2619 | checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" 2620 | 2621 | [[package]] 2622 | name = "unicode_categories" 2623 | version = "0.1.1" 2624 | source = "registry+https://github.com/rust-lang/crates.io-index" 2625 | checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" 2626 | 2627 | [[package]] 2628 | name = "universal-hash" 2629 | version = "0.5.0" 2630 | source = "registry+https://github.com/rust-lang/crates.io-index" 2631 | checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" 2632 | dependencies = [ 2633 | "crypto-common", 2634 | "subtle", 2635 | ] 2636 | 2637 | [[package]] 2638 | name = "unsafe-libyaml" 2639 | version = "0.2.8" 2640 | source = "registry+https://github.com/rust-lang/crates.io-index" 2641 | checksum = "1865806a559042e51ab5414598446a5871b561d21b6764f2eabb0dd481d880a6" 2642 | 2643 | [[package]] 2644 | name = "untrusted" 2645 | version = "0.7.1" 2646 | source = "registry+https://github.com/rust-lang/crates.io-index" 2647 | checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" 2648 | 2649 | [[package]] 2650 | name = "url" 2651 | version = "2.3.1" 2652 | source = "registry+https://github.com/rust-lang/crates.io-index" 2653 | checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" 2654 | dependencies = [ 2655 | "form_urlencoded", 2656 | "idna", 2657 | "percent-encoding", 2658 | ] 2659 | 2660 | [[package]] 2661 | name = "urlencoding" 2662 | version = "2.1.3" 2663 | source = "registry+https://github.com/rust-lang/crates.io-index" 2664 | checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" 2665 | 2666 | [[package]] 2667 | name = "valuable" 2668 | version = "0.1.0" 2669 | source = "registry+https://github.com/rust-lang/crates.io-index" 2670 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 2671 | 2672 | [[package]] 2673 | name = "version_check" 2674 | version = "0.9.4" 2675 | source = "registry+https://github.com/rust-lang/crates.io-index" 2676 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 2677 | 2678 | [[package]] 2679 | name = "want" 2680 | version = "0.3.0" 2681 | source = "registry+https://github.com/rust-lang/crates.io-index" 2682 | checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" 2683 | dependencies = [ 2684 | "log", 2685 | "try-lock", 2686 | ] 2687 | 2688 | [[package]] 2689 | name = "wasi" 2690 | version = "0.10.0+wasi-snapshot-preview1" 2691 | source = "registry+https://github.com/rust-lang/crates.io-index" 2692 | checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" 2693 | 2694 | [[package]] 2695 | name = "wasi" 2696 | version = "0.11.0+wasi-snapshot-preview1" 2697 | source = "registry+https://github.com/rust-lang/crates.io-index" 2698 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2699 | 2700 | [[package]] 2701 | name = "wasm-bindgen" 2702 | version = "0.2.87" 2703 | source = "registry+https://github.com/rust-lang/crates.io-index" 2704 | checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" 2705 | dependencies = [ 2706 | "cfg-if", 2707 | "wasm-bindgen-macro", 2708 | ] 2709 | 2710 | [[package]] 2711 | name = "wasm-bindgen-backend" 2712 | version = "0.2.87" 2713 | source = "registry+https://github.com/rust-lang/crates.io-index" 2714 | checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" 2715 | dependencies = [ 2716 | "bumpalo", 2717 | "log", 2718 | "once_cell", 2719 | "proc-macro2", 2720 | "quote", 2721 | "syn 2.0.13", 2722 | "wasm-bindgen-shared", 2723 | ] 2724 | 2725 | [[package]] 2726 | name = "wasm-bindgen-macro" 2727 | version = "0.2.87" 2728 | source = "registry+https://github.com/rust-lang/crates.io-index" 2729 | checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" 2730 | dependencies = [ 2731 | "quote", 2732 | "wasm-bindgen-macro-support", 2733 | ] 2734 | 2735 | [[package]] 2736 | name = "wasm-bindgen-macro-support" 2737 | version = "0.2.87" 2738 | source = "registry+https://github.com/rust-lang/crates.io-index" 2739 | checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" 2740 | dependencies = [ 2741 | "proc-macro2", 2742 | "quote", 2743 | "syn 2.0.13", 2744 | "wasm-bindgen-backend", 2745 | "wasm-bindgen-shared", 2746 | ] 2747 | 2748 | [[package]] 2749 | name = "wasm-bindgen-shared" 2750 | version = "0.2.87" 2751 | source = "registry+https://github.com/rust-lang/crates.io-index" 2752 | checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" 2753 | 2754 | [[package]] 2755 | name = "web-sys" 2756 | version = "0.3.61" 2757 | source = "registry+https://github.com/rust-lang/crates.io-index" 2758 | checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" 2759 | dependencies = [ 2760 | "js-sys", 2761 | "wasm-bindgen", 2762 | ] 2763 | 2764 | [[package]] 2765 | name = "webpki" 2766 | version = "0.22.0" 2767 | source = "registry+https://github.com/rust-lang/crates.io-index" 2768 | checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" 2769 | dependencies = [ 2770 | "ring", 2771 | "untrusted", 2772 | ] 2773 | 2774 | [[package]] 2775 | name = "webpki-roots" 2776 | version = "0.22.6" 2777 | source = "registry+https://github.com/rust-lang/crates.io-index" 2778 | checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" 2779 | dependencies = [ 2780 | "webpki", 2781 | ] 2782 | 2783 | [[package]] 2784 | name = "whoami" 2785 | version = "1.4.0" 2786 | source = "registry+https://github.com/rust-lang/crates.io-index" 2787 | checksum = "2c70234412ca409cc04e864e89523cb0fc37f5e1344ebed5a3ebf4192b6b9f68" 2788 | dependencies = [ 2789 | "wasm-bindgen", 2790 | "web-sys", 2791 | ] 2792 | 2793 | [[package]] 2794 | name = "winapi" 2795 | version = "0.3.9" 2796 | source = "registry+https://github.com/rust-lang/crates.io-index" 2797 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2798 | dependencies = [ 2799 | "winapi-i686-pc-windows-gnu", 2800 | "winapi-x86_64-pc-windows-gnu", 2801 | ] 2802 | 2803 | [[package]] 2804 | name = "winapi-i686-pc-windows-gnu" 2805 | version = "0.4.0" 2806 | source = "registry+https://github.com/rust-lang/crates.io-index" 2807 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2808 | 2809 | [[package]] 2810 | name = "winapi-util" 2811 | version = "0.1.5" 2812 | source = "registry+https://github.com/rust-lang/crates.io-index" 2813 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 2814 | dependencies = [ 2815 | "winapi", 2816 | ] 2817 | 2818 | [[package]] 2819 | name = "winapi-x86_64-pc-windows-gnu" 2820 | version = "0.4.0" 2821 | source = "registry+https://github.com/rust-lang/crates.io-index" 2822 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2823 | 2824 | [[package]] 2825 | name = "windows" 2826 | version = "0.48.0" 2827 | source = "registry+https://github.com/rust-lang/crates.io-index" 2828 | checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" 2829 | dependencies = [ 2830 | "windows-targets 0.48.0", 2831 | ] 2832 | 2833 | [[package]] 2834 | name = "windows-sys" 2835 | version = "0.45.0" 2836 | source = "registry+https://github.com/rust-lang/crates.io-index" 2837 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 2838 | dependencies = [ 2839 | "windows-targets 0.42.2", 2840 | ] 2841 | 2842 | [[package]] 2843 | name = "windows-sys" 2844 | version = "0.48.0" 2845 | source = "registry+https://github.com/rust-lang/crates.io-index" 2846 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 2847 | dependencies = [ 2848 | "windows-targets 0.48.0", 2849 | ] 2850 | 2851 | [[package]] 2852 | name = "windows-targets" 2853 | version = "0.42.2" 2854 | source = "registry+https://github.com/rust-lang/crates.io-index" 2855 | checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 2856 | dependencies = [ 2857 | "windows_aarch64_gnullvm 0.42.2", 2858 | "windows_aarch64_msvc 0.42.2", 2859 | "windows_i686_gnu 0.42.2", 2860 | "windows_i686_msvc 0.42.2", 2861 | "windows_x86_64_gnu 0.42.2", 2862 | "windows_x86_64_gnullvm 0.42.2", 2863 | "windows_x86_64_msvc 0.42.2", 2864 | ] 2865 | 2866 | [[package]] 2867 | name = "windows-targets" 2868 | version = "0.48.0" 2869 | source = "registry+https://github.com/rust-lang/crates.io-index" 2870 | checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" 2871 | dependencies = [ 2872 | "windows_aarch64_gnullvm 0.48.0", 2873 | "windows_aarch64_msvc 0.48.0", 2874 | "windows_i686_gnu 0.48.0", 2875 | "windows_i686_msvc 0.48.0", 2876 | "windows_x86_64_gnu 0.48.0", 2877 | "windows_x86_64_gnullvm 0.48.0", 2878 | "windows_x86_64_msvc 0.48.0", 2879 | ] 2880 | 2881 | [[package]] 2882 | name = "windows_aarch64_gnullvm" 2883 | version = "0.42.2" 2884 | source = "registry+https://github.com/rust-lang/crates.io-index" 2885 | checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" 2886 | 2887 | [[package]] 2888 | name = "windows_aarch64_gnullvm" 2889 | version = "0.48.0" 2890 | source = "registry+https://github.com/rust-lang/crates.io-index" 2891 | checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" 2892 | 2893 | [[package]] 2894 | name = "windows_aarch64_msvc" 2895 | version = "0.42.2" 2896 | source = "registry+https://github.com/rust-lang/crates.io-index" 2897 | checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" 2898 | 2899 | [[package]] 2900 | name = "windows_aarch64_msvc" 2901 | version = "0.48.0" 2902 | source = "registry+https://github.com/rust-lang/crates.io-index" 2903 | checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" 2904 | 2905 | [[package]] 2906 | name = "windows_i686_gnu" 2907 | version = "0.42.2" 2908 | source = "registry+https://github.com/rust-lang/crates.io-index" 2909 | checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" 2910 | 2911 | [[package]] 2912 | name = "windows_i686_gnu" 2913 | version = "0.48.0" 2914 | source = "registry+https://github.com/rust-lang/crates.io-index" 2915 | checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" 2916 | 2917 | [[package]] 2918 | name = "windows_i686_msvc" 2919 | version = "0.42.2" 2920 | source = "registry+https://github.com/rust-lang/crates.io-index" 2921 | checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" 2922 | 2923 | [[package]] 2924 | name = "windows_i686_msvc" 2925 | version = "0.48.0" 2926 | source = "registry+https://github.com/rust-lang/crates.io-index" 2927 | checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" 2928 | 2929 | [[package]] 2930 | name = "windows_x86_64_gnu" 2931 | version = "0.42.2" 2932 | source = "registry+https://github.com/rust-lang/crates.io-index" 2933 | checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 2934 | 2935 | [[package]] 2936 | name = "windows_x86_64_gnu" 2937 | version = "0.48.0" 2938 | source = "registry+https://github.com/rust-lang/crates.io-index" 2939 | checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" 2940 | 2941 | [[package]] 2942 | name = "windows_x86_64_gnullvm" 2943 | version = "0.42.2" 2944 | source = "registry+https://github.com/rust-lang/crates.io-index" 2945 | checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 2946 | 2947 | [[package]] 2948 | name = "windows_x86_64_gnullvm" 2949 | version = "0.48.0" 2950 | source = "registry+https://github.com/rust-lang/crates.io-index" 2951 | checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" 2952 | 2953 | [[package]] 2954 | name = "windows_x86_64_msvc" 2955 | version = "0.42.2" 2956 | source = "registry+https://github.com/rust-lang/crates.io-index" 2957 | checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 2958 | 2959 | [[package]] 2960 | name = "windows_x86_64_msvc" 2961 | version = "0.48.0" 2962 | source = "registry+https://github.com/rust-lang/crates.io-index" 2963 | checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" 2964 | 2965 | [[package]] 2966 | name = "winnow" 2967 | version = "0.4.1" 2968 | source = "registry+https://github.com/rust-lang/crates.io-index" 2969 | checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" 2970 | dependencies = [ 2971 | "memchr", 2972 | ] 2973 | 2974 | [[package]] 2975 | name = "yaml-rust" 2976 | version = "0.4.5" 2977 | source = "registry+https://github.com/rust-lang/crates.io-index" 2978 | checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" 2979 | dependencies = [ 2980 | "linked-hash-map", 2981 | ] 2982 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rollup_explorer" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [[bin]] 7 | name = "rollup_explorer" 8 | path = "src/bin/main.rs" 9 | 10 | [dependencies] 11 | anyhow = "1.0" 12 | chrono = { version = "0.4", features = [ "serde" ] } 13 | config = "0.13" 14 | dotenvy = "0.15" 15 | futures = "0.3" 16 | lazy_static = "1.4" 17 | log = "0.4" 18 | poem = { version = "1.3", features = ["prometheus", "tokio-metrics"] } 19 | poem-openapi = { version = "2.0", features = ["chrono", "rust_decimal", "swagger-ui"]} 20 | prometheus = "0.13" 21 | rust_decimal = "1.29" 22 | serde = { version = "1.0", features = [ "derive" ] } 23 | serde_json = { version = "1.0" } 24 | sqlx = { version = "0.6", features = [ "chrono", "decimal", "postgres", "runtime-tokio-rustls" ] } 25 | tokio = { version = "1", features = ["full"] } 26 | tracing-subscriber = { version ="0.3", features = ["env-filter"] } 27 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Build 2 | 3 | FROM scrolltech/rust-alpine-builder:nightly-2022-08-23 AS chef 4 | WORKDIR app 5 | 6 | FROM chef AS planner 7 | RUN --mount=target=. \ 8 | cargo chef prepare --recipe-path /recipe.json 9 | 10 | FROM chef AS builder 11 | COPY --from=planner /recipe.json recipe.json 12 | RUN cargo chef cook --release --recipe-path recipe.json 13 | RUN --mount=target=. \ 14 | cargo build --release --target-dir=/app-target 15 | 16 | # Release 17 | 18 | FROM alpine:3.15 19 | 20 | WORKDIR /app 21 | 22 | RUN apk update && apk add vim netcat-openbsd net-tools curl 23 | 24 | COPY --from=builder /app-target/release/rollup_explorer /bin/ 25 | 26 | ENTRYPOINT ["rollup_explorer"] 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Scroll 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: docker 2 | 3 | docker: 4 | docker compose -f docker-compose.yml build 5 | 6 | import_mock_data: 7 | ./scripts/import_mock_data.sh 8 | 9 | lint: 10 | cargo fmt --all && cargo clippy -- -D warnings 11 | shfmt -i 2 -sr -w scripts/*.sh 12 | 13 | login_db: 14 | psql postgres://postgres:scroll2022@localhost:5434/scroll 15 | 16 | start: 17 | ./scripts/stop.sh 18 | ./scripts/start.sh 19 | 20 | stop: 21 | ./scripts/stop.sh 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Scroll's Rollup Explorer Backend 2 | 3 | [![Main Test Status][test-image]][test-link] 4 | [![Audit Status][audit-image]][audit-link] 5 | ![Rust Nightly][rustc-image] 6 | 7 | ## Purpose 8 | 9 | This repo contains the backend code for the [Rollup Explorer](https://scroll.io/rollupscan) that's currently maintained by Scroll. 10 | 11 | ## License 12 | 13 | MIT. 14 | 15 | ## Contributing 16 | 17 | If you encounter bugs or have feature ideas, feel free to [create an issue](/../../issues) or [write a PR](/../../pulls). 18 | 19 | ## Prerequisites 20 | 21 | Naturally, you will need the [Rust toolchain] installed. 22 | Besides that, [goose] is necessary for external database migrations in `database` dictionary of [scroll]. 23 | 24 | ## ENV 25 | 26 | - `BIND_PORT`: Internal binding HTTP port (`5001` as default). 27 | - `DB_URL`: The database URL used to connect. 28 | - `OPEN_API_ADDR`: Open API URL displayed on Web UI. 29 | - `MAX_PER_PAGE`: Max value of query parameter `per_page` (100 as default) 30 | 31 | ## Development 32 | 33 | - `make start`: Start a local `Postgres` docker-container, and `cargo run --bin rollup_explorer`. Then URL `http://0.0.0.0:5001` could be accessed in a Web browser. 34 | 35 | - `make stop`: Stop running `rollup_explorer` processes and `Postgres` docker-container. The `Postgres` data should also be cleared via deleting folder `docker-data`. 36 | 37 | - `make lint`: Format and lint codes. 38 | 39 | - `make shfmt`: Format Shell scripts. 40 | 41 | ## Adding Mock Data 42 | 43 | Run the following: 44 | 45 | `psql postgres://postgres:scroll2022@localhost:5434/scroll -f db/tests/test.sql` 46 | 47 | ## Deployment 48 | 49 | Currently deployed by Scroll's devops and used by https://scroll.io/rollupscan. 50 | 51 | [//]: # "badges" 52 | [Rust toolchain]: https://rustup.rs 53 | [audit-image]: https://github.com/scroll-tech/rollup-explorer-backend/actions/workflows/audit.yml/badge.svg 54 | [audit-link]: https://github.com/scroll-tech/rollup-explorer-backend/actions/workflows/audit.yml 55 | [goose]: https://github.com/pressly/goose 56 | [rustc-image]: https://img.shields.io/badge/rustc-nightly-blue.svg 57 | [scroll]: https://github.com/scroll-tech/scroll 58 | [test-image]: https://github.com/scroll-tech/rollup-explorer-backend/actions/workflows/test.yml/badge.svg 59 | [test-link]: https://github.com/scroll-tech/rollup-explorer-backend/actions/workflows/test.yml 60 | -------------------------------------------------------------------------------- /config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "bind_port": "8560", 3 | "metrics_bind_port": "19130", 4 | "db_url" : "127.0.0.1:8080", 5 | "open_api_addr" : "/rollupscan", 6 | "max_per_page": 500 7 | } -------------------------------------------------------------------------------- /db/tests/test.sql: -------------------------------------------------------------------------------- 1 | delete from batch; 2 | delete from chunk; 3 | delete from l2_block; 4 | 5 | /* batch */ 6 | 7 | INSERT INTO batch values ( 8 | 4, 9 | 'batch-4', 10 | 6, 11 | 'chunk-6', 12 | 6, 13 | 'chunk-6', 14 | 'batch-state-root-4', 15 | 'batch-withdraw-root-4', 16 | '', 17 | 1, 18 | 1, 19 | NULL, 20 | NULL, 21 | NULL, 22 | NULL, 23 | 5, 24 | '0x52dd8c4568daa7df8a5fbffe7cba4def97409ab2bfec47a4b66c140d1fb61162', 25 | CURRENT_TIMESTAMP, 26 | '0x1911710df1000a7bee02fb340ae906804c7f778bd145fea1710b76c1a3103965', 27 | CURRENT_TIMESTAMP 28 | ) ON CONFLICT DO NOTHING; 29 | 30 | INSERT INTO batch values ( 31 | 3, 32 | 'batch-3', 33 | 5, 34 | 'chunk-5', 35 | 5, 36 | 'chunk-5', 37 | 'batch-state-root-3', 38 | 'batch-withdraw-root-3', 39 | '', 40 | 1, 41 | 1, 42 | NULL, 43 | NULL, 44 | NULL, 45 | NULL, 46 | 4, 47 | '0xf60e145b7eecab24830224dda3770e7f284b6f4f8d750f4a1595402906af699f', 48 | CURRENT_TIMESTAMP, 49 | '0xa9dd95aee224402d4abaeac142337450afe897299927b9336d5785e8c6133587', 50 | CURRENT_TIMESTAMP 51 | ) ON CONFLICT DO NOTHING; 52 | 53 | INSERT INTO batch values ( 54 | 2, 55 | 'batch-2', 56 | 3, 57 | 'chunk-3', 58 | 4, 59 | 'chunk-4', 60 | 'batch-state-root-2', 61 | 'batch-withdraw-root-2', 62 | '', 63 | 1, 64 | 1, 65 | NULL, 66 | NULL, 67 | NULL, 68 | NULL, 69 | 3, 70 | '0x7077c274526c182ebb304f7e904d7547e7557083283d22334e2b827732adc227', 71 | CURRENT_TIMESTAMP, 72 | '0xaa096608f4144b225fe1c0fe8867f0a6e52e428454648674dcb16c5ac8c0a72a', 73 | CURRENT_TIMESTAMP 74 | ) ON CONFLICT DO NOTHING; 75 | 76 | INSERT INTO batch values ( 77 | 1, 78 | 'batch-1', 79 | 1, 80 | 'chunk-1', 81 | 2, 82 | 'chunk-2', 83 | 'batch-state-root-1', 84 | 'batch-withdraw-root-1', 85 | '', 86 | 1, 87 | 1, 88 | NULL, 89 | NULL, 90 | NULL, 91 | NULL, 92 | 2, 93 | '0xb2c4670936ebfb12fcf7c390bcf1040a381f4f992b13d7d32879d756d54a8627', 94 | CURRENT_TIMESTAMP, 95 | '0x98d7c2dee6fa1cf200262a22882df35ae55e3cf78ecd554fce1d12ea12c1552c', 96 | CURRENT_TIMESTAMP 97 | ) ON CONFLICT DO NOTHING; 98 | 99 | /* chunk */ 100 | 101 | INSERT INTO chunk values ( 102 | 6, 103 | 'chunk-6', 104 | 10, 105 | 'block-10', 106 | 10, 107 | 'block-10', 108 | 6, 109 | 6, 110 | 6, 111 | 1, 112 | NULL, 113 | NULL, 114 | NULL, 115 | NULL, 116 | 'batch-4', 117 | 6, 118 | 6, 119 | 6, 120 | 6 121 | ) ON CONFLICT DO NOTHING; 122 | 123 | INSERT INTO chunk values ( 124 | 5, 125 | 'chunk-5', 126 | 9, 127 | 'block-9', 128 | 9, 129 | 'block-9', 130 | 5, 131 | 5, 132 | 5, 133 | 1, 134 | NULL, 135 | NULL, 136 | NULL, 137 | NULL, 138 | 'batch-3', 139 | 5, 140 | 5, 141 | 5, 142 | 5 143 | ) ON CONFLICT DO NOTHING; 144 | 145 | INSERT INTO chunk values ( 146 | 4, 147 | 'chunk-4', 148 | 7, 149 | 'block-7', 150 | 8, 151 | 'block-8', 152 | 4, 153 | 4, 154 | 4, 155 | 1, 156 | NULL, 157 | NULL, 158 | NULL, 159 | NULL, 160 | 'batch-2', 161 | 4, 162 | 4, 163 | 4, 164 | 4 165 | ) ON CONFLICT DO NOTHING; 166 | 167 | INSERT INTO chunk values ( 168 | 3, 169 | 'chunk-3', 170 | 5, 171 | 'block-5', 172 | 6, 173 | 'block-6', 174 | 3, 175 | 3, 176 | 3, 177 | 1, 178 | NULL, 179 | NULL, 180 | NULL, 181 | NULL, 182 | 'batch-2', 183 | 3, 184 | 3, 185 | 3, 186 | 3 187 | ) ON CONFLICT DO NOTHING; 188 | 189 | INSERT INTO chunk values ( 190 | 2, 191 | 'chunk-2', 192 | 3, 193 | 'block-3', 194 | 4, 195 | 'block-4', 196 | 2, 197 | 2, 198 | 2, 199 | 1, 200 | NULL, 201 | NULL, 202 | NULL, 203 | NULL, 204 | 'batch-1', 205 | 2, 206 | 2, 207 | 2, 208 | 2 209 | ) ON CONFLICT DO NOTHING; 210 | 211 | INSERT INTO chunk values ( 212 | 1, 213 | 'chunk-1', 214 | 1, 215 | 'block-1', 216 | 2, 217 | 'block-2', 218 | 1, 219 | 1, 220 | 1, 221 | 1, 222 | NULL, 223 | NULL, 224 | NULL, 225 | NULL, 226 | 'batch-1', 227 | 1, 228 | 1, 229 | 1, 230 | 1 231 | ) ON CONFLICT DO NOTHING; 232 | 233 | /* l2_block */ 234 | 235 | INSERT INTO l2_block values ( 236 | 10, 237 | 'block-10', 238 | '', 239 | '', 240 | '', 241 | '', 242 | 10, 243 | 10, 244 | 1658409526, 245 | 'chunk-6' 246 | ) ON CONFLICT DO NOTHING; 247 | 248 | insert into l2_block values ( 249 | 9, 250 | 'block-9', 251 | '', 252 | '', 253 | '', 254 | '', 255 | 9, 256 | 9, 257 | 1658409526, 258 | 'chunk-5' 259 | ) on conflict do nothing; 260 | 261 | insert into l2_block values ( 262 | 8, 263 | 'block-8', 264 | '', 265 | '', 266 | '', 267 | '', 268 | 8, 269 | 8, 270 | 1658409526, 271 | 'chunk-4' 272 | ) on conflict do nothing; 273 | 274 | insert into l2_block values ( 275 | 7, 276 | 'block-7', 277 | '', 278 | '', 279 | '', 280 | '', 281 | 7, 282 | 7, 283 | 1658409526, 284 | 'chunk-4' 285 | ) on conflict do nothing; 286 | 287 | insert into l2_block values ( 288 | 6, 289 | 'block-6', 290 | '', 291 | '', 292 | '', 293 | '', 294 | 6, 295 | 6, 296 | 1658409526, 297 | 'chunk-3' 298 | ) on conflict do nothing; 299 | 300 | insert into l2_block values ( 301 | 5, 302 | 'block-5', 303 | '', 304 | '', 305 | '', 306 | '', 307 | 5, 308 | 5, 309 | 1658409526, 310 | 'chunk-3' 311 | ) on conflict do nothing; 312 | 313 | insert into l2_block values ( 314 | 4, 315 | 'block-4', 316 | '', 317 | '', 318 | '', 319 | '', 320 | 4, 321 | 4, 322 | 1658409526, 323 | 'chunk-2' 324 | ) on conflict do nothing; 325 | 326 | insert into l2_block values ( 327 | 3, 328 | 'block-3', 329 | '', 330 | '', 331 | '', 332 | '', 333 | 3, 334 | 3, 335 | 1658409526, 336 | 'chunk-2' 337 | ) on conflict do nothing; 338 | 339 | insert into l2_block values ( 340 | 2, 341 | 'block-2', 342 | '', 343 | '', 344 | '', 345 | '', 346 | 2, 347 | 2, 348 | 1658409526, 349 | 'chunk-1' 350 | ) on conflict do nothing; 351 | 352 | insert into l2_block values ( 353 | 1, 354 | 'block-1', 355 | '', 356 | '', 357 | '', 358 | '', 359 | 1, 360 | 1, 361 | 1658409526, 362 | 'chunk-1' 363 | ) on conflict do nothing; 364 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | name: "rollup-explorer-backend" 3 | 4 | services: 5 | db: 6 | image: postgres:13.6 7 | container_name: rollup_explorer_postgres 8 | restart: always 9 | volumes: 10 | - ./docker-data/postgres:/var/lib/postgresql/data 11 | environment: 12 | POSTGRES_DB: "scroll" 13 | POSTGRES_PASSWORD: "scroll2022" 14 | ports: 15 | - "5434:5432" 16 | healthcheck: 17 | test: ['CMD', 'pg_isready'] 18 | interval: 5s 19 | timeout: 5s 20 | retries: 5 21 | rollup_explorer_backend: 22 | container_name: rollup_explorer_backend 23 | depends_on: 24 | - db 25 | restart: always 26 | build: 27 | dockerfile: Dockerfile 28 | image: rollup-explorer-backend 29 | links: 30 | - db 31 | environment: 32 | BIND_PORT: 8600 33 | OPEN_API_ADDR: "localhost:8600" 34 | ports: 35 | - "8600:8600" 36 | -------------------------------------------------------------------------------- /docs/openapi.spec: -------------------------------------------------------------------------------- 1 | { 2 | "openapi": "3.0.0", 3 | "info": { 4 | "title": "Scroll Rollup Explorer", 5 | "version": "2.0" 6 | }, 7 | "servers": [ 8 | { 9 | "url": "http://localhost:5001/api" 10 | } 11 | ], 12 | "tags": [], 13 | "paths": { 14 | "/batch": { 15 | "get": { 16 | "parameters": [ 17 | { 18 | "name": "index", 19 | "schema": { 20 | "type": "integer", 21 | "format": "int64" 22 | }, 23 | "in": "query", 24 | "required": true, 25 | "deprecated": false, 26 | "explode": true 27 | } 28 | ], 29 | "responses": { 30 | "200": { 31 | "description": "", 32 | "content": { 33 | "application/json; charset=utf-8": { 34 | "schema": { 35 | "$ref": "#/components/schemas/BatchResponse" 36 | } 37 | } 38 | } 39 | } 40 | } 41 | } 42 | }, 43 | "/batches": { 44 | "get": { 45 | "parameters": [ 46 | { 47 | "name": "page", 48 | "schema": { 49 | "type": "integer", 50 | "format": "uint64" 51 | }, 52 | "in": "query", 53 | "required": false, 54 | "deprecated": false, 55 | "explode": true 56 | }, 57 | { 58 | "name": "per_page", 59 | "schema": { 60 | "type": "integer", 61 | "format": "uint64" 62 | }, 63 | "in": "query", 64 | "required": false, 65 | "deprecated": false, 66 | "explode": true 67 | } 68 | ], 69 | "responses": { 70 | "200": { 71 | "description": "", 72 | "content": { 73 | "application/json; charset=utf-8": { 74 | "schema": { 75 | "$ref": "#/components/schemas/BatchesResponse" 76 | } 77 | } 78 | } 79 | } 80 | } 81 | } 82 | }, 83 | "/batch_blocks": { 84 | "get": { 85 | "parameters": [ 86 | { 87 | "name": "batch_index", 88 | "schema": { 89 | "type": "integer", 90 | "format": "int64" 91 | }, 92 | "in": "query", 93 | "required": true, 94 | "deprecated": false, 95 | "explode": true 96 | } 97 | ], 98 | "responses": { 99 | "200": { 100 | "description": "", 101 | "content": { 102 | "application/json; charset=utf-8": { 103 | "schema": { 104 | "$ref": "#/components/schemas/BlocksResponse" 105 | } 106 | } 107 | } 108 | } 109 | } 110 | } 111 | }, 112 | "/chunks": { 113 | "get": { 114 | "parameters": [ 115 | { 116 | "name": "batch_index", 117 | "schema": { 118 | "type": "integer", 119 | "format": "int64" 120 | }, 121 | "in": "query", 122 | "required": true, 123 | "deprecated": false, 124 | "explode": true 125 | } 126 | ], 127 | "responses": { 128 | "200": { 129 | "description": "", 130 | "content": { 131 | "application/json; charset=utf-8": { 132 | "schema": { 133 | "$ref": "#/components/schemas/ChunksResponse" 134 | } 135 | } 136 | } 137 | } 138 | } 139 | } 140 | }, 141 | "/chunk_blocks": { 142 | "get": { 143 | "parameters": [ 144 | { 145 | "name": "chunk_index", 146 | "schema": { 147 | "type": "integer", 148 | "format": "int64" 149 | }, 150 | "in": "query", 151 | "required": true, 152 | "deprecated": false, 153 | "explode": true 154 | } 155 | ], 156 | "responses": { 157 | "200": { 158 | "description": "", 159 | "content": { 160 | "application/json; charset=utf-8": { 161 | "schema": { 162 | "$ref": "#/components/schemas/BlocksResponse" 163 | } 164 | } 165 | } 166 | } 167 | } 168 | } 169 | }, 170 | "/last_batch_indexes": { 171 | "get": { 172 | "responses": { 173 | "200": { 174 | "description": "", 175 | "content": { 176 | "application/json; charset=utf-8": { 177 | "schema": { 178 | "$ref": "#/components/schemas/LastBatchIndexesResponse" 179 | } 180 | } 181 | } 182 | } 183 | } 184 | } 185 | }, 186 | "/search": { 187 | "get": { 188 | "parameters": [ 189 | { 190 | "name": "keyword", 191 | "schema": { 192 | "type": "string" 193 | }, 194 | "in": "query", 195 | "required": true, 196 | "deprecated": false, 197 | "explode": true 198 | } 199 | ], 200 | "responses": { 201 | "200": { 202 | "description": "", 203 | "content": { 204 | "application/json; charset=utf-8": { 205 | "schema": { 206 | "$ref": "#/components/schemas/SearchResponse" 207 | } 208 | } 209 | } 210 | } 211 | } 212 | } 213 | } 214 | }, 215 | "components": { 216 | "schemas": { 217 | "Batch": { 218 | "type": "object", 219 | "required": [ 220 | "hash", 221 | "index", 222 | "start_chunk_index", 223 | "end_chunk_index", 224 | "start_block_number", 225 | "end_block_number", 226 | "total_tx_num", 227 | "rollup_status", 228 | "created_at" 229 | ], 230 | "properties": { 231 | "hash": { 232 | "type": "string" 233 | }, 234 | "index": { 235 | "type": "integer", 236 | "format": "int64" 237 | }, 238 | "start_chunk_index": { 239 | "type": "integer", 240 | "format": "int64" 241 | }, 242 | "end_chunk_index": { 243 | "type": "integer", 244 | "format": "int64" 245 | }, 246 | "start_block_number": { 247 | "type": "integer", 248 | "format": "int64" 249 | }, 250 | "end_block_number": { 251 | "type": "integer", 252 | "format": "int64" 253 | }, 254 | "total_tx_num": { 255 | "type": "string", 256 | "format": "decimal" 257 | }, 258 | "rollup_status": { 259 | "type": "string" 260 | }, 261 | "commit_tx_hash": { 262 | "type": "string" 263 | }, 264 | "finalize_tx_hash": { 265 | "type": "string" 266 | }, 267 | "created_at": { 268 | "type": "string", 269 | "format": "decimal" 270 | }, 271 | "committed_at": { 272 | "type": "string", 273 | "format": "decimal" 274 | }, 275 | "finalized_at": { 276 | "type": "string", 277 | "format": "decimal" 278 | } 279 | } 280 | }, 281 | "BatchResponse": { 282 | "type": "object", 283 | "properties": { 284 | "batch": { 285 | "$ref": "#/components/schemas/Batch" 286 | } 287 | } 288 | }, 289 | "BatchesResponse": { 290 | "type": "object", 291 | "required": [ 292 | "total", 293 | "batches" 294 | ], 295 | "properties": { 296 | "total": { 297 | "type": "integer", 298 | "format": "int64" 299 | }, 300 | "batches": { 301 | "type": "array", 302 | "items": { 303 | "$ref": "#/components/schemas/Batch" 304 | } 305 | } 306 | } 307 | }, 308 | "Block": { 309 | "type": "object", 310 | "required": [ 311 | "number", 312 | "tx_num", 313 | "hash", 314 | "block_timestamp" 315 | ], 316 | "properties": { 317 | "number": { 318 | "type": "integer", 319 | "format": "int64" 320 | }, 321 | "tx_num": { 322 | "type": "integer", 323 | "format": "int32" 324 | }, 325 | "hash": { 326 | "type": "string" 327 | }, 328 | "block_timestamp": { 329 | "type": "string", 330 | "format": "decimal" 331 | } 332 | } 333 | }, 334 | "BlocksResponse": { 335 | "type": "object", 336 | "required": [ 337 | "blocks" 338 | ], 339 | "properties": { 340 | "batch_index": { 341 | "type": "integer", 342 | "format": "int64" 343 | }, 344 | "chunk_index": { 345 | "type": "integer", 346 | "format": "int64" 347 | }, 348 | "blocks": { 349 | "type": "array", 350 | "items": { 351 | "$ref": "#/components/schemas/Block" 352 | } 353 | } 354 | } 355 | }, 356 | "Chunk": { 357 | "type": "object", 358 | "required": [ 359 | "hash", 360 | "index", 361 | "start_block_number", 362 | "end_block_number", 363 | "total_tx_num", 364 | "created_at" 365 | ], 366 | "properties": { 367 | "hash": { 368 | "type": "string" 369 | }, 370 | "index": { 371 | "type": "integer", 372 | "format": "int64" 373 | }, 374 | "start_block_number": { 375 | "type": "integer", 376 | "format": "int64" 377 | }, 378 | "end_block_number": { 379 | "type": "integer", 380 | "format": "int64" 381 | }, 382 | "total_tx_num": { 383 | "type": "integer", 384 | "format": "int64" 385 | }, 386 | "created_at": { 387 | "type": "string", 388 | "format": "decimal" 389 | } 390 | } 391 | }, 392 | "ChunksResponse": { 393 | "type": "object", 394 | "required": [ 395 | "batch_index", 396 | "chunks" 397 | ], 398 | "properties": { 399 | "batch_index": { 400 | "type": "integer", 401 | "format": "int64" 402 | }, 403 | "chunks": { 404 | "type": "array", 405 | "items": { 406 | "$ref": "#/components/schemas/Chunk" 407 | } 408 | } 409 | } 410 | }, 411 | "LastBatchIndexesResponse": { 412 | "type": "object", 413 | "required": [ 414 | "all_index", 415 | "committed_index", 416 | "finalized_index" 417 | ], 418 | "properties": { 419 | "all_index": { 420 | "type": "integer", 421 | "format": "int64" 422 | }, 423 | "committed_index": { 424 | "type": "integer", 425 | "format": "int64" 426 | }, 427 | "finalized_index": { 428 | "type": "integer", 429 | "format": "int64" 430 | } 431 | } 432 | }, 433 | "SearchResponse": { 434 | "type": "object", 435 | "required": [ 436 | "batch_index" 437 | ], 438 | "properties": { 439 | "batch_index": { 440 | "type": "integer", 441 | "format": "int64" 442 | } 443 | } 444 | } 445 | } 446 | } 447 | } -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly-2022-08-23" 3 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | edition = "2021" 2 | 3 | comment_width = 100 4 | imports_granularity = "Crate" 5 | max_width = 100 6 | newline_style = "Unix" 7 | # normalize_comments = true 8 | reorder_imports = true 9 | wrap_comments = true 10 | -------------------------------------------------------------------------------- /scripts/import_mock_data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -uex 3 | 4 | function import_mock_data() { 5 | for f in db/tests/*.sql; do 6 | psql postgres://postgres:scroll2022@localhost:5434/scroll -f $f 7 | done 8 | } 9 | 10 | import_mock_data 11 | -------------------------------------------------------------------------------- /scripts/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -uex 3 | 4 | export RUST_BACKTRACE=full 5 | 6 | function handle_submodules() { 7 | git submodule update --init --recursive 8 | # if [ -z ${CI+x} ]; then git pull --recurse-submodules; fi 9 | } 10 | 11 | function db_migrate() { 12 | goose -dir "third-parties/scroll/database/migrate/migrations" \ 13 | postgres "postgres://postgres:scroll2022@localhost:5434/scroll?sslmode=disable" \ 14 | up 15 | } 16 | 17 | function run() { 18 | docker compose -f docker-compose.yml up -d db --wait 19 | db_migrate 20 | cargo run --bin rollup_explorer 21 | } 22 | 23 | function setup() { 24 | handle_submodules 25 | } 26 | 27 | setup 28 | run 29 | -------------------------------------------------------------------------------- /scripts/stop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -uex 3 | 4 | export DX_CLEAN=${DX_CLEAN:-TRUE} 5 | echo "DX_CLEAN: $DX_CLEAN" 6 | 7 | function kill_tasks() { 8 | # kill last time running tasks: 9 | echo "===================process list==========================" 10 | ps aux | grep 'rollup_explorer' | grep -v grep | awk '{print $2 " " $11}' 11 | kill -9 $(ps aux | grep 'rollup_explorer' | grep -v grep | awk '{print $2}') || true 12 | echo "===================process list==========================" 13 | } 14 | 15 | function clean_data() { 16 | rm -rf docker-data 17 | } 18 | 19 | kill_tasks 20 | docker compose -f docker-compose.yml down --remove-orphans 21 | if [ $DX_CLEAN == 'TRUE' ]; then 22 | clean_data 23 | fi 24 | -------------------------------------------------------------------------------- /src/bin/main.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use dotenvy::dotenv; 3 | use rollup_explorer::{cache, open_api, Settings}; 4 | use std::sync::Arc; 5 | use tracing_subscriber::EnvFilter; 6 | 7 | #[tokio::main] 8 | async fn main() -> Result<()> { 9 | dotenv().ok(); 10 | tracing_subscriber::fmt() 11 | .with_env_filter(EnvFilter::from_default_env()) 12 | .with_file(true) 13 | .with_line_number(true) 14 | .init(); 15 | 16 | Settings::init()?; 17 | 18 | let mut cache = Arc::new(cache::run()?); 19 | open_api::run(cache.clone()).await?; 20 | Arc::get_mut(&mut cache).unwrap().stop().await 21 | } 22 | -------------------------------------------------------------------------------- /src/cache.rs: -------------------------------------------------------------------------------- 1 | use anyhow::{anyhow, bail, Result}; 2 | use std::{ 3 | any::Any, 4 | collections::HashMap, 5 | sync::{ 6 | mpsc::{channel, sync_channel, Sender, SyncSender}, 7 | Arc, 8 | }, 9 | time::{Duration, Instant}, 10 | }; 11 | use tokio::task::JoinHandle; 12 | 13 | type Key = String; 14 | type RawValue = Arc; 15 | type Ttl = u64; 16 | 17 | const CHANNEL_BOUND: usize = 200; 18 | 19 | pub async fn from_cache(cache: &Cache, cache_key: &str) -> Option 20 | where 21 | T: Clone + 'static, 22 | { 23 | cache 24 | .get(cache_key) 25 | .await 26 | .ok() 27 | .flatten() 28 | .and_then(|any| any.downcast_ref::().cloned()) 29 | } 30 | 31 | pub fn run() -> Result { 32 | let mut cache = Cache::new(); 33 | cache.run(); 34 | 35 | Ok(cache) 36 | } 37 | 38 | #[derive(Debug)] 39 | pub struct Cache { 40 | handle: Option>, 41 | sender: Option>, 42 | } 43 | 44 | // TODO: Add a `Request::AutoClear` to delete expired values automatically. 45 | impl Cache { 46 | fn new() -> Self { 47 | Self { 48 | handle: None, 49 | sender: None, 50 | } 51 | } 52 | 53 | fn run(&mut self) { 54 | let (sender, receiver) = sync_channel(CHANNEL_BOUND); 55 | let handle = tokio::spawn(async move { 56 | let mut kvs: HashMap = HashMap::new(); 57 | loop { 58 | match receiver.recv() { 59 | Ok(req) => { 60 | match req { 61 | Request::Get(sender, key) => { 62 | let raw = match kvs.get(&key) { 63 | Some(val) => { 64 | if val.expired_at > Instant::now() { 65 | Some(val.raw.clone()) 66 | } else { 67 | kvs.remove(&key); 68 | None 69 | } 70 | } 71 | None => None, 72 | }; 73 | if let Err(error) = sender.send(Response::Get(raw)) { 74 | log::error!( 75 | "Cache - Failed to send Response of Get({key}): {error}" 76 | ); 77 | break; 78 | } 79 | } 80 | Request::Set(sender, key, raw, ttl) => { 81 | let expired_at = if let Some(expired_at) = 82 | Instant::now().checked_add(Duration::new(ttl, 0)) 83 | { 84 | expired_at 85 | } else { 86 | log::error!( 87 | "Cache - Failed to calculate expired time by TTL: {ttl}" 88 | ); 89 | break; 90 | }; 91 | if let Err(error) = sender.send(Response::Set) { 92 | log::error!("Cache - Failed to send Response of Set({key}, ..): {error}"); 93 | break; 94 | } 95 | kvs.insert(key, Value { raw, expired_at }); 96 | } 97 | } 98 | } 99 | Err(error) => { 100 | log::warn!("Cache - Failed to receive Request (may exit): {error:?}"); 101 | break; 102 | } 103 | } 104 | } 105 | }); 106 | 107 | self.handle = Some(handle); 108 | self.sender = Some(sender); 109 | } 110 | 111 | pub async fn stop(&mut self) -> Result<()> { 112 | if let Some(sender) = self.sender.take() { 113 | drop(sender); 114 | } 115 | if let Some(handle) = self.handle.take() { 116 | tokio::try_join!(handle)?; 117 | } 118 | 119 | Ok(()) 120 | } 121 | 122 | pub async fn get(&self, key: &str) -> Result>> { 123 | if let Some(sender) = self.sender.as_ref() { 124 | let (req_sender, res_receiver) = channel(); 125 | sender 126 | .send(Request::Get(req_sender, key.to_string())) 127 | .map_err(|error| anyhow!("Cache - Failed to send a Get request: {error}"))?; 128 | match res_receiver.recv()? { 129 | Response::Get(raw) => Ok(raw), 130 | _ => unreachable!(), 131 | } 132 | } else { 133 | bail!("Cache is not running"); 134 | } 135 | } 136 | 137 | pub async fn set(&self, key: &str, val: Arc, ttl: Ttl) -> Result<()> { 138 | if let Some(sender) = self.sender.as_ref() { 139 | let (req_sender, res_receiver) = channel(); 140 | sender 141 | .send(Request::Set(req_sender, key.to_string(), val, ttl)) 142 | .map_err(|error| anyhow!("Cache - Failed to send a Set request: {error}"))?; 143 | match res_receiver.recv()? { 144 | Response::Set => Ok(()), 145 | _ => unreachable!(), 146 | } 147 | } else { 148 | bail!("Cache is not running"); 149 | } 150 | } 151 | } 152 | 153 | #[derive(Debug)] 154 | enum Request { 155 | Get(Sender, Key), 156 | Set(Sender, Key, RawValue, Ttl), 157 | } 158 | 159 | #[derive(Debug)] 160 | enum Response { 161 | Get(Option), 162 | Set, 163 | } 164 | 165 | #[derive(Clone, Debug)] 166 | struct Value { 167 | expired_at: Instant, 168 | raw: RawValue, 169 | } 170 | 171 | #[cfg(test)] 172 | mod tests { 173 | use super::*; 174 | 175 | #[tokio::test(flavor = "multi_thread", worker_threads = 1)] 176 | async fn cache_tests() { 177 | let mut cache = run().unwrap(); 178 | 179 | // Return None for non-existing key. 180 | assert!(cache.get("non-existing-key").await.unwrap().is_none()); 181 | 182 | // Set a key-value to cache and get the cached value. 183 | cache 184 | .set("key1", Arc::new("value1".to_string()), 10) 185 | .await 186 | .unwrap(); 187 | assert_eq!( 188 | cache 189 | .get("key1") 190 | .await 191 | .unwrap() 192 | .unwrap() 193 | .downcast_ref::() 194 | .unwrap(), 195 | "value1" 196 | ); 197 | 198 | // Value should be expired directly for zero TTL. 199 | cache 200 | .set("key2", Arc::new("value2".to_string()), 0) 201 | .await 202 | .unwrap(); 203 | assert!(cache.get("key2").await.unwrap().is_none()); 204 | 205 | cache.stop().await.unwrap(); 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /src/consts.rs: -------------------------------------------------------------------------------- 1 | // Expired seconds of cache data. 2 | pub const DEFAULT_CACHE_EXPIRED_SECS: u64 = 15; 3 | 4 | // Query parameter `page` starts from `1`, default `per_page` is 10. 5 | // (configured in .env). 6 | pub const DEFAULT_PER_PAGE: u64 = 10; 7 | 8 | // Identify if batch or chunk is invalid. 9 | pub const INVALID_INDEX: i64 = -1; 10 | -------------------------------------------------------------------------------- /src/db/mod.rs: -------------------------------------------------------------------------------- 1 | mod queries; 2 | 3 | pub mod models; 4 | 5 | pub use queries::*; 6 | 7 | pub type DbPool = sqlx::postgres::PgPool; 8 | pub type RollupStatusType = i16; 9 | 10 | pub mod table_name { 11 | pub const BATCH: &str = "batch"; 12 | pub const BLOCK: &str = "l2_block"; 13 | pub const CHUNK: &str = "chunk"; 14 | } 15 | -------------------------------------------------------------------------------- /src/db/models/batch.rs: -------------------------------------------------------------------------------- 1 | use crate::db::RollupStatusType; 2 | use chrono::NaiveDateTime; 3 | use serde::Serialize; 4 | 5 | #[derive(sqlx::FromRow, Clone, Debug, Serialize)] 6 | pub struct Batch { 7 | pub hash: String, 8 | pub index: i64, 9 | pub start_chunk_index: i64, 10 | pub end_chunk_index: i64, 11 | pub start_chunk_hash: String, 12 | pub end_chunk_hash: String, 13 | #[sqlx(default)] 14 | pub start_block_number: Option, 15 | #[sqlx(default)] 16 | pub end_block_number: Option, 17 | #[sqlx(default)] 18 | pub total_tx_num: Option, 19 | pub rollup_status: RollupStatusType, 20 | pub commit_tx_hash: Option, 21 | pub finalize_tx_hash: Option, 22 | pub created_at: NaiveDateTime, 23 | pub committed_at: Option, 24 | pub finalized_at: Option, 25 | } 26 | -------------------------------------------------------------------------------- /src/db/models/block.rs: -------------------------------------------------------------------------------- 1 | use rust_decimal::Decimal; 2 | use serde::Serialize; 3 | 4 | #[derive(sqlx::FromRow, Clone, Debug, Serialize)] 5 | pub struct Block { 6 | pub number: i64, 7 | pub tx_num: i32, 8 | pub hash: String, 9 | pub chunk_hash: Option, 10 | pub block_timestamp: Decimal, 11 | } 12 | -------------------------------------------------------------------------------- /src/db/models/chunk.rs: -------------------------------------------------------------------------------- 1 | use chrono::NaiveDateTime; 2 | use serde::Serialize; 3 | 4 | #[derive(sqlx::FromRow, Clone, Debug, Serialize)] 5 | pub struct Chunk { 6 | pub index: i64, 7 | pub start_block_number: i64, 8 | pub end_block_number: i64, 9 | pub total_tx_num: i32, 10 | pub hash: String, 11 | pub batch_hash: Option, 12 | pub created_at: NaiveDateTime, 13 | } 14 | -------------------------------------------------------------------------------- /src/db/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod batch; 2 | pub mod block; 3 | pub mod chunk; 4 | 5 | pub use batch::*; 6 | pub use block::*; 7 | pub use chunk::*; 8 | -------------------------------------------------------------------------------- /src/db/queries/batch_query.rs: -------------------------------------------------------------------------------- 1 | use super::chunk_query; 2 | use crate::db::{models::Batch, table_name, DbPool, RollupStatusType}; 3 | use sqlx::{query_as, query_scalar, Result}; 4 | use std::collections::HashMap; 5 | 6 | pub async fn fetch_all(db_pool: &DbPool, offset: u64, limit: u64) -> Result> { 7 | let stmt = format!( 8 | "SELECT 9 | hash, 10 | index, 11 | start_chunk_index, 12 | end_chunk_index, 13 | start_chunk_hash, 14 | end_chunk_hash, 15 | rollup_status, 16 | commit_tx_hash, 17 | finalize_tx_hash, 18 | created_at, 19 | committed_at, 20 | finalized_at 21 | FROM {} 22 | WHERE deleted_at IS NULL 23 | ORDER BY index DESC OFFSET {} LIMIT {}", 24 | table_name::BATCH, 25 | offset, 26 | limit, 27 | ); 28 | 29 | let mut batches = query_as::<_, Batch>(&stmt).fetch_all(db_pool).await?; 30 | for batch in batches.iter_mut() { 31 | complete_batch(db_pool, batch).await?; 32 | } 33 | 34 | Ok(batches) 35 | } 36 | 37 | pub async fn fetch_one(db_pool: &DbPool, index: i64) -> Result> { 38 | let stmt = format!( 39 | "SELECT 40 | hash, 41 | index, 42 | start_chunk_index, 43 | end_chunk_index, 44 | start_chunk_hash, 45 | end_chunk_hash, 46 | rollup_status, 47 | commit_tx_hash, 48 | finalize_tx_hash, 49 | created_at, 50 | committed_at, 51 | finalized_at 52 | FROM {} 53 | WHERE index = $1 AND deleted_at IS NULL", 54 | table_name::BATCH, 55 | ); 56 | 57 | let batch = query_as::<_, Batch>(&stmt) 58 | .bind(index) 59 | .fetch_optional(db_pool) 60 | .await?; 61 | Ok(if let Some(mut batch) = batch { 62 | complete_batch(db_pool, &mut batch).await?; 63 | Some(batch) 64 | } else { 65 | None 66 | }) 67 | } 68 | 69 | pub async fn get_hash_by_index(db_pool: &DbPool, index: i64) -> Result> { 70 | let stmt = format!( 71 | "SELECT hash FROM {} 72 | WHERE index = $1 AND deleted_at IS NULL", 73 | table_name::BATCH, 74 | ); 75 | 76 | query_scalar::<_, String>(&stmt) 77 | .bind(index) 78 | .fetch_optional(db_pool) 79 | .await 80 | } 81 | 82 | pub async fn get_index_by_hash(db_pool: &DbPool, hash: &str) -> Result> { 83 | let stmt = format!( 84 | "SELECT index FROM {} 85 | WHERE hash = $1 AND deleted_at IS NULL", 86 | table_name::BATCH, 87 | ); 88 | 89 | query_scalar::<_, i64>(&stmt) 90 | .bind(hash) 91 | .fetch_optional(db_pool) 92 | .await 93 | } 94 | 95 | pub async fn get_total(db_pool: &DbPool) -> Result { 96 | let stmt = format!( 97 | "SELECT COALESCE(MAX(index), 0) FROM {} 98 | WHERE deleted_at IS NULL", 99 | table_name::BATCH, 100 | ); 101 | 102 | query_scalar::<_, i64>(&stmt).fetch_one(db_pool).await 103 | } 104 | 105 | pub async fn get_max_status_indexes(db_pool: &DbPool) -> Result> { 106 | let stmt = format!( 107 | "SELECT rollup_status, MAX(index) FROM {} 108 | WHERE deleted_at IS NULL 109 | GROUP BY rollup_status", 110 | table_name::BATCH, 111 | ); 112 | 113 | query_as::<_, (RollupStatusType, i64)>(&stmt) 114 | .fetch_all(db_pool) 115 | .await 116 | .map(|v| v.into_iter().collect()) 117 | } 118 | 119 | async fn complete_batch(db_pool: &DbPool, batch: &mut Batch) -> Result<()> { 120 | batch.start_block_number = 121 | chunk_query::get_start_block_number_by_chunk_hash(db_pool, &batch.start_chunk_hash).await?; 122 | batch.end_block_number = 123 | chunk_query::get_end_block_number_by_chunk_hash(db_pool, &batch.end_chunk_hash).await?; 124 | batch.total_tx_num = Some( 125 | chunk_query::get_total_tx_num_by_index_range( 126 | db_pool, 127 | batch.start_chunk_index, 128 | batch.end_chunk_index, 129 | ) 130 | .await?, 131 | ); 132 | 133 | Ok(()) 134 | } 135 | -------------------------------------------------------------------------------- /src/db/queries/block_query.rs: -------------------------------------------------------------------------------- 1 | use super::chunk_query; 2 | use crate::db::{models::Block, table_name, DbPool}; 3 | use sqlx::{query_as, query_scalar, Result}; 4 | 5 | pub async fn fetch_by_chunk_hash(db_pool: &DbPool, chunk_hash: &str) -> Result> { 6 | let stmt = format!( 7 | "SELECT 8 | number, 9 | tx_num, 10 | hash, 11 | chunk_hash, 12 | block_timestamp 13 | FROM {} 14 | WHERE chunk_hash = $1 AND deleted_at IS NULL 15 | ORDER BY number ASC", 16 | table_name::BLOCK, 17 | ); 18 | 19 | query_as::<_, Block>(&stmt) 20 | .bind(chunk_hash) 21 | .fetch_all(db_pool) 22 | .await 23 | } 24 | 25 | pub async fn fetch_by_num_range( 26 | db_pool: &DbPool, 27 | start_num: i64, 28 | end_num: i64, 29 | ) -> Result> { 30 | let stmt = format!( 31 | "SELECT 32 | number, 33 | tx_num, 34 | hash, 35 | chunk_hash, 36 | block_timestamp 37 | FROM {} 38 | WHERE number >= $1 AND number <= $2 AND deleted_at IS NULL 39 | ORDER BY number ASC", 40 | table_name::BLOCK, 41 | ); 42 | 43 | query_as::<_, Block>(&stmt) 44 | .bind(start_num) 45 | .bind(end_num) 46 | .fetch_all(db_pool) 47 | .await 48 | } 49 | 50 | pub async fn get_batch_hash_by_block_hash( 51 | db_pool: &DbPool, 52 | block_hash: &str, 53 | ) -> Result> { 54 | let stmt = format!( 55 | "SELECT chunk_hash FROM {} 56 | where hash = $1 AND deleted_at IS NULL", 57 | table_name::BLOCK, 58 | ); 59 | 60 | let chunk_hash = query_scalar::<_, String>(&stmt) 61 | .bind(block_hash.to_lowercase()) 62 | .fetch_optional(db_pool) 63 | .await?; 64 | 65 | Ok(if let Some(chunk_hash) = chunk_hash { 66 | chunk_query::get_batch_hash_by_chunk_hash(db_pool, &chunk_hash).await? 67 | } else { 68 | None 69 | }) 70 | } 71 | 72 | pub async fn get_batch_hash_by_number(db_pool: &DbPool, number: i64) -> Result> { 73 | let stmt = format!( 74 | "SELECT chunk_hash FROM {} 75 | where number = $1 AND deleted_at IS NULL", 76 | table_name::BLOCK, 77 | ); 78 | 79 | let chunk_hash = query_scalar::<_, String>(&stmt) 80 | .bind(number) 81 | .fetch_optional(db_pool) 82 | .await?; 83 | 84 | Ok(if let Some(chunk_hash) = chunk_hash { 85 | chunk_query::get_batch_hash_by_chunk_hash(db_pool, &chunk_hash).await? 86 | } else { 87 | None 88 | }) 89 | } 90 | -------------------------------------------------------------------------------- /src/db/queries/chunk_query.rs: -------------------------------------------------------------------------------- 1 | use crate::db::{models::Chunk, table_name, DbPool}; 2 | use sqlx::{query_as, query_scalar, Result}; 3 | 4 | pub async fn fetch_by_batch_hash(db_pool: &DbPool, batch_hash: &str) -> Result> { 5 | let stmt = format!( 6 | "SELECT 7 | index, 8 | start_block_number, 9 | end_block_number, 10 | (total_l1_messages_popped_in_chunk + total_l2_tx_num) AS total_tx_num, 11 | hash, 12 | batch_hash, 13 | created_at 14 | FROM {} 15 | WHERE batch_hash = $1 AND deleted_at IS NULL 16 | ORDER BY index ASC", 17 | table_name::CHUNK, 18 | ); 19 | 20 | query_as::<_, Chunk>(&stmt) 21 | .bind(batch_hash) 22 | .fetch_all(db_pool) 23 | .await 24 | } 25 | 26 | pub async fn get_batch_hash_by_chunk_hash( 27 | db_pool: &DbPool, 28 | chunk_hash: &str, 29 | ) -> Result> { 30 | let stmt = format!( 31 | "SELECT batch_hash FROM {} 32 | WHERE hash = $1 AND deleted_at IS NULL", 33 | table_name::CHUNK, 34 | ); 35 | 36 | query_scalar::<_, String>(&stmt) 37 | .bind(chunk_hash.to_lowercase()) 38 | .fetch_optional(db_pool) 39 | .await 40 | } 41 | 42 | pub async fn get_block_num_range_by_batch_hash( 43 | db_pool: &DbPool, 44 | batch_hash: &str, 45 | ) -> Result<(i64, i64)> { 46 | let stmt = format!( 47 | "SELECT 48 | COALESCE(MIN(start_block_number), 0), 49 | COALESCE(MAX(end_block_number), 0) 50 | FROM {} 51 | WHERE batch_hash = $1 AND deleted_at IS NULL", 52 | table_name::CHUNK, 53 | ); 54 | 55 | query_as::<_, (i64, i64)>(&stmt) 56 | .bind(batch_hash) 57 | .fetch_one(db_pool) 58 | .await 59 | } 60 | 61 | pub async fn get_end_block_number_by_chunk_hash( 62 | db_pool: &DbPool, 63 | chunk_hash: &str, 64 | ) -> Result> { 65 | let stmt = format!( 66 | "SELECT end_block_number FROM {} 67 | where hash = $1 AND deleted_at IS NULL", 68 | table_name::CHUNK 69 | ); 70 | query_scalar::<_, i64>(&stmt) 71 | .bind(chunk_hash) 72 | .fetch_optional(db_pool) 73 | .await 74 | } 75 | 76 | pub async fn get_hash_by_index(db_pool: &DbPool, index: i64) -> Result> { 77 | let stmt = format!( 78 | "SELECT hash FROM {} 79 | WHERE index = $1 AND deleted_at IS NULL", 80 | table_name::CHUNK, 81 | ); 82 | 83 | query_scalar::<_, String>(&stmt) 84 | .bind(index) 85 | .fetch_optional(db_pool) 86 | .await 87 | } 88 | 89 | pub async fn get_start_block_number_by_chunk_hash( 90 | db_pool: &DbPool, 91 | chunk_hash: &str, 92 | ) -> Result> { 93 | let stmt = format!( 94 | "SELECT start_block_number FROM {} 95 | where hash = $1 AND deleted_at IS NULL", 96 | table_name::CHUNK, 97 | ); 98 | 99 | query_scalar::<_, i64>(&stmt) 100 | .bind(chunk_hash) 101 | .fetch_optional(db_pool) 102 | .await 103 | } 104 | 105 | pub async fn get_total_tx_num_by_index_range( 106 | db_pool: &DbPool, 107 | start_chunk_index: i64, 108 | end_chunk_index: i64, 109 | ) -> Result { 110 | let stmt = format!( 111 | "SELECT 112 | COALESCE( 113 | SUM(total_l1_messages_popped_in_chunk + total_l2_tx_num), 114 | 0 115 | ) FROM {} 116 | WHERE index >= $1 AND index <= $2 AND deleted_at IS NULL", 117 | table_name::CHUNK, 118 | ); 119 | 120 | query_scalar::<_, i64>(&stmt) 121 | .bind(start_chunk_index) 122 | .bind(end_chunk_index) 123 | .fetch_one(db_pool) 124 | .await 125 | } 126 | -------------------------------------------------------------------------------- /src/db/queries/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod batch_query; 2 | pub mod block_query; 3 | pub mod chunk_query; 4 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(once_cell)] 2 | 3 | pub mod cache; 4 | pub mod consts; 5 | pub mod db; 6 | pub mod open_api; 7 | pub mod settings; 8 | 9 | pub use cache::Cache; 10 | pub use settings::Settings; 11 | -------------------------------------------------------------------------------- /src/open_api/apis.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | consts::*, 3 | db::*, 4 | open_api::{responses::*, State, CACHE_HITS, INCOMING_REQUESTS, RESPONSE_TIME_COLLECTOR}, 5 | Settings, 6 | }; 7 | use poem::{error::InternalServerError, web::Data, Result}; 8 | use poem_openapi::{param::Query, payload::Json, OpenApi}; 9 | use std::{sync::Arc, time::Instant}; 10 | 11 | // Macro used to log error with right line number. 12 | macro_rules! api_err { 13 | ($err:expr) => {{ 14 | log::error!("{:?}", $err); 15 | InternalServerError($err) 16 | }}; 17 | } 18 | 19 | pub(crate) struct Apis; 20 | 21 | #[OpenApi] 22 | impl Apis { 23 | #[oai(path = "/batch", method = "get")] 24 | async fn batch(&self, state: Data<&State>, index: Query) -> Result> { 25 | let response_time = Instant::now(); 26 | INCOMING_REQUESTS.with_label_values(&["batch"]).inc(); 27 | 28 | let index = index.0; 29 | 30 | // Return directly if cached. 31 | let cache_key = format!("batch-{index}"); 32 | if let Some(response) = BatchResponse::from_cache(state.cache.as_ref(), &cache_key).await { 33 | log::debug!("OpenAPI - Get batch from Cache: {response:?}"); 34 | CACHE_HITS.with_label_values(&["batch"]).inc(); 35 | 36 | RESPONSE_TIME_COLLECTOR 37 | .with_label_values(&["batch"]) 38 | .observe(response_time.elapsed().as_secs_f64()); 39 | 40 | return Ok(Json(response)); 41 | }; 42 | 43 | let batch = batch_query::fetch_one(&state.db_pool, index) 44 | .await 45 | .map_err(|e| api_err!(e))?; 46 | let response = BatchResponse::new(batch); 47 | 48 | // Save to cache. 49 | if let Err(error) = state 50 | .cache 51 | .set( 52 | &cache_key, 53 | Arc::new(response.clone()), 54 | Settings::get().cache_expired_secs, 55 | ) 56 | .await 57 | { 58 | log::error!("OpenAPI - Failed to save cache of {cache_key}: {error}"); 59 | } 60 | 61 | RESPONSE_TIME_COLLECTOR 62 | .with_label_values(&["batch"]) 63 | .observe(response_time.elapsed().as_secs_f64()); 64 | 65 | Ok(Json(response)) 66 | } 67 | 68 | #[oai(path = "/batches", method = "get")] 69 | async fn batches( 70 | &self, 71 | state: Data<&State>, 72 | page: Query>, 73 | per_page: Query>, 74 | ) -> Result> { 75 | let response_time = Instant::now(); 76 | INCOMING_REQUESTS.with_label_values(&["batches"]).inc(); 77 | 78 | let limit = per_page.0.map_or_else( 79 | || DEFAULT_PER_PAGE, 80 | |val| { 81 | if val == 10 || val == 25 || val == 100 { 82 | val 83 | } else { 84 | DEFAULT_PER_PAGE 85 | } 86 | }, 87 | ); 88 | let offset = page 89 | .0 90 | .map_or_else(|| 0, |val| if val > 0 { (val - 1) * limit } else { 0 }); 91 | 92 | // Return directly if cached. 93 | let cache_key = format!("batches-of-offset-{offset}-limit-{limit}"); 94 | if let Some(response) = BatchesResponse::from_cache(state.cache.as_ref(), &cache_key).await 95 | { 96 | log::debug!("OpenAPI - Get batches from Cache: {response:?}"); 97 | CACHE_HITS.with_label_values(&["batches"]).inc(); 98 | 99 | RESPONSE_TIME_COLLECTOR 100 | .with_label_values(&["batches"]) 101 | .observe(response_time.elapsed().as_secs_f64()); 102 | 103 | return Ok(Json(response)); 104 | }; 105 | 106 | let total = batch_query::get_total(&state.db_pool) 107 | .await 108 | .map_err(|e| api_err!(e))?; 109 | let batches = batch_query::fetch_all(&state.db_pool, offset, limit) 110 | .await 111 | .map_err(|e| api_err!(e))?; 112 | let response = BatchesResponse::new(total, batches); 113 | 114 | // Save to cache. 115 | if let Err(error) = state 116 | .cache 117 | .set( 118 | &cache_key, 119 | Arc::new(response.clone()), 120 | Settings::get().cache_expired_secs, 121 | ) 122 | .await 123 | { 124 | log::error!("OpenAPI - Failed to save cache of {cache_key}: {error}"); 125 | } 126 | 127 | RESPONSE_TIME_COLLECTOR 128 | .with_label_values(&["batches"]) 129 | .observe(response_time.elapsed().as_secs_f64()); 130 | 131 | Ok(Json(response)) 132 | } 133 | 134 | #[oai(path = "/batch_blocks", method = "get")] 135 | async fn batch_blocks( 136 | &self, 137 | state: Data<&State>, 138 | batch_index: Query, 139 | ) -> Result> { 140 | let response_time = Instant::now(); 141 | INCOMING_REQUESTS.with_label_values(&["batch_blocks"]).inc(); 142 | 143 | let batch_index = batch_index.0; 144 | 145 | // Return directly if cached. 146 | let cache_key = format!("blocks-of-batch-{batch_index}"); 147 | if let Some(response) = BlocksResponse::from_cache(state.cache.as_ref(), &cache_key).await { 148 | log::debug!("OpenAPI - Get blocks from Cache: {response:?}"); 149 | CACHE_HITS.with_label_values(&["batch_blocks"]).inc(); 150 | 151 | RESPONSE_TIME_COLLECTOR 152 | .with_label_values(&["batch_blocks"]) 153 | .observe(response_time.elapsed().as_secs_f64()); 154 | 155 | return Ok(Json(response)); 156 | }; 157 | 158 | let response = query_blocks_by_batch_index(&state.db_pool, batch_index).await?; 159 | 160 | // Save to cache. 161 | if let Err(error) = state 162 | .cache 163 | .set( 164 | &cache_key, 165 | Arc::new(response.clone()), 166 | Settings::get().cache_expired_secs, 167 | ) 168 | .await 169 | { 170 | log::error!("OpenAPI - Failed to save cache of {cache_key}: {error}"); 171 | } 172 | 173 | RESPONSE_TIME_COLLECTOR 174 | .with_label_values(&["batch_blocks"]) 175 | .observe(response_time.elapsed().as_secs_f64()); 176 | 177 | Ok(Json(response)) 178 | } 179 | 180 | #[oai(path = "/chunks", method = "get")] 181 | async fn chunks( 182 | &self, 183 | state: Data<&State>, 184 | batch_index: Query, 185 | ) -> Result> { 186 | let response_time = Instant::now(); 187 | INCOMING_REQUESTS.with_label_values(&["chunks"]).inc(); 188 | 189 | let batch_index = batch_index.0; 190 | 191 | // Return directly if cached. 192 | let cache_key = format!("chunks-of-batch-{batch_index}"); 193 | if let Some(response) = ChunksResponse::from_cache(state.cache.as_ref(), &cache_key).await { 194 | log::debug!("OpenAPI - Get chunks from Cache: {response:?}"); 195 | CACHE_HITS.with_label_values(&["chunks"]).inc(); 196 | 197 | RESPONSE_TIME_COLLECTOR 198 | .with_label_values(&["chunks"]) 199 | .observe(response_time.elapsed().as_secs_f64()); 200 | 201 | return Ok(Json(response)); 202 | }; 203 | 204 | let batch_hash = batch_query::get_hash_by_index(&state.db_pool, batch_index) 205 | .await 206 | .map_err(|e| api_err!(e))?; 207 | let (batch_index, chunks) = if let Some(hash) = batch_hash { 208 | ( 209 | batch_index, 210 | chunk_query::fetch_by_batch_hash(&state.db_pool, &hash) 211 | .await 212 | .map_err(|e| api_err!(e))?, 213 | ) 214 | } else { 215 | (INVALID_INDEX, vec![]) 216 | }; 217 | let response = ChunksResponse::new(batch_index, chunks); 218 | 219 | // Save to cache. 220 | if let Err(error) = state 221 | .cache 222 | .set( 223 | &cache_key, 224 | Arc::new(response.clone()), 225 | Settings::get().cache_expired_secs, 226 | ) 227 | .await 228 | { 229 | log::error!("OpenAPI - Failed to save cache of {cache_key}: {error}"); 230 | } 231 | 232 | RESPONSE_TIME_COLLECTOR 233 | .with_label_values(&["chunks"]) 234 | .observe(response_time.elapsed().as_secs_f64()); 235 | 236 | Ok(Json(response)) 237 | } 238 | 239 | #[oai(path = "/chunk_blocks", method = "get")] 240 | async fn chunk_blocks( 241 | &self, 242 | state: Data<&State>, 243 | chunk_index: Query, 244 | ) -> Result> { 245 | let response_time = Instant::now(); 246 | INCOMING_REQUESTS.with_label_values(&["chunk_blocks"]).inc(); 247 | 248 | let chunk_index = chunk_index.0; 249 | 250 | // Return directly if cached. 251 | let cache_key = format!("blocks-of-chunk-{chunk_index}"); 252 | if let Some(response) = BlocksResponse::from_cache(state.cache.as_ref(), &cache_key).await { 253 | log::debug!("OpenAPI - Get blocks from Cache: {response:?}"); 254 | CACHE_HITS.with_label_values(&["chunk_blocks"]).inc(); 255 | 256 | RESPONSE_TIME_COLLECTOR 257 | .with_label_values(&["chunk_blocks"]) 258 | .observe(response_time.elapsed().as_secs_f64()); 259 | 260 | return Ok(Json(response)); 261 | }; 262 | 263 | let response = query_blocks_by_chunk_index(&state.db_pool, chunk_index).await?; 264 | 265 | // Save to cache. 266 | if let Err(error) = state 267 | .cache 268 | .set( 269 | &cache_key, 270 | Arc::new(response.clone()), 271 | Settings::get().cache_expired_secs, 272 | ) 273 | .await 274 | { 275 | log::error!("OpenAPI - Failed to save cache of {cache_key}: {error}"); 276 | } 277 | 278 | RESPONSE_TIME_COLLECTOR 279 | .with_label_values(&["chunk_blocks"]) 280 | .observe(response_time.elapsed().as_secs_f64()); 281 | 282 | Ok(Json(response)) 283 | } 284 | 285 | #[oai(path = "/last_batch_indexes", method = "get")] 286 | async fn last_batch_indexes( 287 | &self, 288 | state: Data<&State>, 289 | ) -> Result> { 290 | let response_time = Instant::now(); 291 | INCOMING_REQUESTS 292 | .with_label_values(&["last_batch_indexes"]) 293 | .inc(); 294 | 295 | // Return directly if cached. 296 | if let Some(response) = 297 | LastBatchIndexesResponse::from_cache(&state.cache, "last_batch_indexes").await 298 | { 299 | log::debug!("OpenAPI - Get last batch indexes from Cache: {response:?}"); 300 | CACHE_HITS.with_label_values(&["last_batch_indexes"]).inc(); 301 | 302 | RESPONSE_TIME_COLLECTOR 303 | .with_label_values(&["last_batch_indexes"]) 304 | .observe(response_time.elapsed().as_secs_f64()); 305 | 306 | return Ok(Json(response)); 307 | }; 308 | 309 | let status_indexes = batch_query::get_max_status_indexes(&state.db_pool) 310 | .await 311 | .map_err(|e| api_err!(e))?; 312 | let response = LastBatchIndexesResponse::new(status_indexes); 313 | 314 | // Save to cache. 315 | if let Err(error) = state 316 | .cache 317 | .set( 318 | "last_batch_indexes", 319 | Arc::new(response.clone()), 320 | Settings::get().cache_expired_secs, 321 | ) 322 | .await 323 | { 324 | log::error!("OpenAPI - Failed to save cache for last batch indexes: {error}"); 325 | } 326 | 327 | RESPONSE_TIME_COLLECTOR 328 | .with_label_values(&["last_batch_indexes"]) 329 | .observe(response_time.elapsed().as_secs_f64()); 330 | 331 | Ok(Json(response)) 332 | } 333 | 334 | // Parameter `keyword` should be a block number or block hash in `l2block` 335 | // table. 336 | #[oai(path = "/search", method = "get")] 337 | async fn search( 338 | &self, 339 | state: Data<&State>, 340 | keyword: Query, 341 | ) -> Result> { 342 | let response_time = Instant::now(); 343 | INCOMING_REQUESTS.with_label_values(&["search"]).inc(); 344 | 345 | let keyword = keyword.0; 346 | 347 | // Return directly if cached. 348 | let cache_key = format!("search-{keyword}"); 349 | if let Some(response) = SearchResponse::from_cache(state.cache.as_ref(), &cache_key).await { 350 | log::debug!("OpenAPI - Get blocks from Cache: {response:?}"); 351 | CACHE_HITS.with_label_values(&["search"]).inc(); 352 | 353 | RESPONSE_TIME_COLLECTOR 354 | .with_label_values(&["search"]) 355 | .observe(response_time.elapsed().as_secs_f64()); 356 | 357 | return Ok(Json(response)); 358 | }; 359 | 360 | // Consider `keyword` as block number if it is an integer, otherwise 361 | // consider as block hash (starts as `0x`). 362 | let batch_hash = match keyword.parse::() { 363 | Ok(block_num) => block_query::get_batch_hash_by_number(&state.db_pool, block_num) 364 | .await 365 | .map_err(|e| api_err!(e))?, 366 | Err(_) => block_query::get_batch_hash_by_block_hash(&state.db_pool, &keyword) 367 | .await 368 | .map_err(|e| api_err!(e))?, 369 | }; 370 | 371 | let batch_index = if let Some(hash) = batch_hash { 372 | batch_query::get_index_by_hash(&state.db_pool, &hash) 373 | .await 374 | .map_err(|e| api_err!(e))? 375 | .unwrap_or(INVALID_INDEX) 376 | } else { 377 | INVALID_INDEX 378 | }; 379 | let response = SearchResponse::new(batch_index); 380 | 381 | // Save to cache. 382 | if let Err(error) = state 383 | .cache 384 | .set( 385 | &cache_key, 386 | Arc::new(response.clone()), 387 | Settings::get().cache_expired_secs, 388 | ) 389 | .await 390 | { 391 | log::error!("OpenAPI - Failed to save cache of {cache_key}: {error}"); 392 | } 393 | 394 | RESPONSE_TIME_COLLECTOR 395 | .with_label_values(&["search"]) 396 | .observe(response_time.elapsed().as_secs_f64()); 397 | 398 | Ok(Json(response)) 399 | } 400 | } 401 | 402 | async fn query_blocks_by_batch_index(db_pool: &DbPool, batch_index: i64) -> Result { 403 | let batch_hash = batch_query::get_hash_by_index(db_pool, batch_index) 404 | .await 405 | .map_err(|e| api_err!(e))?; 406 | if batch_hash.is_none() { 407 | return Ok(BlocksResponse::from_batch_blocks(INVALID_INDEX, vec![])); 408 | } 409 | let batch_hash = batch_hash.unwrap(); 410 | 411 | let (start_block_num, end_block_num) = 412 | chunk_query::get_block_num_range_by_batch_hash(db_pool, &batch_hash) 413 | .await 414 | .map_err(|e| api_err!(e))?; 415 | 416 | let blocks = block_query::fetch_by_num_range(db_pool, start_block_num, end_block_num) 417 | .await 418 | .map_err(|e| api_err!(e))?; 419 | 420 | Ok(BlocksResponse::from_batch_blocks(batch_index, blocks)) 421 | } 422 | 423 | async fn query_blocks_by_chunk_index(db_pool: &DbPool, chunk_index: i64) -> Result { 424 | let chunk_hash = chunk_query::get_hash_by_index(db_pool, chunk_index) 425 | .await 426 | .map_err(|e| api_err!(e))?; 427 | if chunk_hash.is_none() { 428 | return Ok(BlocksResponse::from_chunk_blocks(INVALID_INDEX, vec![])); 429 | } 430 | let chunk_hash = chunk_hash.unwrap(); 431 | 432 | let blocks = block_query::fetch_by_chunk_hash(db_pool, &chunk_hash) 433 | .await 434 | .map_err(|e| api_err!(e))?; 435 | 436 | Ok(BlocksResponse::from_chunk_blocks(chunk_index, blocks)) 437 | } 438 | -------------------------------------------------------------------------------- /src/open_api/mod.rs: -------------------------------------------------------------------------------- 1 | use crate::{cache::Cache, db::DbPool, Settings}; 2 | use anyhow::Result; 3 | use futures::join; 4 | use lazy_static::lazy_static; 5 | use poem::{ 6 | endpoint::PrometheusExporter, 7 | listener::TcpListener, 8 | middleware::{Cors, TokioMetrics, Tracing}, 9 | EndpointExt, Route, Server, 10 | }; 11 | use poem_openapi::OpenApiService; 12 | use prometheus::{HistogramOpts, HistogramVec, IntCounterVec, Opts, Registry}; 13 | use sqlx::postgres::PgPoolOptions; 14 | use std::sync::Arc; 15 | 16 | mod apis; 17 | mod objects; 18 | mod responses; 19 | 20 | lazy_static! { 21 | pub static ref INCOMING_REQUESTS: IntCounterVec = IntCounterVec::new( 22 | Opts::new("incoming_requests", "Incoming Requests Hits"), 23 | &["api"] 24 | ) 25 | .unwrap(); 26 | pub static ref RESPONSE_TIME_COLLECTOR: HistogramVec = HistogramVec::new( 27 | HistogramOpts::new("response_time", "Response Times"), 28 | &["api"] 29 | ) 30 | .unwrap(); 31 | pub static ref CACHE_HITS: IntCounterVec = 32 | IntCounterVec::new(Opts::new("cache_hits", "Cache Hits"), &["api"]).unwrap(); 33 | } 34 | 35 | #[derive(Clone, Debug)] 36 | struct State { 37 | cache: Arc, 38 | db_pool: DbPool, 39 | } 40 | 41 | pub async fn run(cache: Arc) -> Result<()> { 42 | let settings = Settings::get(); 43 | let db_pool = PgPoolOptions::new() 44 | .max_connections(settings.max_db_conns) 45 | .connect(settings.db_url.as_str()) 46 | .await?; 47 | 48 | let state = State { cache, db_pool }; 49 | 50 | let open_api_addr = &settings.open_api_addr; 51 | let svr = OpenApiService::new(apis::Apis, "Scroll Rollup Explorer", "2.0") 52 | .server(format!("{open_api_addr}/api")); 53 | 54 | let tokio_metrics = TokioMetrics::new(); 55 | let ui = svr.swagger_ui(); 56 | let spec = svr.spec(); 57 | 58 | let metrics = Route::new() 59 | .at("/metrics", PrometheusExporter::new(prometheus_registry())) 60 | .at("/tokio_metrics", tokio_metrics.exporter()) 61 | // TODO: Fix to only allow specified origins. 62 | .with(Cors::new().allow_origins_fn(|_| true)) 63 | .with(Tracing); 64 | 65 | let app = Route::new() 66 | .nest("/", ui) 67 | .nest("/api", svr.with(tokio_metrics)) 68 | .at("/spec", poem::endpoint::make_sync(move |_| spec.clone())) 69 | // TODO: Fix to only allow specified origins. 70 | .with(Cors::new().allow_origins_fn(|_| true)) 71 | .data(state); 72 | 73 | let app_bind_addr = format!("0.0.0.0:{}", settings.bind_port); 74 | let metrics_bind_addr = format!("0.0.0.0:{}", settings.metrics_bind_port); 75 | let app_server = Server::new(TcpListener::bind(app_bind_addr)).run(app); 76 | let metrics_server = Server::new(TcpListener::bind(metrics_bind_addr)).run(metrics); 77 | 78 | let (app_result, metrics_result) = join!(app_server, metrics_server); 79 | if let Err(err) = app_result.and(metrics_result) { 80 | log::error!("An error occurred in run function: {err}"); 81 | } 82 | 83 | Ok(()) 84 | } 85 | 86 | fn prometheus_registry() -> Registry { 87 | let registry = Registry::new(); 88 | registry 89 | .register(Box::new(INCOMING_REQUESTS.clone())) 90 | .unwrap(); 91 | 92 | registry 93 | .register(Box::new(RESPONSE_TIME_COLLECTOR.clone())) 94 | .unwrap(); 95 | registry.register(Box::new(CACHE_HITS.clone())).unwrap(); 96 | 97 | registry 98 | } 99 | -------------------------------------------------------------------------------- /src/open_api/objects/batch.rs: -------------------------------------------------------------------------------- 1 | use crate::db::{models, RollupStatusType}; 2 | use poem_openapi::Object; 3 | use rust_decimal::Decimal; 4 | use std::fmt; 5 | 6 | #[derive(Clone, Debug)] 7 | pub enum RollupStatus { 8 | Precommitted, 9 | Committed, 10 | Finalized, 11 | Unknown, 12 | } 13 | 14 | impl fmt::Display for RollupStatus { 15 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 16 | let s = match self { 17 | Self::Precommitted => "precommitted", 18 | Self::Committed => "committed", 19 | Self::Finalized => "finalized", 20 | Self::Unknown => "unknown", 21 | }; 22 | write!(f, "{s}") 23 | } 24 | } 25 | 26 | impl From for RollupStatus { 27 | fn from(t: RollupStatusType) -> Self { 28 | match t { 29 | 1 | 2 => Self::Precommitted, 30 | 3 | 4 => Self::Committed, 31 | 5 => Self::Finalized, 32 | _ => Self::Unknown, 33 | } 34 | } 35 | } 36 | 37 | #[derive(Clone, Debug, Object)] 38 | pub struct Batch { 39 | hash: String, 40 | index: i64, 41 | start_chunk_index: i64, 42 | end_chunk_index: i64, 43 | start_block_number: i64, 44 | end_block_number: i64, 45 | total_tx_num: i64, 46 | rollup_status: String, 47 | start_chunk_hash: String, 48 | end_chunk_hash: String, 49 | commit_tx_hash: Option, 50 | finalize_tx_hash: Option, 51 | created_at: Decimal, 52 | committed_at: Option, 53 | finalized_at: Option, 54 | } 55 | 56 | impl From for Batch { 57 | fn from(batch: models::Batch) -> Self { 58 | Self { 59 | hash: batch.hash, 60 | index: batch.index, 61 | start_chunk_index: batch.start_chunk_index, 62 | end_chunk_index: batch.end_chunk_index, 63 | start_block_number: batch.start_block_number.unwrap_or_default(), 64 | end_block_number: batch.end_block_number.unwrap_or_default(), 65 | total_tx_num: batch.total_tx_num.unwrap_or_default(), 66 | rollup_status: RollupStatus::from(batch.rollup_status).to_string(), 67 | start_chunk_hash: batch.start_chunk_hash, 68 | end_chunk_hash: batch.end_chunk_hash, 69 | commit_tx_hash: batch.commit_tx_hash, 70 | finalize_tx_hash: batch.finalize_tx_hash, 71 | created_at: batch.created_at.timestamp().into(), 72 | committed_at: batch.committed_at.map(|t| t.timestamp().into()), 73 | finalized_at: batch.finalized_at.map(|t| t.timestamp().into()), 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/open_api/objects/block.rs: -------------------------------------------------------------------------------- 1 | use crate::db::models; 2 | use poem_openapi::Object; 3 | use rust_decimal::Decimal; 4 | 5 | #[derive(Clone, Debug, Object)] 6 | pub struct Block { 7 | number: i64, 8 | tx_num: i32, 9 | hash: String, 10 | block_timestamp: Decimal, 11 | } 12 | 13 | impl From for Block { 14 | fn from(l2_block: models::Block) -> Self { 15 | Self { 16 | number: l2_block.number, 17 | tx_num: l2_block.tx_num, 18 | hash: l2_block.hash, 19 | block_timestamp: l2_block.block_timestamp, 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/open_api/objects/chunk.rs: -------------------------------------------------------------------------------- 1 | use crate::db::models; 2 | use poem_openapi::Object; 3 | use rust_decimal::Decimal; 4 | 5 | #[derive(Clone, Debug, Object)] 6 | pub struct Chunk { 7 | hash: String, 8 | index: i64, 9 | start_block_number: i64, 10 | end_block_number: i64, 11 | total_tx_num: i32, 12 | created_at: Decimal, 13 | } 14 | 15 | impl From for Chunk { 16 | fn from(chunk: models::Chunk) -> Self { 17 | Self { 18 | hash: chunk.hash, 19 | index: chunk.index, 20 | start_block_number: chunk.start_block_number, 21 | end_block_number: chunk.end_block_number, 22 | total_tx_num: chunk.total_tx_num, 23 | created_at: chunk.created_at.timestamp().into(), 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/open_api/objects/mod.rs: -------------------------------------------------------------------------------- 1 | mod batch; 2 | mod block; 3 | mod chunk; 4 | 5 | pub use batch::*; 6 | pub use block::*; 7 | pub use chunk::*; 8 | -------------------------------------------------------------------------------- /src/open_api/responses/batch_response.rs: -------------------------------------------------------------------------------- 1 | use crate::{cache::*, db::models, open_api::objects::Batch}; 2 | use poem_openapi::Object; 3 | 4 | #[derive(Clone, Debug, Object)] 5 | pub struct BatchResponse { 6 | batch: Option, 7 | } 8 | 9 | impl BatchResponse { 10 | pub fn new(batch: Option) -> Self { 11 | let batch = batch.map(Into::into); 12 | 13 | Self { batch } 14 | } 15 | 16 | pub async fn from_cache(cache: &Cache, cache_key: &str) -> Option { 17 | from_cache(cache, cache_key).await 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/open_api/responses/batches_response.rs: -------------------------------------------------------------------------------- 1 | use crate::{cache::*, db::models, open_api::objects::Batch}; 2 | use poem_openapi::Object; 3 | 4 | #[derive(Clone, Debug, Object)] 5 | pub struct BatchesResponse { 6 | total: i64, 7 | batches: Vec, 8 | } 9 | 10 | impl BatchesResponse { 11 | pub fn new(total: i64, batches: Vec) -> Self { 12 | let batches = batches.into_iter().map(Into::into).collect(); 13 | 14 | Self { total, batches } 15 | } 16 | 17 | pub async fn from_cache(cache: &Cache, cache_key: &str) -> Option { 18 | from_cache(cache, cache_key).await 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/open_api/responses/blocks_response.rs: -------------------------------------------------------------------------------- 1 | use crate::{cache::*, db::models, open_api::objects::Block}; 2 | use poem_openapi::Object; 3 | 4 | #[derive(Clone, Debug, Object)] 5 | pub struct BlocksResponse { 6 | batch_index: Option, 7 | chunk_index: Option, 8 | blocks: Vec, 9 | } 10 | 11 | impl BlocksResponse { 12 | pub fn from_batch_blocks(batch_index: i64, blocks: Vec) -> Self { 13 | let blocks = blocks.into_iter().map(Into::into).collect(); 14 | 15 | Self { 16 | batch_index: Some(batch_index), 17 | chunk_index: None, 18 | blocks, 19 | } 20 | } 21 | pub fn from_chunk_blocks(chunk_index: i64, blocks: Vec) -> Self { 22 | let blocks = blocks.into_iter().map(Into::into).collect(); 23 | 24 | Self { 25 | batch_index: None, 26 | chunk_index: Some(chunk_index), 27 | blocks, 28 | } 29 | } 30 | 31 | pub async fn from_cache(cache: &Cache, cache_key: &str) -> Option { 32 | from_cache(cache, cache_key).await 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/open_api/responses/chunks_response.rs: -------------------------------------------------------------------------------- 1 | use crate::{cache::*, db::models, open_api::objects::Chunk}; 2 | use poem_openapi::Object; 3 | 4 | #[derive(Clone, Debug, Object)] 5 | pub struct ChunksResponse { 6 | batch_index: i64, 7 | chunks: Vec, 8 | } 9 | 10 | impl ChunksResponse { 11 | pub fn new(batch_index: i64, chunks: Vec) -> Self { 12 | let chunks = chunks.into_iter().map(Into::into).collect(); 13 | 14 | Self { 15 | batch_index, 16 | chunks, 17 | } 18 | } 19 | 20 | pub async fn from_cache(cache: &Cache, cache_key: &str) -> Option { 21 | from_cache(cache, cache_key).await 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/open_api/responses/last_batch_indexes_response.rs: -------------------------------------------------------------------------------- 1 | use crate::{cache::*, db::RollupStatusType, open_api::objects::RollupStatus}; 2 | use poem_openapi::Object; 3 | use std::collections::HashMap; 4 | 5 | #[derive(Clone, Debug, Object)] 6 | pub struct LastBatchIndexesResponse { 7 | all_index: i64, 8 | committed_index: i64, 9 | finalized_index: i64, 10 | } 11 | 12 | impl LastBatchIndexesResponse { 13 | pub fn new(status_indexes: HashMap) -> Self { 14 | let mut all_index = 0; 15 | let mut committed_index = 0; 16 | let mut finalized_index = 0; 17 | 18 | for (status, index) in status_indexes.into_iter() { 19 | all_index = all_index.max(index); 20 | match status.into() { 21 | RollupStatus::Committed => committed_index = committed_index.max(index), 22 | RollupStatus::Finalized => finalized_index = finalized_index.max(index), 23 | _ => (), 24 | } 25 | } 26 | 27 | // Set `committed` index as maximum index of both committed and 28 | // finalized batches. 29 | committed_index = committed_index.max(finalized_index); 30 | 31 | Self { 32 | all_index, 33 | committed_index, 34 | finalized_index, 35 | } 36 | } 37 | 38 | pub async fn from_cache(cache: &Cache, cache_key: &str) -> Option { 39 | from_cache(cache, cache_key).await 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/open_api/responses/mod.rs: -------------------------------------------------------------------------------- 1 | mod batch_response; 2 | mod batches_response; 3 | mod blocks_response; 4 | mod chunks_response; 5 | mod last_batch_indexes_response; 6 | mod search_response; 7 | 8 | pub use batch_response::*; 9 | pub use batches_response::*; 10 | pub use blocks_response::*; 11 | pub use chunks_response::*; 12 | pub use last_batch_indexes_response::*; 13 | pub use search_response::*; 14 | -------------------------------------------------------------------------------- /src/open_api/responses/search_response.rs: -------------------------------------------------------------------------------- 1 | use crate::cache::*; 2 | use poem_openapi::Object; 3 | 4 | #[derive(Clone, Debug, Object)] 5 | pub struct SearchResponse { 6 | batch_index: i64, 7 | } 8 | 9 | impl SearchResponse { 10 | pub fn new(batch_index: i64) -> Self { 11 | Self { batch_index } 12 | } 13 | 14 | pub async fn from_cache(cache: &Cache, cache_key: &str) -> Option { 15 | from_cache(cache, cache_key).await 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/settings.rs: -------------------------------------------------------------------------------- 1 | use crate::consts::DEFAULT_CACHE_EXPIRED_SECS; 2 | use anyhow::{anyhow, Result}; 3 | use config::{Config, Environment, File}; 4 | use serde::Deserialize; 5 | use std::{env, sync::OnceLock}; 6 | 7 | const DEFAULT_BIND_PORT: &str = "5001"; 8 | const DEFAULT_METRICS_BIND_PORT: &str = "6001"; 9 | const DEFAULT_MAX_CONNS: u32 = 200; 10 | 11 | static SETTINGS: OnceLock = OnceLock::new(); 12 | 13 | #[derive(Debug, Deserialize)] 14 | pub struct Settings { 15 | /// Internal HTTP bind port (5001 as default) 16 | pub bind_port: String, 17 | /// Internal HTTP metrics bind port (6001 as default) 18 | pub metrics_bind_port: String, 19 | /// As format of `postgres://USERNAME:PASSWORD@DB_HOST:DB_PORT/DATABASE` 20 | pub db_url: String, 21 | /// As format of `HTTP_HOST:HTTP_PORT` 22 | pub open_api_addr: String, 23 | /// Max value of query parameter `per_page` (100 as default) 24 | pub max_per_page: u64, 25 | /// Max DB connections (1000 as default) 26 | pub max_db_conns: u32, 27 | /// Expired cache seconds 28 | pub cache_expired_secs: u64, 29 | } 30 | 31 | impl Settings { 32 | pub fn init() -> Result<()> { 33 | let bind_port = env::var("BIND_PORT").unwrap_or_else(|_| DEFAULT_BIND_PORT.into()); 34 | let metrics_bind_port = 35 | env::var("METRICS_BIND_PORT").unwrap_or_else(|_| DEFAULT_METRICS_BIND_PORT.into()); 36 | let max_db_conns = env::var("MAX_DB_CONNS").map_or_else( 37 | |_| DEFAULT_MAX_CONNS, 38 | |conns| conns.parse::().ok().unwrap_or(DEFAULT_MAX_CONNS), 39 | ); 40 | let cache_expired_secs = env::var("CACHE_EXPIRED_SECS").map_or_else( 41 | |_| DEFAULT_CACHE_EXPIRED_SECS, 42 | |secs| { 43 | secs.parse::() 44 | .ok() 45 | .unwrap_or(DEFAULT_CACHE_EXPIRED_SECS) 46 | }, 47 | ); 48 | let config = Config::builder() 49 | .set_default("bind_port", bind_port)? 50 | .set_default("metrics_bind_port", metrics_bind_port)? 51 | .set_default("max_per_page", 100)? 52 | .set_default("max_db_conns", max_db_conns)? 53 | .set_default("cache_expired_secs", cache_expired_secs)? 54 | .add_source(File::with_name("config/config.json")) 55 | .add_source(Environment::default()) 56 | .build()?; 57 | 58 | let settings: Settings = config.try_deserialize()?; 59 | SETTINGS 60 | .set(settings) 61 | .map_err(|s| anyhow!("Wrong settings: {:?}", s))?; 62 | 63 | Ok(()) 64 | } 65 | 66 | pub fn get() -> &'static Self { 67 | SETTINGS.get().unwrap() 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /third-parties/scroll/database/migrate/migrations/00001_l1_message.sql: -------------------------------------------------------------------------------- 1 | -- +goose Up 2 | -- +goose StatementBegin 3 | create table l1_message 4 | ( 5 | queue_index BIGINT NOT NULL, 6 | msg_hash VARCHAR NOT NULL, 7 | height BIGINT NOT NULL, 8 | gas_limit BIGINT NOT NULL, 9 | sender VARCHAR NOT NULL, 10 | target VARCHAR NOT NULL, 11 | value VARCHAR NOT NULL, 12 | calldata TEXT NOT NULL, 13 | layer1_hash VARCHAR NOT NULL, 14 | layer2_hash VARCHAR DEFAULT NULL, 15 | status INTEGER NOT NULL DEFAULT 1, 16 | 17 | -- metadata 18 | created_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, 19 | updated_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, 20 | deleted_at TIMESTAMP(0) DEFAULT NULL 21 | ); 22 | 23 | comment 24 | on column l1_message.status is 'undefined, pending, submitted, confirmed, failed, expired, relay_failed'; 25 | 26 | create unique index l1_message_hash_uindex 27 | on l1_message (msg_hash); 28 | 29 | create unique index l1_message_nonce_uindex 30 | on l1_message (queue_index); 31 | 32 | create index l1_message_height_index 33 | on l1_message (height); 34 | 35 | -- +goose StatementEnd 36 | 37 | -- +goose Down 38 | -- +goose StatementBegin 39 | drop table if exists l1_message; 40 | -- +goose StatementEnd -------------------------------------------------------------------------------- /third-parties/scroll/database/migrate/migrations/00002_l1_block.sql: -------------------------------------------------------------------------------- 1 | -- +goose Up 2 | -- +goose StatementBegin 3 | 4 | create table l1_block 5 | ( 6 | -- block 7 | number BIGINT NOT NULL, 8 | hash VARCHAR NOT NULL, 9 | base_fee BIGINT NOT NULL, 10 | 11 | -- import 12 | block_status SMALLINT NOT NULL DEFAULT 1, 13 | import_tx_hash VARCHAR DEFAULT NULL, 14 | 15 | -- oracle 16 | oracle_status SMALLINT NOT NULL DEFAULT 1, 17 | oracle_tx_hash VARCHAR DEFAULT NULL, 18 | 19 | -- metadata 20 | created_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, 21 | updated_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, 22 | deleted_at TIMESTAMP(0) DEFAULT NULL 23 | ); 24 | 25 | comment 26 | on column l1_block.block_status is 'undefined, pending, importing, imported, failed'; 27 | 28 | comment 29 | on column l1_block.oracle_status is 'undefined, pending, importing, imported, failed'; 30 | 31 | create unique index l1_block_hash_uindex 32 | on l1_block (hash); 33 | 34 | create unique index l1_block_number_uindex 35 | on l1_block (number); 36 | 37 | -- +goose StatementEnd 38 | 39 | -- +goose Down 40 | -- +goose StatementBegin 41 | drop table if exists l1_block; 42 | -- +goose StatementEnd 43 | -------------------------------------------------------------------------------- /third-parties/scroll/database/migrate/migrations/00003_l2_block.sql: -------------------------------------------------------------------------------- 1 | -- +goose Up 2 | -- +goose StatementBegin 3 | 4 | create table l2_block 5 | ( 6 | -- block 7 | number BIGINT NOT NULL, 8 | hash VARCHAR NOT NULL, 9 | parent_hash VARCHAR NOT NULL, 10 | header TEXT NOT NULL, 11 | transactions TEXT NOT NULL, 12 | withdraw_trie_root VARCHAR NOT NULL, 13 | tx_num INTEGER NOT NULL, 14 | gas_used BIGINT NOT NULL, 15 | block_timestamp NUMERIC NOT NULL, 16 | 17 | -- chunk 18 | chunk_hash VARCHAR DEFAULT NULL, 19 | 20 | -- metadata 21 | created_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, 22 | updated_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, 23 | deleted_at TIMESTAMP(0) DEFAULT NULL 24 | ); 25 | 26 | create unique index l2_block_hash_uindex 27 | on l2_block (hash); 28 | 29 | create unique index l2_block_number_uindex 30 | on l2_block (number); 31 | 32 | create index l2_block_chunk_hash_index 33 | on l2_block (chunk_hash); 34 | 35 | -- +goose StatementEnd 36 | 37 | -- +goose Down 38 | -- +goose StatementBegin 39 | drop table if exists l2_block; 40 | -- +goose StatementEnd 41 | -------------------------------------------------------------------------------- /third-parties/scroll/database/migrate/migrations/00004_chunk.sql: -------------------------------------------------------------------------------- 1 | -- +goose Up 2 | -- +goose StatementBegin 3 | 4 | create table chunk 5 | ( 6 | -- chunk 7 | index BIGINT NOT NULL, 8 | hash VARCHAR NOT NULL, 9 | start_block_number BIGINT NOT NULL, 10 | start_block_hash VARCHAR NOT NULL, 11 | end_block_number BIGINT NOT NULL, 12 | end_block_hash VARCHAR NOT NULL, 13 | total_l1_messages_popped_before BIGINT NOT NULL, 14 | total_l1_messages_popped_in_chunk INTEGER NOT NULL, 15 | start_block_time BIGINT NOT NULL, 16 | 17 | -- proof 18 | proving_status SMALLINT NOT NULL DEFAULT 1, 19 | proof BYTEA DEFAULT NULL, 20 | prover_assigned_at TIMESTAMP(0) DEFAULT NULL, 21 | proved_at TIMESTAMP(0) DEFAULT NULL, 22 | proof_time_sec INTEGER DEFAULT NULL, 23 | 24 | -- batch 25 | batch_hash VARCHAR DEFAULT NULL, 26 | 27 | -- metadata 28 | total_l2_tx_gas BIGINT NOT NULL, 29 | total_l2_tx_num INTEGER NOT NULL, 30 | total_l1_commit_calldata_size INTEGER NOT NULL, 31 | total_l1_commit_gas BIGINT NOT NULL, 32 | created_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, 33 | updated_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, 34 | deleted_at TIMESTAMP(0) DEFAULT NULL 35 | ); 36 | 37 | comment 38 | on column chunk.proving_status is 'undefined, unassigned, assigned, proved, verified, failed'; 39 | 40 | create unique index chunk_index_uindex 41 | on chunk (index); 42 | 43 | create unique index chunk_hash_uindex 44 | on chunk (hash); 45 | 46 | create index batch_hash_index 47 | on chunk (batch_hash); 48 | 49 | -- +goose StatementEnd 50 | 51 | -- +goose Down 52 | -- +goose StatementBegin 53 | drop table if exists chunk; 54 | -- +goose StatementEnd 55 | -------------------------------------------------------------------------------- /third-parties/scroll/database/migrate/migrations/00005_batch.sql: -------------------------------------------------------------------------------- 1 | -- +goose Up 2 | -- +goose StatementBegin 3 | 4 | create table batch 5 | ( 6 | -- batch 7 | index BIGINT NOT NULL, 8 | hash VARCHAR NOT NULL, 9 | start_chunk_index BIGINT NOT NULL, 10 | start_chunk_hash VARCHAR NOT NULL, 11 | end_chunk_index BIGINT NOT NULL, 12 | end_chunk_hash VARCHAR NOT NULL, 13 | state_root VARCHAR NOT NULL, 14 | withdraw_root VARCHAR NOT NULL, 15 | batch_header BYTEA NOT NULL, 16 | 17 | -- proof 18 | chunk_proofs_status SMALLINT NOT NULL DEFAULT 1, 19 | proving_status SMALLINT NOT NULL DEFAULT 1, 20 | proof BYTEA DEFAULT NULL, 21 | prover_assigned_at TIMESTAMP(0) DEFAULT NULL, 22 | proved_at TIMESTAMP(0) DEFAULT NULL, 23 | proof_time_sec INTEGER DEFAULT NULL, 24 | 25 | -- rollup 26 | rollup_status SMALLINT NOT NULL DEFAULT 1, 27 | commit_tx_hash VARCHAR DEFAULT NULL, 28 | committed_at TIMESTAMP(0) DEFAULT NULL, 29 | finalize_tx_hash VARCHAR DEFAULT NULL, 30 | finalized_at TIMESTAMP(0) DEFAULT NULL, 31 | 32 | -- gas oracle 33 | oracle_status SMALLINT NOT NULL DEFAULT 1, 34 | oracle_tx_hash VARCHAR DEFAULT NULL, 35 | 36 | -- metadata 37 | created_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, 38 | updated_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, 39 | deleted_at TIMESTAMP(0) DEFAULT NULL 40 | ); 41 | 42 | create unique index batch_index_uindex 43 | on batch (index); 44 | 45 | create unique index batch_hash_uindex 46 | on batch (hash); 47 | 48 | comment 49 | on column batch.chunk_proofs_status is 'undefined, pending, ready'; 50 | 51 | comment 52 | on column batch.proving_status is 'undefined, unassigned, assigned, proved, verified, failed'; 53 | 54 | comment 55 | on column batch.rollup_status is 'undefined, pending, committing, committed, finalizing, finalized, commit_failed, finalize_failed'; 56 | 57 | -- +goose StatementEnd 58 | 59 | -- +goose Down 60 | -- +goose StatementBegin 61 | drop table if exists batch; 62 | -- +goose StatementEnd 63 | -------------------------------------------------------------------------------- /third-parties/scroll/database/migrate/migrations/00006_prover_task.sql: -------------------------------------------------------------------------------- 1 | -- +goose Up 2 | -- +goose StatementBegin 3 | 4 | create table prover_task 5 | ( 6 | id BIGSERIAL PRIMARY KEY, 7 | 8 | -- prover 9 | prover_public_key VARCHAR NOT NULL, 10 | prover_name VARCHAR NOT NULL, 11 | 12 | -- task 13 | task_id VARCHAR NOT NULL, 14 | task_type SMALLINT NOT NULL DEFAULT 0, 15 | 16 | -- status 17 | proving_status SMALLINT NOT NULL DEFAULT 0, 18 | failure_type SMALLINT NOT NULL DEFAULT 0, 19 | reward DECIMAL(78, 0) NOT NULL DEFAULT 0, 20 | proof BYTEA DEFAULT NULL, 21 | 22 | -- metadata 23 | created_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, 24 | updated_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, 25 | deleted_at TIMESTAMP(0) DEFAULT NULL, 26 | 27 | CONSTRAINT uk_tasktype_taskid_publickey UNIQUE (task_type, task_id, prover_public_key) 28 | ); 29 | 30 | comment 31 | on column prover_task.task_type is 'undefined, chunk, batch'; 32 | 33 | comment 34 | on column prover_task.proving_status is 'undefined, roller assigned, roller proof valid, roller proof invalid'; 35 | 36 | comment 37 | on column prover_task.failure_type is 'undefined'; 38 | 39 | -- +goose StatementEnd 40 | 41 | -- +goose Down 42 | -- +goose StatementBegin 43 | drop table if exists prover_task; 44 | -- +goose StatementEnd 45 | --------------------------------------------------------------------------------