diff --git a/.cargo/config.toml b/.cargo/config.toml index 70f9eae..72817e9 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,2 +1,5 @@ [registries.crates-io] protocol = "sparse" + +[build] +rustflags = ["--cfg", "tokio_unstable"] diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 6d77d02..757d616 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -14,7 +14,7 @@ env: RELEASE: | ${{ github.event.pull_request.merged == true || - github.ref_name =='main' || + github.ref_name == 'main' || github.ref_type == 'tag' }} diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index aaeff3b..10e36d4 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -36,7 +36,7 @@ jobs: strategy: matrix: rust: [ - 1.70.0, + 1.76.0, nightly ] @@ -58,7 +58,7 @@ jobs: strategy: matrix: rust: [ - 1.70.0, + 1.76.0, nightly ] diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a3fcc0..eb05ac1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,9 +11,19 @@ Book](https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field) ### Added - A batteries-included payment gateway built around the core library. +- `get_ids()` method to invoice stores. +- `is_empty()` method to invoice stores. +- `is_paid()` method to `PaymentGateway`. +- `get_invoice_ids()` method to `PaymentGateway`. +- `build_with_mock_daemon()` method to `PaymentGateway`. ### Changed -- Update MSRV to 1.68 +- Update MSRV to 1.76 +- Replace invoice store `try_iter()` method with `try_for_each()`. + +### Fixed +- `is_expired` returning false when invoice is awaiting configrmation despite it + being expired. ## [0.13.0] - 2023-07-23 diff --git a/Cargo.lock b/Cargo.lock index 40ccad4..ea98f08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 3 [[package]] name = "acceptxmr" -version = "0.13.0" +version = "0.14.0" dependencies = [ "acceptxmr", "actix", @@ -12,29 +12,33 @@ dependencies = [ "actix-session", "actix-web", "actix-web-actors", + "backoff", "bincode", + "blake3", + "bytes", "bytestring", "env_logger", "handlebars", "hex", - "http", - "httpmock", - "hyper", + "http-body-util", + "hyper 1.4.0", "hyper-rustls", - "indexmap 2.0.2", + "hyper-util", + "indexmap 2.2.6", "log", "md-5", "monero", "qrcode", "rand", "rand_chacha", + "rayon", "serde", "serde_json", "sled", "sqlite", "strum", - "tempfile", "test-case", + "testing-utils", "thiserror", "tokio", ] @@ -44,48 +48,53 @@ name = "acceptxmr-server" version = "0.1.0" dependencies = [ "acceptxmr", - "actix", - "actix-files", - "actix-session", - "actix-web", - "actix-web-actors", - "actix-web-httpauth", - "anyhow", - "bytestring", + "axum", + "base64 0.22.1", + "bytes", "clap", "dotenv", "env_logger", "futures", - "http", - "hyper", + "futures-util", + "http-body-util", + "hyper 1.4.0", "hyper-rustls", + "hyper-util", "log", + "mime", "monero", "rand", "rand_chacha", "rcgen", - "rustls", "rustls-pemfile", "secrecy", "serde", "serde_json", "serde_with", "serde_yaml", + "tera", "test-case", + "testing-utils", "thiserror", "tokio", + "tokio-rustls", + "tokio-tungstenite", + "tower", + "tower-http", + "utoipa", + "utoipa-swagger-ui", ] [[package]] name = "actix" -version = "0.13.1" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cba56612922b907719d4a01cf11c8d5b458e7d3dba946d0435f20f58d6795ed2" +checksum = "de7fa236829ba0841304542f7614c42b80fca007455315c45c785ccfa873a85b" dependencies = [ "actix-macros", "actix-rt", "actix_derive", - "bitflags 2.4.1", + "bitflags 2.6.0", "bytes", "crossbeam-channel", "futures-core", @@ -94,7 +103,7 @@ dependencies = [ "futures-util", "log", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "pin-project-lite", "smallvec", "tokio", @@ -103,11 +112,11 @@ dependencies = [ [[package]] name = "actix-codec" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8" +checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "bytes", "futures-core", "futures-sink", @@ -120,16 +129,15 @@ dependencies = [ [[package]] name = "actix-files" -version = "0.6.2" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d832782fac6ca7369a70c9ee9a20554623c5e51c76e190ad151780ebea1cf689" +checksum = "0773d59061dedb49a8aed04c67291b9d8cf2fe0b60130a381aab53c6dd86e9be" dependencies = [ "actix-http", "actix-service", "actix-utils", "actix-web", - "askama_escape", - "bitflags 1.3.2", + "bitflags 2.6.0", "bytes", "derive_more", "futures-core", @@ -139,22 +147,22 @@ dependencies = [ "mime_guess", "percent-encoding", "pin-project-lite", + "v_htmlescape", ] [[package]] name = "actix-http" -version = "3.4.0" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92ef85799cba03f76e4f7c10f533e66d87c9a7e7055f3391f09000ad8351bc9" +checksum = "3ae682f693a9cd7b058f2b0b5d9a6d7728a8555779bedbbc35dd88528611d020" dependencies = [ "actix-codec", "actix-rt", "actix-service", - "actix-tls", "actix-utils", "ahash", - "base64 0.21.4", - "bitflags 2.4.1", + "base64 0.22.1", + "bitflags 2.6.0", "brotli", "bytes", "bytestring", @@ -162,8 +170,8 @@ dependencies = [ "encoding_rs", "flate2", "futures-core", - "h2", - "http", + "h2 0.3.26", + "http 0.2.12", "httparse", "httpdate", "itoa", @@ -188,27 +196,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.38", + "syn 2.0.68", ] [[package]] name = "actix-router" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799" +checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" dependencies = [ "bytestring", - "http", + "cfg-if", + "http 0.2.12", "regex", + "regex-lite", "serde", "tracing", ] [[package]] name = "actix-rt" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d" +checksum = "24eda4e2a6e042aa4e55ac438a2ae052d3b5da0ecf83d7411e1a368946925208" dependencies = [ "futures-core", "tokio", @@ -216,9 +226,9 @@ dependencies = [ [[package]] name = "actix-server" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb13e7eef0423ea6eab0e59f6c72e7cb46d33691ad56a726b3cd07ddec2c2d4" +checksum = "b02303ce8d4e8be5b855af6cf3c3a08f3eff26880faad82bab679c22d3650cb5" dependencies = [ "actix-rt", "actix-service", @@ -226,7 +236,7 @@ dependencies = [ "futures-core", "futures-util", "mio", - "socket2 0.5.4", + "socket2 0.5.7", "tokio", "tracing", ] @@ -244,42 +254,20 @@ dependencies = [ [[package]] name = "actix-session" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e6a28f813a6671e1847d005cad0be36ae4d016287690f765c303379837c13d6" +checksum = "b671404ec72194d8af58c2bdaf51e3c477a0595056bd5010148405870dda8df2" dependencies = [ "actix-service", "actix-utils", "actix-web", "anyhow", - "async-trait", "derive_more", "serde", "serde_json", "tracing", ] -[[package]] -name = "actix-tls" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72616e7fbec0aa99c6f3164677fa48ff5a60036d0799c98cab894a44f3e0efc3" -dependencies = [ - "actix-rt", - "actix-service", - "actix-utils", - "futures-core", - "impl-more", - "pin-project-lite", - "rustls", - "rustls-webpki 0.101.6", - "tokio", - "tokio-rustls", - "tokio-util", - "tracing", - "webpki-roots 0.25.2", -] - [[package]] name = "actix-utils" version = "3.0.1" @@ -292,9 +280,9 @@ dependencies = [ [[package]] name = "actix-web" -version = "4.4.0" +version = "4.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4a5b5e29603ca8c94a77c65cf874718ceb60292c5a5c3e5f4ace041af462b9" +checksum = "1988c02af8d2b718c05bc4aeb6a66395b7cdf32858c2c71131e5637a8c05a9ff" dependencies = [ "actix-codec", "actix-http", @@ -303,7 +291,6 @@ dependencies = [ "actix-rt", "actix-server", "actix-service", - "actix-tls", "actix-utils", "actix-web-codegen", "ahash", @@ -322,20 +309,21 @@ dependencies = [ "once_cell", "pin-project-lite", "regex", + "regex-lite", "serde", "serde_json", "serde_urlencoded", "smallvec", - "socket2 0.5.4", + "socket2 0.5.7", "time", "url", ] [[package]] name = "actix-web-actors" -version = "4.2.0" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf6e9ccc371cfddbed7aa842256a4abc7a6dcac9f3fce392fe1d0f68cfd136b2" +checksum = "420b001bb709d8510c3e2659dae046e54509ff9528018d09c78381e765a1f9fa" dependencies = [ "actix", "actix-codec", @@ -351,29 +339,14 @@ dependencies = [ [[package]] name = "actix-web-codegen" -version = "4.2.2" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1f50ebbb30eca122b188319a4398b3f7bb4a8cdf50ecfb73bfc6a3c3ce54f5" +checksum = "f591380e2e68490b5dfaf1dd1aa0ebe78d84ba7067078512b4ea6e4492d622b8" dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.38", -] - -[[package]] -name = "actix-web-httpauth" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d613edf08a42ccc6864c941d30fe14e1b676a77d16f1dbadc1174d065a0a775" -dependencies = [ - "actix-utils", - "actix-web", - "base64 0.21.4", - "futures-core", - "futures-util", - "log", - "pin-project-lite", + "syn 2.0.68", ] [[package]] @@ -384,14 +357,14 @@ checksum = "7c7db3d5a9718568e4cf4a537cfd7070e6e6ff7481510d0237fb529ac850f6d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.68", ] [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -414,9 +387,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", @@ -439,21 +412,22 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "getrandom", "once_cell", "version_check", + "zerocopy", ] [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -490,57 +464,70 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "ascii-canvas" @@ -551,12 +538,6 @@ dependencies = [ "term", ] -[[package]] -name = "askama_escape" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" - [[package]] name = "assert-json-diff" version = "2.0.2" @@ -567,6 +548,16 @@ dependencies = [ "serde_json", ] +[[package]] +name = "async-attributes" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "async-channel" version = "1.9.0" @@ -578,32 +569,43 @@ dependencies = [ "futures-core", ] +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + [[package]] name = "async-executor" -version = "1.5.4" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1da3ae8dabd9c00f453a329dfe1fb28da3c0a72e2478cdcd93171740c20499" +checksum = "c8828ec6e544c02b0d6691d21ed9f9218d0384a82542855073c2a3f58304aaf0" dependencies = [ - "async-lock", "async-task", "concurrent-queue", - "fastrand 2.0.1", - "futures-lite", + "fastrand 2.1.0", + "futures-lite 2.3.0", "slab", ] [[package]] name = "async-global-executor" -version = "2.3.1" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ - "async-channel", + "async-channel 2.3.1", "async-executor", - "async-io", - "async-lock", + "async-io 2.3.3", + "async-lock 3.4.0", "blocking", - "futures-lite", + "futures-lite 2.3.0", "once_cell", ] @@ -613,20 +615,39 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" dependencies = [ - "async-lock", + "async-lock 2.8.0", "autocfg", "cfg-if", "concurrent-queue", - "futures-lite", + "futures-lite 1.13.0", "log", "parking", - "polling", - "rustix 0.37.25", + "polling 2.8.0", + "rustix 0.37.27", "slab", - "socket2 0.4.9", + "socket2 0.4.10", "waker-fn", ] +[[package]] +name = "async-io" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" +dependencies = [ + "async-lock 3.4.0", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite 2.3.0", + "parking", + "polling 3.7.2", + "rustix 0.38.34", + "slab", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "async-lock" version = "2.8.0" @@ -636,6 +657,17 @@ dependencies = [ "event-listener 2.5.3", ] +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener 5.3.1", + "event-listener-strategy", + "pin-project-lite", +] + [[package]] name = "async-object-pool" version = "0.1.4" @@ -651,33 +683,33 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" dependencies = [ - "async-io", - "async-lock", + "async-io 1.13.0", + "async-lock 2.8.0", "async-signal", "blocking", "cfg-if", - "event-listener 3.0.0", - "futures-lite", - "rustix 0.38.19", - "windows-sys", + "event-listener 3.1.0", + "futures-lite 1.13.0", + "rustix 0.38.34", + "windows-sys 0.48.0", ] [[package]] name = "async-signal" -version = "0.2.4" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2a5415b7abcdc9cd7d63d6badba5288b2ca017e3fbd4173b8f405449f1a2399" +checksum = "794f185324c2f00e771cd9f1ae8b5ac68be2ca7abb129a87afd6e86d228bc54d" dependencies = [ - "async-io", - "async-lock", + "async-io 2.3.3", + "async-lock 3.4.0", "atomic-waker", "cfg-if", "futures-core", "futures-io", - "rustix 0.38.19", + "rustix 0.38.34", "signal-hook-registry", "slab", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -686,16 +718,17 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" dependencies = [ - "async-channel", + "async-attributes", + "async-channel 1.9.0", "async-global-executor", - "async-io", - "async-lock", + "async-io 1.13.0", + "async-lock 2.8.0", "async-process", "crossbeam-utils", "futures-channel", "futures-core", "futures-io", - "futures-lite", + "futures-lite 1.13.0", "gloo-timers", "kv-log-macro", "log", @@ -709,19 +742,19 @@ dependencies = [ [[package]] name = "async-task" -version = "4.4.1" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9441c6b2fe128a7c2bf680a44c34d0df31ce09e5b7e401fcca3faa483dbc921" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.68", ] [[package]] @@ -732,15 +765,100 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "axum" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" +dependencies = [ + "async-trait", + "axum-core", + "axum-macros", + "base64 0.21.7", + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "hyper 1.4.0", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sha1", + "sync_wrapper 1.0.1", + "tokio", + "tokio-tungstenite", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper 0.1.2", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00c055ee2d014ae5981ce1016374e8213682aa14d9bf40e48ab48b5f3ef20eaa" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "backoff" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" +dependencies = [ + "futures-core", + "getrandom", + "instant", + "pin-project-lite", + "rand", + "tokio", +] [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", @@ -768,15 +886,21 @@ checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "basic-cookies" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb53b6b315f924c7f113b162e53b3901c05fc9966baf84d201dfcc7432a4bb38" +checksum = "67bd8fd42c16bdb08688243dc5f0cc117a3ca9efeeaba3a345a18a6159ad96f7" dependencies = [ "lalrpop", "lalrpop-util", @@ -825,9 +949,22 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "blake3" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] [[package]] name = "block-buffer" @@ -840,25 +977,22 @@ dependencies = [ [[package]] name = "blocking" -version = "1.4.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c36a4d0d48574b3dd360b4b7d95cc651d2b6557b6402848a27d4b228a473e2a" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" dependencies = [ - "async-channel", - "async-lock", + "async-channel 2.3.1", "async-task", - "fastrand 2.0.1", "futures-io", - "futures-lite", + "futures-lite 2.3.0", "piper", - "tracing", ] [[package]] name = "brotli" -version = "3.4.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" +checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -867,25 +1001,35 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.5.0" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da74e2b81409b1b743f8f0c62cc6254afefb8b8e50bbfe3735550f7aeefa3448" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", ] +[[package]] +name = "bstr" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.14.0" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" [[package]] name = "byteorder" @@ -895,33 +1039,28 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "bytestring" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238e4886760d98c4f899360c834fa93e62cf7f721ac3c2da375cbdf4b8679aae" +checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72" dependencies = [ "bytes", ] -[[package]] -name = "castaway" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6" - [[package]] name = "cc" -version = "1.0.83" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490" dependencies = [ "jobserver", "libc", + "once_cell", ] [[package]] @@ -930,23 +1069,39 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "checked_int_cast" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cc5e6b5ab06331c33589842070416baa137e8b0eb912b008cfd4a78ada7919" - [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", "serde", - "windows-targets", + "windows-targets 0.52.5", +] + +[[package]] +name = "chrono-tz" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93698b29de5e97ad0ae26447b344c482a7284c737d9ddc5f9e52b74a336671bb" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf", +] + +[[package]] +name = "chrono-tz-build" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c088aee841df9c3041febbb73934cfc39708749bf96dc827e3359cd39ef11b1" +dependencies = [ + "parse-zoneinfo", + "phf", + "phf_codegen", ] [[package]] @@ -961,18 +1116,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.6" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" +checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.4.6" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" +checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708" dependencies = [ "anstream", "anstyle", @@ -982,9 +1137,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" [[package]] name = "color_quant" @@ -994,19 +1149,25 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "concurrent-queue" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ "crossbeam-utils", ] +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + [[package]] name = "convert_case" version = "0.4.0" @@ -1033,62 +1194,64 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] -name = "crossbeam-epoch" -version = "0.9.15" +name = "crossbeam-deque" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "autocfg", - "cfg-if", + "crossbeam-epoch", "crossbeam-utils", - "memoffset", - "scopeguard", ] [[package]] -name = "crossbeam-utils" -version = "0.8.16" +name = "crossbeam-epoch" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "cfg-if", + "crossbeam-utils", ] [[package]] -name = "crunchy" +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" @@ -1113,48 +1276,16 @@ dependencies = [ "cipher", ] -[[package]] -name = "curl" -version = "0.4.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" -dependencies = [ - "curl-sys", - "libc", - "openssl-probe", - "openssl-sys", - "schannel", - "socket2 0.4.9", - "winapi", -] - -[[package]] -name = "curl-sys" -version = "0.4.68+curl-8.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4a0d18d88360e374b16b2273c832b5e57258ffc1d4aa4f96b108e0738d5752f" -dependencies = [ - "cc", - "libc", - "libnghttp2-sys", - "libz-sys", - "openssl-sys", - "pkg-config", - "vcpkg", - "windows-sys", -] - [[package]] name = "curve25519-dalek" -version = "4.1.1" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", "fiat-crypto", - "platforms", "rustc_version", "serde", "subtle", @@ -1163,20 +1294,20 @@ dependencies = [ [[package]] name = "curve25519-dalek-derive" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.68", ] [[package]] name = "darling" -version = "0.20.3" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" dependencies = [ "darling_core", "darling_macro", @@ -1184,34 +1315,40 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.3" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 2.0.38", + "syn 2.0.68", ] [[package]] name = "darling_macro" -version = "0.20.3" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", - "syn 2.0.38", + "syn 2.0.68", ] +[[package]] +name = "data-encoding" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" + [[package]] name = "deranged" -version = "0.3.9" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", "serde", @@ -1219,22 +1356,22 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case", "proc-macro2", "quote", "rustc_version", - "syn 1.0.109", + "syn 2.0.68", ] [[package]] -name = "diff" -version = "0.1.13" +name = "deunicode" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" +checksum = "339544cc9e2c4dc3fc7149fd630c5f22263a4fdf18a98afd0075784968b5cf00" [[package]] name = "digest" @@ -1276,39 +1413,49 @@ checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "ena" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" dependencies = [ "log", ] [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +dependencies = [ + "log", + "regex", +] + [[package]] name = "env_logger" -version = "0.10.0" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" dependencies = [ + "anstream", + "anstyle", + "env_filter", "humantime", - "is-terminal", "log", - "regex", - "termcolor", ] [[package]] @@ -1319,12 +1466,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.5" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1335,15 +1482,36 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "3.0.0" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29e56284f00d94c1bc7fd3c77027b4623c88c1f53d8d2394c6199f2921dea325" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ "concurrent-queue", "parking", "pin-project-lite", ] +[[package]] +name = "event-listener-strategy" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +dependencies = [ + "event-listener 5.3.1", + "pin-project-lite", +] + [[package]] name = "fastrand" version = "1.9.0" @@ -1355,15 +1523,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fiat-crypto" -version = "0.2.1" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "fixed-hash" @@ -1385,9 +1553,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", @@ -1401,9 +1569,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -1420,9 +1588,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -1435,9 +1603,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -1445,15 +1613,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -1462,9 +1630,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-lite" @@ -1481,34 +1649,47 @@ dependencies = [ "waker-fn", ] +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand 2.1.0", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.68", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -1543,9 +1724,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -1554,9 +1735,9 @@ dependencies = [ [[package]] name = "ghash" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ "opaque-debug", "polyval", @@ -1564,9 +1745,33 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + +[[package]] +name = "globset" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", +] + +[[package]] +name = "globwalk" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" +dependencies = [ + "bitflags 2.6.0", + "ignore", + "walkdir", +] [[package]] name = "gloo-timers" @@ -1582,17 +1787,36 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.21" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http", - "indexmap 1.9.3", + "http 0.2.12", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", + "indexmap 2.2.6", "slab", "tokio", "tokio-util", @@ -1601,9 +1825,9 @@ dependencies = [ [[package]] name = "handlebars" -version = "4.4.0" +version = "5.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39b3bc2a8f715298032cf5087e58573809374b08160aa7d750582bdb82d2683" +checksum = "d08485b96a0e6393e9e4d1b8d48cf74ad6c063cd905eb33f42c1ce3f0377539b" dependencies = [ "log", "pest", @@ -1622,9 +1846,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.1" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" @@ -1632,11 +1856,23 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" [[package]] name = "hex" @@ -1652,9 +1888,9 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "hkdf" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ "hmac", ] @@ -1670,9 +1906,20 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -1681,12 +1928,35 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", - "http", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite", ] @@ -1696,11 +1966,17 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" +[[package]] +name = "http-range-header" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08a397c49fec283e3d6211adbe480be95aae5f304cfb923e9970e08956d5168a" + [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -1710,20 +1986,20 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "httpmock" -version = "0.6.8" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b02e044d3b4c2f94936fb05f9649efa658ca788f44eb6b87554e2033fc8ce93" +checksum = "08ec9586ee0910472dec1a1f0f8acf52f0fdde93aea74d70d4a3107b4be0fd5b" dependencies = [ "assert-json-diff", "async-object-pool", + "async-std", "async-trait", - "base64 0.21.4", + "base64 0.21.7", "basic-cookies", "crossbeam-utils", "form_urlencoded", "futures-util", - "hyper", - "isahc", + "hyper 0.14.29", "lazy_static", "levenshtein", "log", @@ -1736,6 +2012,15 @@ dependencies = [ "url", ] +[[package]] +name = "humansize" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" +dependencies = [ + "libm", +] + [[package]] name = "humantime" version = "2.1.0" @@ -1744,56 +2029,99 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" dependencies = [ "bytes", "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.9", + "socket2 0.5.7", "tokio", "tower-service", "tracing", "want", ] +[[package]] +name = "hyper" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4fe55fb7a772d59a5ff1dfbff4fe0258d19b89fec4b233e75d35d5d2316badc" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.5", + "http 1.1.0", + "http-body 1.0.0", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + [[package]] name = "hyper-rustls" -version = "0.24.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" dependencies = [ "futures-util", - "http", - "hyper", + "http 1.1.0", + "hyper 1.4.0", + "hyper-util", "log", "rustls", + "rustls-pki-types", "tokio", "tokio-rustls", - "webpki-roots 0.23.1", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.4.0", + "pin-project-lite", + "socket2 0.5.7", + "tokio", + "tower", + "tower-service", + "tracing", ] [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "windows-core", ] [[package]] @@ -1813,34 +2141,42 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", ] +[[package]] +name = "ignore" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata 0.4.7", + "same-file", + "walkdir", + "winapi-util", +] + [[package]] name = "image" -version = "0.23.14" +version = "0.24.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" dependencies = [ "bytemuck", "byteorder", "color_quant", - "num-iter", - "num-rational", "num-traits", ] -[[package]] -name = "impl-more" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d" - [[package]] name = "indexmap" version = "1.9.3" @@ -1854,12 +2190,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.2" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.1", + "hashbrown 0.14.5", "serde", ] @@ -1874,9 +2210,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -1887,78 +2223,46 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", - "windows-sys", -] - -[[package]] -name = "is-terminal" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix 0.38.19", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] -name = "isahc" -version = "1.7.2" +name = "is_terminal_polyfill" +version = "1.70.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "334e04b4d781f436dc315cb1e7515bd96826426345d498149e4bde36b67f8ee9" -dependencies = [ - "async-channel", - "castaway", - "crossbeam-utils", - "curl", - "curl-sys", - "encoding_rs", - "event-listener 2.5.3", - "futures-lite", - "http", - "log", - "mime", - "once_cell", - "polling", - "slab", - "sluice", - "tracing", - "tracing-futures", - "url", - "waker-fn", -] +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" [[package]] name = "itertools" -version = "0.10.5" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -1974,33 +2278,33 @@ dependencies = [ [[package]] name = "lalrpop" -version = "0.19.12" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a1cbf952127589f2851ab2046af368fd20645491bb4b376f04b7f94d7a9837b" +checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" dependencies = [ "ascii-canvas", "bit-set", - "diff", "ena", - "is-terminal", "itertools", "lalrpop-util", "petgraph", + "pico-args", "regex", - "regex-syntax 0.6.29", + "regex-syntax 0.8.4", "string_cache", "term", "tiny-keccak", "unicode-xid", + "walkdir", ] [[package]] name = "lalrpop-util" -version = "0.19.12" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3c48237b9604c5a4702de6b824e02006c3214327564636aef27c1028a8fa0ed" +checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" dependencies = [ - "regex", + "regex-automata 0.4.7", ] [[package]] @@ -2011,9 +2315,9 @@ checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "levenshtein" @@ -2023,30 +2327,24 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] -name = "libnghttp2-sys" -version = "0.1.8+1.55.1" +name = "libm" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fae956c192dadcdb5dace96db71fa0b827333cce7c7b38dc71446f024d8a340" -dependencies = [ - "cc", - "libc", -] +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] -name = "libz-sys" -version = "1.1.12" +name = "libredox" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "cc", + "bitflags 2.6.0", "libc", - "pkg-config", - "vcpkg", ] [[package]] @@ -2057,15 +2355,15 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "local-channel" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a493488de5f18c8ffcba89eebb8532ffc562dc400490eb65b84893fae0b178" +checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" dependencies = [ "futures-core", "futures-sink", @@ -2074,15 +2372,15 @@ dependencies = [ [[package]] name = "local-waker" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" +checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -2090,14 +2388,29 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" dependencies = [ "serde", "value-bag", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "md-5" version = "0.10.6" @@ -2110,18 +2423,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" - -[[package]] -name = "memoffset" -version = "0.9.0" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mime" @@ -2131,9 +2435,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" dependencies = [ "mime", "unicase", @@ -2141,30 +2445,30 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", "wasi", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "monero" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdf671c5fd0fa1f1dcc2495b6ca97a83f0aa6b2a737957e773d34c6c6bac0659" +checksum = "1b205707fd34b01a547f2fe77e687b40fed05966fb82e955b86ac55cd8ee31b5" dependencies = [ "base58-monero", "curve25519-dalek", @@ -2180,47 +2484,31 @@ dependencies = [ [[package]] name = "new_debug_unreachable" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" - -[[package]] -name = "num-integer" -version = "0.1.45" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] -name = "num-iter" -version = "0.1.43" +name = "nu-ansi-term" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" dependencies = [ - "autocfg", - "num-integer", - "num-traits", + "overload", + "winapi", ] [[package]] -name = "num-rational" -version = "0.3.2" +name = "num-conv" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -2231,54 +2519,42 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", ] [[package]] name = "object" -version = "0.32.1" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "openssl-probe" -version = "0.1.5" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] -name = "openssl-sys" -version = "0.9.93" +name = "overload" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parking" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e52c774a4c39359c1d1c52e43f73dd91a75a614652c825408eec30c95a9b2067" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" [[package]] name = "parking_lot" @@ -2293,12 +2569,12 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", - "parking_lot_core 0.9.8", + "parking_lot_core 0.9.10", ] [[package]] @@ -2317,44 +2593,53 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall 0.5.2", "smallvec", - "windows-targets", + "windows-targets 0.52.5", +] + +[[package]] +name = "parse-zoneinfo" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24" +dependencies = [ + "regex", ] [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pem" -version = "3.0.2" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3163d2912b7c3b52d651a055f2c7eec9ba5cd22d26ef75b8dd3a59980b185923" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" dependencies = [ - "base64 0.21.4", + "base64 0.22.1", "serde", ] [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.4" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c022f1e7b65d6a24c0dbbd5fb344c66881bc01f3e5ae74a1c8100f2f985d98a4" +checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" dependencies = [ "memchr", "thiserror", @@ -2363,9 +2648,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.4" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35513f630d46400a977c4cb58f78e1bfbe01434316e60c37d27b9ad6139c66d8" +checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" dependencies = [ "pest", "pest_generator", @@ -2373,22 +2658,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.4" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc9fc1b9e7057baba189b5c626e2d6f40681ae5b6eb064dc7c7834101ec8123a" +checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.68", ] [[package]] name = "pest_meta" -version = "2.7.4" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df74e9e7ec4053ceb980e7c0c8bd3594e977fde1af91daba9c928e8e8c6708d" +checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" dependencies = [ "once_cell", "pest", @@ -2397,12 +2682,41 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.0.2", + "indexmap 2.2.6", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator", + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared 0.11.2", + "rand", ] [[package]] @@ -2414,31 +2728,46 @@ dependencies = [ "siphasher", ] +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.68", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -2448,26 +2777,20 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" dependencies = [ "atomic-waker", - "fastrand 2.0.1", + "fastrand 2.1.0", "futures-io", ] [[package]] name = "pkg-config" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - -[[package]] -name = "platforms" -version = "3.1.2" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "polling" @@ -2482,14 +2805,29 @@ dependencies = [ "libc", "log", "pin-project-lite", - "windows-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "polling" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix 0.38.34", + "tracing", + "windows-sys 0.52.0", ] [[package]] name = "polyval" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", "cpufeatures", @@ -2541,28 +2879,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "qrcode" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16d2f1455f3630c6e5107b4f2b94e74d76dea80736de0981fd27644216cff57f" +checksum = "166f136dfdb199f98186f3649cf7a0536534a61417a1a30221b492b4fb60ce3f" dependencies = [ - "checked_int_cast", "image", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -2597,11 +2934,31 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "rcgen" -version = "0.11.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52c4f3084aa3bc7dfbba4eff4fab2a54db4324965d8872ab933565e6fbd83bc6" +checksum = "48406db8ac1f3cbc7dcdb56ec355343817958a356ff430259bb07baf7607e1e1" dependencies = [ "pem", "ring", @@ -2620,47 +2977,62 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom", - "redox_syscall 0.2.16", + "libredox", "thiserror", ] [[package]] name = "regex" -version = "1.10.1" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaac441002f822bc9705a681810a4dd2963094b9ca0ddc41cb963a4c189189ea" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax 0.8.2", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] name = "regex-automata" -version = "0.4.2" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5011c7e263a695dc8ca064cddb722af1be54e517a280b12a5356f98366899e5d" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.4", ] +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + [[package]] name = "regex-syntax" version = "0.6.29" @@ -2669,30 +3041,64 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "ring" -version = "0.16.20" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", + "getrandom", "libc", - "once_cell", "spin", "untrusted", - "web-sys", - "winapi", + "windows-sys 0.52.0", +] + +[[package]] +name = "rust-embed" +version = "8.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19549741604902eb99a7ed0ee177a0663ee1eda51a29f71401f166e47e77806a" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "8.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb9f96e283ec64401f30d3df8ee2aaeb2561f34c824381efa24a35f79bf40ee4" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "syn 2.0.68", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "8.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c74a686185620830701348de757fd36bef4aa9680fd23c49fc539ddcc1af32" +dependencies = [ + "sha2", + "walkdir", ] [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hex" @@ -2711,83 +3117,83 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.25" +version = "0.37.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4eb579851244c2c03e7c24f501c3432bed80b8f720af1d6e5b0e0f01555a035" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" dependencies = [ "bitflags 1.3.2", "errno", "io-lifetimes", "libc", "linux-raw-sys 0.3.8", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "rustix" -version = "0.38.19" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "745ecfa778e66b2b63c88a61cb36e0eea109e803b0b86bf9879fbc77c70e86ed" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "errno", "libc", - "linux-raw-sys 0.4.10", - "windows-sys", + "linux-raw-sys 0.4.14", + "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.21.7" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ "log", "ring", - "rustls-webpki 0.101.6", - "sct", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", ] [[package]] name = "rustls-pemfile" -version = "1.0.3" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" dependencies = [ - "base64 0.21.4", + "base64 0.22.1", + "rustls-pki-types", ] [[package]] -name = "rustls-webpki" -version = "0.100.3" +name = "rustls-pki-types" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6a5fc258f1c1276dfe3016516945546e2d5383911efc0fc4f1cdc5df3a4ae3" -dependencies = [ - "ring", - "untrusted", -] +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" -version = "0.101.6" +version = "0.102.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" +checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" dependencies = [ "ring", + "rustls-pki-types", "untrusted", ] [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -2798,41 +3204,22 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "schannel" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" -dependencies = [ - "windows-sys", -] - [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "sealed" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4a8caec23b7800fb97971a1c6ae365b6239aaeddfb934d6265f8505e795699d" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.68", ] [[package]] @@ -2847,15 +3234,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.189" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] @@ -2871,26 +3258,36 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.189" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.68", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" +dependencies = [ + "itoa", + "serde", +] + [[package]] name = "serde_regex" version = "1.1.0" @@ -2915,16 +3312,17 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.3.0" +version = "3.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca3b16a3d82c4088f343b7480a93550b3eabe1a358569c2dfe38bbcead07237" +checksum = "079f3a42cd87588d924ed95b533f8d30a483388c4e400ab736a7058e34f16169" dependencies = [ - "base64 0.21.4", + "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.0.2", + "indexmap 2.2.6", "serde", + "serde_derive", "serde_json", "serde_with_macros", "time", @@ -2932,23 +3330,23 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.3.0" +version = "3.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e6be15c453eb305019bfa438b1593c731f36a289a7853f7707ee29e870b3b3c" +checksum = "bc03aad67c1d26b7de277d51c86892e7d9a0110a2fe44bf6b26cc569fba302d6" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.68", ] [[package]] name = "serde_yaml" -version = "0.9.25" +version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.2.6", "itoa", "ryu", "serde", @@ -2977,20 +3375,29 @@ dependencies = [ "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] [[package]] name = "similar" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aeaf503862c419d66959f5d7ca015337d864e9c49485d771b732e2a20453597" +checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" [[package]] name = "siphasher" @@ -3024,27 +3431,26 @@ dependencies = [ ] [[package]] -name = "sluice" -version = "0.5.5" +name = "slug" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7400c0eff44aa2fcb5e31a5f24ba9716ed90138769e4977a2ba6014ae63eb5" +checksum = "3bd94acec9c8da640005f8e135a39fc0372e74535e6b368b7a04b875f784c8c4" dependencies = [ - "async-channel", - "futures-core", - "futures-io", + "deunicode", + "wasm-bindgen", ] [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi", @@ -3052,25 +3458,25 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.4" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "spin" -version = "0.5.2" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "sqlite" -version = "0.31.1" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05439db7afa0ce0b38f6d1b4c691f368adde108df021e15e900fec6a1af92488" +checksum = "78a97f6ee5b054b7cfddc3b6613fdea4c77af2ef8f8aac3048c7d0be31e605e3" dependencies = [ "libc", "sqlite3-sys", @@ -3078,9 +3484,9 @@ dependencies = [ [[package]] name = "sqlite3-src" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfc95a51a1ee38839599371685b9d4a926abb51791f0bc3bf8c3bb7867e6e454" +checksum = "174d4a6df77c27db281fb23de1a6d968f3aaaa4807c2a1afa8056b971f947b4a" dependencies = [ "cc", "pkg-config", @@ -3088,9 +3494,9 @@ dependencies = [ [[package]] name = "sqlite3-sys" -version = "0.15.2" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2752c669433e40ebb08fde824146f50d9628aa0b66a3b7fc6be34db82a8063b" +checksum = "aed0b61828382e1103930d2d5df1972d493173319730b481192e63d929097321" dependencies = [ "libc", "sqlite3-src", @@ -3110,44 +3516,44 @@ checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" dependencies = [ "new_debug_unreachable", "once_cell", - "parking_lot 0.12.1", - "phf_shared", + "parking_lot 0.12.3", + "phf_shared 0.10.0", "precomputed-hash", ] [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" -version = "0.25.0" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.25.3" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "rustversion", - "syn 2.0.38", + "syn 2.0.68", ] [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -3162,9 +3568,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" dependencies = [ "proc-macro2", "quote", @@ -3172,101 +3578,146 @@ dependencies = [ ] [[package]] -name = "tempfile" -version = "3.8.0" +name = "sync_wrapper" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" -dependencies = [ - "cfg-if", - "fastrand 2.0.1", - "redox_syscall 0.3.5", - "rustix 0.38.19", - "windows-sys", -] +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] -name = "term" -version = "0.7.0" +name = "sync_wrapper" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" -dependencies = [ - "dirs-next", - "rustversion", - "winapi", -] +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" [[package]] -name = "termcolor" -version = "1.3.0" +name = "tempfile" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ - "winapi-util", + "cfg-if", + "fastrand 2.1.0", + "rustix 0.38.34", + "windows-sys 0.52.0", ] [[package]] -name = "test-case" -version = "3.2.1" +name = "tera" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8f1e820b7f1d95a0cdbf97a5df9de10e1be731983ab943e56703ac1b8e9d425" +checksum = "ab9d851b45e865f178319da0abdbfe6acbc4328759ff18dafc3a41c16b4cd2ee" dependencies = [ - "test-case-macros", + "chrono", + "chrono-tz", + "globwalk", + "humansize", + "lazy_static", + "percent-encoding", + "pest", + "pest_derive", + "rand", + "regex", + "serde", + "serde_json", + "slug", + "unic-segment", +] + +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + +[[package]] +name = "test-case" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb2550dd13afcd286853192af8601920d959b14c401fcece38071d53bf0768a8" +dependencies = [ + "test-case-macros", ] [[package]] name = "test-case-core" -version = "3.2.1" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54c25e2cb8f5fcd7318157634e8838aa6f7e4715c96637f969fabaccd1ef5462" +checksum = "adcb7fd841cd518e279be3d5a3eb0636409487998a4aff22f3de87b81e88384f" dependencies = [ "cfg-if", - "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.68", ] [[package]] name = "test-case-macros" -version = "3.2.1" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37cfd7bbc88a0104e304229fba519bdc45501a30b760fb72240342f1289ad257" +checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ - "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.68", "test-case-core", ] +[[package]] +name = "testing-utils" +version = "0.1.0" +dependencies = [ + "acceptxmr", + "httpmock", + "log", + "serde_json", + "tempfile", + "tracing-subscriber", +] + [[package]] name = "thiserror" -version = "1.0.49" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.49" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.68", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", ] [[package]] name = "time" -version = "0.3.30" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -3281,10 +3732,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.15" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -3299,9 +3751,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82" dependencies = [ "tinyvec_macros", ] @@ -3314,58 +3766,119 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.33.0" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" dependencies = [ "backtrace", "bytes", "libc", "mio", "num_cpus", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.4", + "socket2 0.5.7", "tokio-macros", - "windows-sys", + "tracing", + "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.68", ] [[package]] name = "tokio-rustls" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ "rustls", + "rustls-pki-types", "tokio", ] +[[package]] +name = "tokio-tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] + [[package]] name = "tokio-util" -version = "0.7.9" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", "tracing", ] +[[package]] +name = "tower-http" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" +dependencies = [ + "base64 0.21.7", + "bitflags 2.6.0", + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "http-range-header", + "httpdate", + "mime", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -3374,51 +3887,78 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.39" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2ef2af84856a50c1d430afce2fdded0a4ec7eda868db86409b4543df0797f9" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ "log", "pin-project-lite", - "tracing-attributes", "tracing-core", ] [[package]] -name = "tracing-attributes" -version = "0.1.27" +name = "tracing-core" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", + "once_cell", + "valuable", ] [[package]] -name = "tracing-core" -version = "0.1.32" +name = "tracing-log" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ + "log", "once_cell", + "tracing-core", ] [[package]] -name = "tracing-futures" -version = "0.2.5" +name = "tracing-subscriber" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ - "pin-project", + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", "tracing", + "tracing-core", + "tracing-log", ] [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 1.1.0", + "httparse", + "log", + "rand", + "sha1", + "thiserror", + "url", + "utf-8", +] [[package]] name = "typenum" @@ -3432,6 +3972,56 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +[[package]] +name = "unic-char-property" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +dependencies = [ + "unic-char-range", +] + +[[package]] +name = "unic-char-range" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" + +[[package]] +name = "unic-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" + +[[package]] +name = "unic-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23" +dependencies = [ + "unic-ucd-segment", +] + +[[package]] +name = "unic-ucd-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700" +dependencies = [ + "unic-char-property", + "unic-char-range", + "unic-ucd-version", +] + +[[package]] +name = "unic-ucd-version" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" +dependencies = [ + "unic-common", +] + [[package]] name = "unicase" version = "2.7.0" @@ -3443,9 +4033,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -3455,9 +4045,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] @@ -3480,44 +4070,96 @@ dependencies = [ [[package]] name = "unsafe-libyaml" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] name = "untrusted" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.4.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] -name = "value-bag" -version = "1.4.1" +name = "utoipa" +version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d92ccd67fb88503048c01b59152a04effd0782d035a83a6d256ce6085f08f4a3" +checksum = "c5afb1a60e207dca502682537fefcfd9921e71d0b83e9576060f09abc6efab23" +dependencies = [ + "indexmap 2.2.6", + "serde", + "serde_json", + "utoipa-gen", +] [[package]] -name = "vcpkg" -version = "0.2.15" +name = "utoipa-gen" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +checksum = "7bf0e16c02bc4bf5322ab65f10ab1149bdbcaa782cba66dc7057370a3f8190be" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "utoipa-swagger-ui" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b39868d43c011961e04b41623e050aedf2cc93652562ff7935ce0f819aaf2da" +dependencies = [ + "axum", + "mime_guess", + "regex", + "rust-embed", + "serde", + "serde_json", + "utoipa", + "zip", +] + +[[package]] +name = "v_htmlescape" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e8257fbc510f0a46eb602c10215901938b5c2a7d5e70fc11483b1d3c9b5b18c" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "value-bag" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" [[package]] name = "version_check" @@ -3533,15 +4175,15 @@ checksum = "9dcc60c0624df774c82a0ef104151231d37da4962957d691c011c852b2473314" [[package]] name = "waker-fn" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -3564,9 +4206,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3574,24 +4216,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.68", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -3601,9 +4243,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3611,28 +4253,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.68", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -3640,19 +4282,13 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.23.1" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" +checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" dependencies = [ - "rustls-webpki 0.100.3", + "rustls-pki-types", ] -[[package]] -name = "webpki-roots" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" - [[package]] name = "winapi" version = "0.3.9" @@ -3671,11 +4307,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -3685,12 +4321,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.48.0" +name = "windows-core" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets", + "windows-targets 0.52.5", ] [[package]] @@ -3699,7 +4335,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", ] [[package]] @@ -3708,13 +4353,29 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -3723,42 +4384,90 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + [[package]] name = "yasna" version = "0.5.2" @@ -3768,36 +4477,67 @@ dependencies = [ "time", ] +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + [[package]] name = "zeroize" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "byteorder", + "crc32fast", + "crossbeam-utils", + "flate2", +] [[package]] name = "zstd" -version = "0.12.4" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" +checksum = "2d789b1514203a1120ad2429eae43a7bd32b90976a7bb8a05f7ec02fa88cc23a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "6.0.6" +version = "7.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" +checksum = "1cd99b45c6bc03a018c8b8a86025678c87e55526064e38f9df301989dce7ec0a" dependencies = [ - "libc", "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" +version = "2.0.11+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +checksum = "75652c55c0b6f3e6f12eb786fe1bc960396bf05a1eb3bf1f3691c3610ac2e6d4" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index edecbc2..c05767d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,8 +3,79 @@ resolver = "2" members = [ "server", - "library" + "library", + "testing-utils" ] +[workspace.lints.rust] +unsafe_code = "forbid" +missing_docs = "warn" +unreachable_pub = "warn" + +[workspace.lints.clippy] +pedantic = "warn" +cargo = "warn" +module_name_repetitions = { level = "allow", priority = 1 } +multiple_crate_versions = { level = "allow", priority = 1 } + +[workspace.dependencies] +acceptxmr = { path = "library" } +actix = "0.13" +actix-files = "0.6" +actix-session = "0.9" +actix-web = "4" +actix-web-actors = "4" +axum = { version = "0.7", default-features = false } +backoff = "0.4" +base64 = "0.22" +bincode = "^2.0.0-rc.3" +blake3 = "1" +bytes = "1" +bytestring = "1" +clap = "4" +dotenv = "0.15" +env_logger = "0.11" +futures = "0.3" +futures-util = "0.3" +handlebars = "5" +hex = "0.4" +http-body-util = "0.1" +httpmock = "0.7" +hyper = "1" +hyper-rustls = { version = "0.26", default-features = false } +hyper-util = "0.1" +indexmap = "2" +log = "0.4" +md-5 = "0.10" +mime = "0.3" +monero = "0.20" +qrcode = "0.13" +rand = "0.8" +rand_chacha = "0.3" +rayon = "1" +rcgen = "0.12" +rustls-pemfile = "2" +secrecy = "0.8" +serde = { version = "1.0", default-features = false } +serde_json = "1" +serde_with = "3" +serde_yaml = "0.9" +sled = "0.34" +sqlite = "0.33" +strum = "0.26" +tempfile = "3" +tera = "1" +test-case = "3" +testing-utils = { path = "testing-utils" } +thiserror = "1" +tokio = "1" +tokio-rustls = "0.25" +tokio-tungstenite = "0.21" +tower = "0.4" +tower-http = "0.5" +tracing-subscriber = "0.3" +utoipa = "4" +utoipa-swagger-ui = "6" + [profile.release] lto = true diff --git a/Dockerfile b/Dockerfile index 2325f1a..163cfac 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,32 @@ -FROM rust:1.73-slim-bookworm as build +FROM --platform=$BUILDPLATFORM rust:1.76-slim-bookworm as build # Create a new empty shell project. RUN USER=root cargo new --bin acceptxmr-server WORKDIR /acceptxmr-server +# Prepare for cross compilation. +ARG TARGETARCH +RUN apt update && apt upgrade -y + +RUN if [ "$TARGETARCH" = "arm64" ]; then \ + apt install -y g++-aarch64-linux-gnu libc6-dev-arm64-cross; \ + rustup toolchain install stable-aarch64-unknown-linux-gnu; \ + rustup target add aarch64-unknown-linux-gnu; \ + elif [ "$TARGETARCH" = "amd64" ]; then \ + apt install -y g++-x86_64-linux-gnu libc6-dev-amd64-cross; \ + rustup toolchain install stable-x86_64-unknown-linux-gnu; \ + rustup target add x86_64-unknown-linux-gnu; \ + else \ + echo "Unsupported target arch $TARGETARCH"; \ + exit 1; \ + fi + # Copy over the manifests COPY ./.cargo ./.cargo COPY ./Cargo.lock ./Cargo.lock COPY ./Cargo.toml ./Cargo.toml COPY ./library/Cargo.toml ./library/Cargo.toml +COPY ./testing-utils/Cargo.toml ./testing-utils/Cargo.toml # Create main.rs so build succeeds. RUN cargo init server RUN touch server/src/lib.rs @@ -18,23 +36,44 @@ COPY ./server/Cargo.toml ./server/Cargo.toml # Copy over the AcceptXMR lib. COPY ./library ./library -# This build step will cache the dependencies (including the AcceptXMR lib). -RUN cargo build --release +# Copy over the testing-utils lib. +COPY ./testing-utils ./testing-utils + +# This build step will cache the dependencies (including the AcceptXMR lib and testing-utils). +RUN if [ "$TARGETARCH" = "arm64" ]; then \ + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=/usr/bin/aarch64-linux-gnu-gcc cargo build --target=aarch64-unknown-linux-gnu --release; \ + elif [ "$TARGETARCH" = "amd64" ]; then \ + CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=/usr/bin/x86_64-linux-gnu-gcc cargo build --target=x86_64-unknown-linux-gnu --release; \ + else \ + echo "Unsupported target arch $TARGETARCH"; \ + exit 1; \ + fi # Copy the source tree. RUN rm ./server/src/*.rs COPY ./server/src ./server/src # Build for release. -RUN rm ./target/release/deps/acceptxmr_server* -RUN rm ./target/release/deps/libacceptxmr_server* -RUN cargo build --release +RUN if [ "$TARGETARCH" = "arm64" ]; then \ + rm ./target/aarch64-unknown-linux-gnu/release/deps/acceptxmr_server*; \ + rm ./target/aarch64-unknown-linux-gnu/release/deps/libacceptxmr_server*; \ + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=/usr/bin/aarch64-linux-gnu-gcc cargo build --target=aarch64-unknown-linux-gnu --release; \ + cp /acceptxmr-server/target/aarch64-unknown-linux-gnu/release/acceptxmr-server .; \ + elif [ "$TARGETARCH" = "amd64" ]; then \ + rm ./target/x86_64-unknown-linux-gnu/release/deps/acceptxmr_server*; \ + rm ./target/x86_64-unknown-linux-gnu/release/deps/libacceptxmr_server*; \ + CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=/usr/bin/x86_64-linux-gnu-gcc cargo build --target=x86_64-unknown-linux-gnu --release; \ + cp /acceptxmr-server/target/x86_64-unknown-linux-gnu/release/acceptxmr-server .; \ + else \ + echo "Unsupported target arch $TARGETARCH"; \ + exit 1; \ + fi # Final base. FROM frolvlad/alpine-glibc:alpine-3.17 # Copy the binary from the build stage. -COPY --from=build /acceptxmr-server/target/release/acceptxmr-server . +COPY --from=build /acceptxmr-server/acceptxmr-server . # Copy the static files. COPY ./server/static ./server/static diff --git a/acceptxmr.yaml b/acceptxmr.yaml index 32e9868..d785c36 100644 --- a/acceptxmr.yaml +++ b/acceptxmr.yaml @@ -45,6 +45,20 @@ internal-api: # Specify where static HTML/CSS/JS files can be found. static_dir: server/static/ +# When a connection fails to be made to a callback recipient or the recipient +# returns an error, the callback will be placed back into the queue and retried. +# If the queue fills up, the payment gateway will stop processing invoices until +# the queue begins to clear. +# +# Note that the queue is held in memory. When the server is stopped, the queue +# is lost and the queued callbacks will not be delivered. +# +# Retries are delayed according to an exponential decay schedule starting at 1s +# and increasing by 1.5x each retry up to a maximum interval of 1 hour. +callback: + queue-size: 1000 + max-retries: 50 + # Remember to change the address below to your own. You will also need to set # your private viewkey using the PRIVATE_VIEWKEY environment variable. # @@ -62,9 +76,15 @@ wallet: daemon: url: http://xmr-node.cakewallet.com:18081/ login: null + # Timeout in seconds for RPC calls to the daemon. Defaults to 30s. + rpc-timeout: 30 + # Timeout in seconds for making an RPC connection to the daemon. Defaults to 20s. + connection-timeout: 20 database: path: AcceptXMR_DB/ + # Delete expired invoices if they aren't pending confirmation. Defaults to true. + delete-expired: true logging: verbosity: DEBUG diff --git a/clippy.toml b/clippy.toml new file mode 100644 index 0000000..42cb2e7 --- /dev/null +++ b/clippy.toml @@ -0,0 +1,40 @@ +# Needed because simply blanket allowing duplicate crates does not currently work in workspaces. +allowed-duplicate-crates = [ + "async-channel", + "async-io", + "async-lock", + "axum-core", + "axum", + "bitflags", + "event-listener-strategy", + "event-listener", + "fastrand", + "futures-lite", + "h2", + "hashbrown", + "http-body", + "http", + "hyper", + "indexmap", + "linux-raw-sys", + "parking_lot_core", + "parking_lot", + "polling", + "redox_syscall", + "regex-automata", + "regex-syntax", + "rustix", + "socket2", + "strsim", + "syn", + "sync_wrapper", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", + "windows-sys", + "windows-targets", +] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 33e5894..939ee23 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,7 +15,7 @@ services: - "8080:8080" - "8081:8081" volumes: - - db:/AcceptXMR_DB + - ./AcceptXMR_DB:/AcceptXMR_DB - ./server/tests/testdata/cert:/server/tests/testdata/cert/ - ./acceptxmr.yaml:/acceptxmr.yaml env_file: .env diff --git a/flake.lock b/flake.lock index a9b9982..9756666 100644 --- a/flake.lock +++ b/flake.lock @@ -5,11 +5,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1694529238, - "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "type": "github" }, "original": { @@ -19,11 +19,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1695318763, - "narHash": "sha256-FHVPDRP2AfvsxAdc+AsgFJevMz5VBmnZglFUMlxBkcY=", + "lastModified": 1719900233, + "narHash": "sha256-n0r/+L73jFW4Y+sCUerulR7VcVADnfcXdzRs7PaiIqw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "e12483116b3b51a185a33a272bf351e357ba9a99", + "rev": "0f56e3221392452f2c38e3ddf2eba03abda6bf47", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index cf0a703..f6a85c4 100644 --- a/flake.nix +++ b/flake.nix @@ -13,14 +13,24 @@ fmtr = nixpkgs.legacyPackages.${system}.alejandra; in { formatter = fmtr; - devShells.default = pkgs.mkShell { - packages = with pkgs; [ - gcc - rustup - pkg-config - openssl.dev - ]; - }; + devShells.default = + pkgs.mkShell.override { + stdenv = pkgs.stdenvAdapters.useMoldLinker pkgs.clangStdenv; + } { + packages = with pkgs; [ + gcc + rustup + pkg-config + rust-analyzer + openssl.dev + typos-lsp + ]; + + shellHook = '' + alias clippy="cargo +nightly clippy --all-targets --all-features" + alias test="cargo +nightly test --all-targets --all-features" + ''; + }; } ); } diff --git a/library/Cargo.toml b/library/Cargo.toml index d50f042..0bafc62 100644 --- a/library/Cargo.toml +++ b/library/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "acceptxmr" -version = "0.13.0" +version = "0.14.0" edition = "2021" -rust-version = "1.70" +rust-version = "1.76" license = "MIT OR Apache-2.0" description = "Accept monero in your application." repository = "https://github.com/busyboredom/acceptxmr" @@ -10,6 +10,9 @@ readme = "README.md" keywords = ["crypto", "gateway", "monero", "payment", "xmr"] categories = ["cryptography::cryptocurrencies"] +[lints] +workspace = true + [lib] name = "acceptxmr" path = "src/lib.rs" @@ -19,24 +22,29 @@ all-features = true rustc-args = ["--cfg", "docsrs"] [dependencies] -bincode = { version = "^2.0.0-rc.3", optional = true } -hex = "0.4" -http = "0.2" -hyper = { version = "0.14", features = ["client", "http1", "http2", "tcp"] } -hyper-rustls = { version = "0.24", features = ["logging", "http1", "http2", "tls12", "webpki-tokio"], default-features = false } -indexmap = "2" -log = "0.4" -md-5 = "0.10" -monero = "0.19" -rand = "0.8" -rand_chacha = "0.3" -serde = { version = "1.0", default-features = false, features = ["derive", "alloc"], optional = true } -serde_json = "1" -sled = { version = "0.34", optional = true } -sqlite = { version = "0.31", optional = true } -strum = { version = "0.25", features = ["derive"] } -thiserror = "1" -tokio = { version = "1", features = ["macros", "rt-multi-thread", "time"] } +backoff = { workspace = true, features = ["tokio"] } +bincode = { workspace = true, optional = true } +blake3 = { workspace = true, features = ["std"] } +bytes.workspace = true +hex.workspace = true +http-body-util.workspace = true +hyper = { workspace = true, features = ["client", "http1", "http2"] } +hyper-rustls = { workspace = true, features = ["logging", "http1", "http2", "tls12", "webpki-tokio", "webpki-roots", "ring"] } +hyper-util = { workspace = true, features = ["client-legacy", "http1", "http2"] } +indexmap.workspace = true +log.workspace = true +md-5.workspace = true +monero.workspace = true +rand.workspace = true +rand_chacha.workspace = true +rayon.workspace = true +serde = { workspace = true, features = ["derive", "alloc"], optional = true } +serde_json.workspace = true +sled = { workspace = true, optional = true } +sqlite = { workspace = true, optional = true } +strum = { workspace = true, features = ["derive"] } +thiserror.workspace = true +tokio = { workspace = true, features = ["macros", "rt-multi-thread", "time", "tracing"] } [features] bincode = ["dep:bincode"] @@ -46,21 +54,20 @@ sled = ["bincode", "dep:sled"] sqlite = ["bincode", "dep:sqlite"] [dev-dependencies] -actix = "0.13" -actix-files = "0.6" -actix-session = { version = "0.8", features = ["cookie-session"] } -actix-web = "4" -actix-web-actors = "4" -bytestring = "1" -env_logger = "0.10" -handlebars = { version = "4", features = ["dir_source"] } -httpmock = "0.6" -qrcode = "0.12" -serde = "1" -tempfile = "3" -test-case = "3" +actix.workspace = true +actix-files.workspace = true +actix-session = { workspace = true, features = ["cookie-session"] } +actix-web.workspace = true +actix-web-actors.workspace = true +bytestring.workspace = true +env_logger.workspace = true +handlebars = { workspace = true, features = ["dir_source"] } +qrcode.workspace = true +serde.workspace = true +test-case.workspace = true +testing-utils.workspace = true # This is a workaround to enable features in tests. -acceptxmr = { path = ".", features = ["sled", "in-memory", "sqlite"] } +acceptxmr = { workspace = true, features = ["sled", "in-memory", "sqlite"] } [[example]] name = "custom_storage" diff --git a/library/README.md b/library/README.md index 1530df2..1f53a45 100644 --- a/library/README.md +++ b/library/README.md @@ -1,7 +1,7 @@ [![BuildStatus](https://github.com/busyboredom/acceptxmr/workflows/CI/badge.svg)](https://img.shields.io/github/actions/workflow/status/busyboredom/acceptxmr/ci.yml?branch=main) [![Crates.io](https://img.shields.io/crates/v/acceptxmr.svg)](https://crates.io/crates/acceptxmr) [![Documentation](https://docs.rs/acceptxmr/badge.svg)](https://docs.rs/acceptxmr) -[![MSRV](https://img.shields.io/badge/MSRV-1.70.0-blue)](https://blog.rust-lang.org/2023/06/01/Rust-1.70.0.html) +[![MSRV](https://img.shields.io/badge/MSRV-1.76.0-blue)](https://blog.rust-lang.org/2024/02/08/Rust-1.76.0.html) # `AcceptXMR`: Accept Monero in Your Application `AcceptXMR` is a library for building payment gateways. @@ -50,7 +50,7 @@ let invoice_id = payment_gateway.new_invoice( 0, // require 0 confirmations, 10, // expire in 10 blocks, "Large Cheese Pizza".to_string() // and get the order right. -)?; +).await?; // We can now subscribe to updates to the pizza invoice. let subscriber = payment_gateway.subscribe(invoice_id)? @@ -62,8 +62,8 @@ let update = subscriber.recv().await.expect("channel closed"); if update.is_confirmed() { // Great, ship the pizza and stop tracking the invoice. println!("Invoice for \"{}\" paid", update.description()); - payment_gateway.remove_invoice(invoice_id)?; + payment_gateway.remove_invoice(invoice_id).await?; } ``` For more detailed documentation, see [docs.rs](https://docs.rs/acceptxmr) or the -[examples](./examples/). \ No newline at end of file +[examples](./examples/). diff --git a/library/examples/custom_storage/main.rs b/library/examples/custom_storage/main.rs index 6657b30..21057b6 100644 --- a/library/examples/custom_storage/main.rs +++ b/library/examples/custom_storage/main.rs @@ -1,9 +1,6 @@ -#![warn(clippy::pedantic)] +//! Use a custom storage layer. -use std::collections::{ - btree_map::{self, Entry}, - BTreeMap, -}; +use std::collections::{btree_map::Entry, BTreeMap}; use acceptxmr::{ storage::{HeightStorage, InvoiceStorage, OutputId, OutputKeyStorage, OutputPubKey, Storage}, @@ -33,6 +30,7 @@ async fn main() { ) .daemon_url("http://node.sethforprivacy.com:18089".to_string()) .build() + .await .unwrap(); info!("Payment gateway created."); @@ -41,9 +39,11 @@ async fn main() { // custom storage layer. let invoice_id = payment_gateway .new_invoice(1000, 2, 5, "Demo invoice".to_string()) + .await .unwrap(); let invoice = payment_gateway .get_invoice(invoice_id) + .await .unwrap() .expect("invoice not found"); @@ -53,9 +53,9 @@ async fn main() { ); } -// This example uses a BTreeMap for simplicity, but you can implement this trait -// on virtually any storage layer you choose. Postgres or MySQL, CSV files, -// whatever works best for your application. +/// This example storage layer uses a `BTreeMap` for simplicity, but you can +/// implement this trait on virtually any storage layer you choose. `Postgres` +/// or `MySQL`, CSV files, whatever works best for your application. pub struct MyCustomStorage { invoices: BTreeMap, output_keys: BTreeMap, @@ -82,7 +82,6 @@ impl Default for MyCustomStorage { impl InvoiceStorage for MyCustomStorage { type Error = MyCustomStorageError; - type Iter<'a> = MyCustomStorageIter<'a>; fn insert(&mut self, invoice: Invoice) -> Result<(), Self::Error> { if self.invoices.contains_key(&invoice.id()) { @@ -107,6 +106,10 @@ impl InvoiceStorage for MyCustomStorage { Ok(self.invoices.get(&invoice_id).cloned()) } + fn get_ids(&self) -> Result, Self::Error> { + Ok(self.invoices.keys().copied().collect()) + } + fn contains_sub_index(&self, sub_index: SubIndex) -> Result { Ok(self .invoices @@ -115,19 +118,17 @@ impl InvoiceStorage for MyCustomStorage { .is_some()) } - fn try_iter(&self) -> Result, Self::Error> { - let iter = self.invoices.values(); - Ok(MyCustomStorageIter(iter)) + fn try_for_each(&self, mut f: F) -> Result<(), Self::Error> + where + F: FnMut(Result) -> Result<(), Self::Error>, + { + self.invoices + .iter() + .try_for_each(|(_, invoice)| f(Ok(invoice.clone()))) } -} - -pub struct MyCustomStorageIter<'a>(btree_map::Values<'a, InvoiceId, Invoice>); - -impl<'a> Iterator for MyCustomStorageIter<'a> { - type Item = Result; - fn next(&mut self) -> Option { - self.0.next().map(|v| Ok(v.clone())) + fn is_empty(&self) -> Result { + Ok(self.invoices.is_empty()) } } diff --git a/library/examples/nojs/main.rs b/library/examples/nojs/main.rs index 8c0a3d7..59c9fab 100644 --- a/library/examples/nojs/main.rs +++ b/library/examples/nojs/main.rs @@ -1,4 +1,4 @@ -#![warn(clippy::pedantic)] +//! Serve a no-js frontend. use acceptxmr::{storage::stores::InMemory, InvoiceId, PaymentGateway, PaymentGatewayBuilder}; use actix_files::Files; @@ -15,7 +15,7 @@ use actix_web::{ web::{Data, Form}, App, HttpResponse, HttpServer, Result, }; -use handlebars::{no_escape, Handlebars}; +use handlebars::{no_escape, DirectorySourceOptions, Handlebars}; use log::{debug, error, info, LevelFilter}; use qrcode::{render::svg, EcLevel, QrCode}; use rand::{thread_rng, Rng}; @@ -46,6 +46,7 @@ async fn main() -> std::io::Result<()> { ) .daemon_url("http://xmr-node.cakewallet.com:18081".to_string()) .build() + .await .expect("failed to build payment gateway"); info!("Payment gateway created."); @@ -57,7 +58,7 @@ async fn main() -> std::io::Result<()> { // Watch for invoice updates and deal with them accordingly. let gateway_copy = payment_gateway.clone(); - std::thread::spawn(move || { + tokio::spawn(async move { // Watch all invoice updates. let mut subscriber = gateway_copy.subscribe_all(); loop { @@ -74,7 +75,7 @@ async fn main() -> std::io::Result<()> { "Invoice to index {} has been tracked for > 30 blocks. Removing invoice now", invoice.index() ); - if let Err(e) = gateway_copy.remove_invoice(invoice.id()) { + if let Err(e) = gateway_copy.remove_invoice(invoice.id()).await { error!("Failed to remove invoice: {}", e); }; } @@ -89,7 +90,14 @@ async fn main() -> std::io::Result<()> { // Templating setup. let mut handlebars = Handlebars::new(); handlebars - .register_templates_directory(".html", "./library/examples/nojs/static/templates") + .register_templates_directory( + "./library/examples/nojs/static/templates", + DirectorySourceOptions { + tpl_extension: ".html".to_string(), + hidden: false, + temporary: false, + }, + ) .expect("failed to register template directory"); handlebars.register_escape_fn(no_escape); @@ -131,6 +139,7 @@ async fn start_checkout( ) -> Result { let invoice_id = payment_gateway .new_invoice(1_000_000_000, 2, 5, checkout_info.message.clone()) + .await .unwrap(); session.insert("id", invoice_id)?; Ok(HttpResponse::TemporaryRedirect() @@ -149,7 +158,7 @@ async fn checkout( templater: Data>, ) -> Result { if let Ok(Some(invoice_id)) = session.get::("id") { - if let Ok(Some(invoice)) = payment_gateway.get_invoice(invoice_id) { + if let Ok(Some(invoice)) = payment_gateway.get_invoice(invoice_id).await { let mut instruction = "Send Monero to Address Below"; let mut address = invoice.address(); let mut qrcode = qrcode(&invoice.uri()); diff --git a/library/examples/persistence/main.rs b/library/examples/persistence/main.rs index d61d73b..4365fab 100644 --- a/library/examples/persistence/main.rs +++ b/library/examples/persistence/main.rs @@ -1,4 +1,4 @@ -#![warn(clippy::pedantic)] +//! Use a persistent invoice store to enable recovery from power loss. use acceptxmr::{storage::stores::Sqlite, PaymentGateway, PaymentGatewayBuilder}; use log::{error, info, LevelFilter}; @@ -33,6 +33,7 @@ async fn main() { ) .daemon_url("http://node.sethforprivacy.com:18089".to_string()) .build() + .await .unwrap(); info!("Payment gateway created."); @@ -41,9 +42,11 @@ async fn main() { // persistently in your Sqlite database. let invoice_id = payment_gateway .new_invoice(1000, 2, 5, "Demo invoice".to_string()) + .await .unwrap(); let invoice = payment_gateway .get_invoice(invoice_id) + .await .unwrap() .expect("invoice not found"); @@ -70,11 +73,13 @@ async fn main() { ) .daemon_url("http://node.sethforprivacy.com:18089".to_string()) .build() + .await .unwrap(); // The invoice is still there! let invoice = payment_gateway .get_invoice(invoice_id) + .await .unwrap() .expect("invoice not found"); diff --git a/library/examples/websockets/main.rs b/library/examples/websockets/main.rs index 76c15d0..abccd93 100644 --- a/library/examples/websockets/main.rs +++ b/library/examples/websockets/main.rs @@ -1,4 +1,4 @@ -#![warn(clippy::pedantic)] +//! Use websockets to notify of invoice updates. use std::{ future::Future, @@ -59,6 +59,7 @@ async fn main() -> std::io::Result<()> { ) .daemon_url("http://xmr-node.cakewallet.com:18081".to_string()) .build() + .await .expect("failed to build payment gateway"); info!("Payment gateway created."); @@ -70,7 +71,7 @@ async fn main() -> std::io::Result<()> { // Watch for invoice updates and deal with them accordingly. let gateway_copy = payment_gateway.clone(); - std::thread::spawn(move || { + tokio::spawn(async move { // Watch all invoice updates. let mut subscriber = gateway_copy.subscribe_all(); loop { @@ -86,7 +87,7 @@ async fn main() -> std::io::Result<()> { "Invoice to index {} is either confirmed or expired. Removing invoice now", invoice.index() ); - if let Err(e) = gateway_copy.remove_invoice(invoice.id()) { + if let Err(e) = gateway_copy.remove_invoice(invoice.id()).await { error!("Failed to remove fully confirmed invoice: {}", e); }; } @@ -137,6 +138,7 @@ async fn checkout( ) -> Result { let invoice_id = payment_gateway .new_invoice(1_000_000_000, 2, 5, checkout_info.message.clone()) + .await .unwrap(); session.insert("id", invoice_id)?; Ok(HttpResponse::Ok() @@ -152,7 +154,7 @@ async fn update( payment_gateway: web::Data>, ) -> Result { if let Ok(Some(invoice_id)) = session.get::("id") { - if let Ok(Some(invoice)) = payment_gateway.get_invoice(invoice_id) { + if let Ok(Some(invoice)) = payment_gateway.get_invoice(invoice_id).await { return Ok(HttpResponse::Ok() .append_header(CacheControl(vec![CacheDirective::NoStore])) .json(json!( diff --git a/library/examples/websockets/static/acceptxmr.js b/library/examples/websockets/static/acceptxmr.js index ff24d34..9b46ab0 100644 --- a/library/examples/websockets/static/acceptxmr.js +++ b/library/examples/websockets/static/acceptxmr.js @@ -11,7 +11,7 @@ init() async function next(hasAddress) { // Hide prep stuff, show payment stuff. - document.getElementById("preperation-content").style.display = "None"; + document.getElementById("preparation-content").style.display = "None"; document.getElementById("payment-content").style.display = "inherit"; // Create invoice. diff --git a/library/examples/websockets/static/index.html b/library/examples/websockets/static/index.html index b9511dd..f6ecc2e 100644 --- a/library/examples/websockets/static/index.html +++ b/library/examples/websockets/static/index.html @@ -8,7 +8,7 @@
-
+
-
- -
-
-
- -
-
- -
-

- -
- -

- Paid: / 0.00000000 XMR
- Confirmations: - 0 / 0
-

-
-
-
- - - diff --git a/server/static/missing-invoice.html b/server/static/missing-invoice.html new file mode 100644 index 0000000..adfa33b --- /dev/null +++ b/server/static/missing-invoice.html @@ -0,0 +1,21 @@ + + +AcceptXMR + +
+
+

Expired!

+
+
+
+
+ +
+

{{invoice_id}}

+ +
+
+
+
+ + diff --git a/server/static/pay.html b/server/static/pay.html new file mode 100644 index 0000000..499be9b --- /dev/null +++ b/server/static/pay.html @@ -0,0 +1,29 @@ + + +AcceptXMR + +
+
+

Loading...

+
+
+
+
+ +
+
+ +
+

{{address}}

+ +
+ +

+ Paid: / {{ amount_requested - amount_paid }} XMR
+

+
+
+
+ + + diff --git a/server/tests/common/mod.rs b/server/tests/common/mod.rs index cab8bd3..dddebb6 100644 --- a/server/tests/common/mod.rs +++ b/server/tests/common/mod.rs @@ -1,35 +1,55 @@ -use std::{sync::Arc, time::Duration}; +use std::{ + net::SocketAddr, + str::FromStr, + sync::{Arc, Mutex, PoisonError}, + time::Duration, +}; -use http::header::{ACCEPT, CONTENT_TYPE}; +use acceptxmr_server::api::{types::invoice_id::Base64InvoiceId, InvoiceUpdate}; +use bytes::Bytes; +use http_body_util::{BodyExt, Empty, Full}; use hyper::{ - client::connect::HttpConnector, header::AUTHORIZATION, Body, Method, Request, Response, Uri, + body::Incoming, + header::AUTHORIZATION, + http::header::{ACCEPT, CONTENT_TYPE}, + service::service_fn, + Error as HyperError, Method, Request, Response, StatusCode, Uri, }; use hyper_rustls::{HttpsConnector, HttpsConnectorBuilder}; -use log::{debug, error, LevelFilter}; -use rustls::{ - client::{ServerCertVerified, ServerCertVerifier}, - ClientConfig, +use hyper_util::{ + client::legacy::{connect::HttpConnector, Client}, + rt::{TokioExecutor, TokioIo}, + server::conn::auto::Builder as ServerBuilder, }; +use log::{debug, error, info}; use serde::{Deserialize, Serialize}; use thiserror::Error; -use tokio::time::{error, timeout}; - -pub const PRIVATE_VIEW_KEY: &str = - "ad2093a5705b9f33e6f0f0c1bc1f5f639c756cdfc168c8f2ac6127ccbdab3a03"; -pub const PRIMARY_ADDRESS: &str = - "4613YiHLM6JMH4zejMB2zJY5TwQCxL8p65ufw8kBP5yxX9itmuGLqp1dS4tkVoTxjyH3aYhYNrtGHbQzJQP5bFus3KHVdmf"; +use tokio::{ + net::{TcpListener, TcpStream}, + sync::mpsc::{self, Receiver, Sender}, + time::{ + error::{self, Elapsed}, + timeout, + }, +}; +use tokio_rustls::rustls::{ + client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier}, + pki_types::{CertificateDer, ServerName, UnixTime}, + ClientConfig, DigitallySignedStruct, Error as RustlsError, SignatureScheme, +}; +use tokio_tungstenite::{MaybeTlsStream, WebSocketStream}; #[derive(Debug, Clone)] -pub struct GatewayClient { - client: hyper::Client>, - pub url: Uri, - timeout: Duration, - pub token: Option, +pub(crate) struct GatewayClient { + client: Client, Full>, + pub(crate) url: Uri, + pub(crate) timeout: Duration, + pub(crate) token: Option, } impl GatewayClient { /// Returns a payment gateway client. - pub fn new( + pub(crate) fn new( url: Uri, total_timeout: Duration, connection_timeout: Duration, @@ -42,7 +62,7 @@ impl GatewayClient { let rustls_connector = HttpsConnectorBuilder::new() .with_tls_config( ClientConfig::builder() - .with_safe_defaults() + .dangerous() .with_custom_certificate_verifier(Arc::new(NoCertVerifier {})) .with_no_client_auth(), ) @@ -50,7 +70,7 @@ impl GatewayClient { .enable_http1() .enable_http2() .wrap_connector(hyper_connector); - let client = hyper::Client::builder().build(rustls_connector); + let client = Client::builder(TokioExecutor::new()).build(rustls_connector); GatewayClient { client, @@ -60,62 +80,92 @@ impl GatewayClient { } } - pub async fn request(&self, body: &str, endpoint: &str) -> Result, ClientError> { + pub(crate) async fn request( + &self, + body: &str, + endpoint: &str, + ) -> Result, ClientError> { let mut response = None; timeout(self.timeout, async { - loop { - let mut request_builder = Request::builder() - .method(Method::POST) - .header(ACCEPT, "*/*") - .header(CONTENT_TYPE, "application/json") - .uri(self.url.clone().to_string() + endpoint); - - if let Some(token) = &self.token { - request_builder = - request_builder.header(AUTHORIZATION, format!("Bearer {}", token)); - } + let mut request_builder = Request::builder() + .method(Method::POST) + .header(ACCEPT, "*/*") + .header(CONTENT_TYPE, "application/json") + .uri(self.url.clone().to_string() + endpoint); + + if let Some(token) = &self.token { + request_builder = request_builder.header(AUTHORIZATION, format!("Bearer {token}")); + } - let request = match request_builder.body(Body::from(body.to_string())) { + let request = + match request_builder.body(Full::new(Bytes::copy_from_slice(body.as_bytes()))) { Ok(r) => r, Err(e) => { response = Some(Err(e.into())); - break; + return; } }; - debug!("Sending request: {:?}", request); + debug!("Sending request: {:?}", request); - match self.client.request(request).await { - Ok(r) => { - response = Some(Ok(r)); - break; - } - Err(e) if e.is_connect() => { - error!("Error connecting to gateway, retrying: {}", e); - continue; - } - Err(e) => { - error!("Checkout response contains an error: {}", e); - response = Some(Err(e.into())) - } - }; - } + match self.client.request(request).await { + Ok(r) if r.status().is_server_error() | r.status().is_client_error() => { + error!( + "Response contains an error. Status code: {}, body: {:?}", + r.status(), + r.body() + ); + response = Some(Ok(r)); + } + Ok(r) => { + debug!("Request successful. Response: {r:?}"); + response = Some(Ok(r)); + } + Err(e) => { + error!("Response contains an error: {}", e); + response = Some(Err(ClientError::Request(Box::new(e)))); + } + }; }) .await?; response.expect("Timed out waiting for response.") } - pub async fn checkout(&self) -> Result, ClientError> { - let endpoint = "checkout"; + pub(crate) async fn new_invoice( + &self, + payload: MockNewInvoicePayload, + ) -> Result, ClientError> { + let endpoint = "invoice"; - #[derive(Deserialize, Serialize)] - struct CheckoutInfo { - message: String, - } + let body = serde_json::to_value(payload) + .expect("failed to build json from new_invoice payload") + .to_string(); - let body = r#"{"message":"This is a test message"}"#; + self.request(&body, endpoint).await + } - self.request(body, endpoint).await + pub(crate) async fn subscribe_to_websocket( + self, + invoice_id: Base64InvoiceId, + ) -> Result>, ClientError> { + let websocket_endpoint = format!( + "ws://{}:{}/invoice/ws?id={invoice_id}", + self.url.host().expect("no host configured"), + self.url.port().expect("no port configured") + ); + debug!("Websocket endpoint: {}", websocket_endpoint); + let (socket, response) = tokio_tungstenite::connect_async(websocket_endpoint) + .await + .map_err(|e| ClientError::WebsocketUpgradeFailure(Box::new(e)))?; + + if response.status() != StatusCode::SWITCHING_PROTOCOLS { + return Err(ClientError::WebsocketUpgradeFailure(Box::new(format!( + "{:?}", + response.into_body() + )))); + } + + Ok(socket) } } @@ -123,52 +173,196 @@ impl Default for GatewayClient { fn default() -> Self { GatewayClient::new( Uri::from_static("https://localhost:8081"), - Duration::from_secs(1), - Duration::from_millis(500), + Duration::from_secs(60), + Duration::from_secs(30), Some("supersecrettoken".to_string()), ) } } -/// Initialize the logging implementation. Defaults to `Trace` verbosity for -/// `AcceptXMR` and `Warn` for dependencies. -pub fn init_logger() { - let _ = env_logger::builder() - .is_test(true) - .filter_level(LevelFilter::Debug) - .filter_module("acceptxmr", LevelFilter::Trace) - .filter_module("acceptxmr_server", LevelFilter::Trace) - .try_init(); -} - +#[derive(Debug)] struct NoCertVerifier {} impl ServerCertVerifier for NoCertVerifier { fn verify_server_cert( &self, - _end_entity: &rustls::Certificate, - _intermediates: &[rustls::Certificate], - _server_name: &rustls::ServerName, - _scts: &mut dyn Iterator, + _end_entity: &CertificateDer<'_>, + _intermediates: &[CertificateDer<'_>], + _server_name: &ServerName<'_>, _ocsp_response: &[u8], - _now: std::time::SystemTime, - ) -> Result { + _now: UnixTime, + ) -> Result { Ok(ServerCertVerified::assertion()) } - fn request_scts(&self) -> bool { - false + fn verify_tls12_signature( + &self, + _message: &[u8], + _cert: &CertificateDer<'_>, + _dss: &DigitallySignedStruct, + ) -> Result { + Ok(HandshakeSignatureValid::assertion()) + } + + fn verify_tls13_signature( + &self, + _message: &[u8], + _cert: &CertificateDer<'_>, + _dss: &DigitallySignedStruct, + ) -> Result { + Ok(HandshakeSignatureValid::assertion()) + } + + fn supported_verify_schemes(&self) -> Vec { + vec![ + SignatureScheme::RSA_PKCS1_SHA1, + SignatureScheme::ECDSA_SHA1_Legacy, + SignatureScheme::RSA_PKCS1_SHA256, + SignatureScheme::ECDSA_NISTP256_SHA256, + SignatureScheme::RSA_PKCS1_SHA384, + SignatureScheme::ECDSA_NISTP384_SHA384, + SignatureScheme::RSA_PKCS1_SHA512, + SignatureScheme::ECDSA_NISTP521_SHA512, + SignatureScheme::RSA_PSS_SHA256, + SignatureScheme::RSA_PSS_SHA384, + SignatureScheme::RSA_PSS_SHA512, + SignatureScheme::ED25519, + SignatureScheme::ED448, + ] } } +#[derive(Deserialize, Serialize)] +pub(crate) struct MockNewInvoicePayload { + pub(crate) piconeros_due: u64, + pub(crate) confirmations_required: u64, + pub(crate) expiration_in: u64, + pub(crate) order: String, + pub(crate) callback: Option, +} + +impl Default for MockNewInvoicePayload { + fn default() -> Self { + MockNewInvoicePayload { + piconeros_due: 2_234_345, + confirmations_required: 2, + expiration_in: 20, + order: "I am a test order".to_string(), + callback: Some("http://localhost:1234".to_string()), + } + } +} + +#[derive(Deserialize, Serialize)] +pub(crate) struct MockInvoiceIdPayload { + pub(crate) invoice_id: Base64InvoiceId, +} + +pub(crate) struct CallbackListener { + address: SocketAddr, + rx: Receiver, + tx: Sender, +} + +async fn handle( + req: Request, + tx: Sender, + rx: Arc>>, +) -> Result>, HyperError> { + let invoice: InvoiceUpdate = + serde_json::from_slice(&req.into_body().collect().await.unwrap().to_bytes()).unwrap(); + tx.send(invoice).await.unwrap(); + + // Check for any commands before responding. + if let Ok(command) = rx.lock().unwrap_or_else(PoisonError::into_inner).try_recv() { + match command { + // Send a bad gateway response as if the service were down. + ListenerCommand::FailNext => { + let mut response = Response::new(Empty::new()); + let status = response.status_mut(); + *status = StatusCode::BAD_GATEWAY; + return Ok::<_, HyperError>(response); + } + } + } + + Ok::<_, HyperError>(Response::new(Empty::new())) +} + +impl CallbackListener { + pub(crate) async fn init() -> Self { + let addr: SocketAddr = ([127, 0, 0, 1], 0).into(); + let listener = TcpListener::bind(addr).await.unwrap(); + let address = listener.local_addr().unwrap(); + + let (update_tx, update_rx) = mpsc::channel(100); + let (command_tx, command_rx) = mpsc::channel(100); + let sharable_command_rx = Arc::new(Mutex::new(command_rx)); + + info!("Callback listener bound to {}", address); + tokio::spawn(async move { + let service = service_fn(|req: Request| { + handle(req, update_tx.clone(), sharable_command_rx.clone()) + }); + + loop { + let (stream, _) = listener.accept().await.unwrap(); + let stream = TokioIo::new(stream); + + let _ = ServerBuilder::new(TokioExecutor::new()) + .serve_connection_with_upgrades(stream, service) + .await; + } + }); + + CallbackListener { + address, + rx: update_rx, + tx: command_tx, + } + } + + pub(crate) async fn recv_timeout( + &mut self, + timeout: Duration, + ) -> Result, Elapsed> { + tokio::time::timeout(timeout, self.rx.recv()).await + } + + pub(crate) fn url(&self) -> Uri { + Uri::from_str(&format!( + "http://{}:{}", + self.address.ip(), + self.address.port() + )) + .unwrap() + } + + pub(crate) fn port(&self) -> u16 { + self.address.port() + } + + /// Artificially fail callback to test retry mechanism. + pub(crate) async fn fail_one_callback(&mut self) { + self.tx.send(ListenerCommand::FailNext).await.unwrap(); + } +} + +enum ListenerCommand { + /// Fail the next callback. + FailNext, +} + #[derive(Error, Debug)] -pub enum ClientError { +pub(crate) enum ClientError { #[error("HTTP request failed: {0}")] - Http(#[from] hyper::Error), + Request(Box), #[error("failed to build HTTP request: {0}")] - Request(#[from] hyper::http::Error), + InvalidRequest(#[from] hyper::http::Error), #[error("HTTP request timed out: {0}")] Timeout(#[from] error::Elapsed), #[error("failed to interpret response body as json: {0}")] InvalidJson(#[from] serde_json::Error), + #[error("failed to upgrade to websocket connection: {0:?}")] + WebsocketUpgradeFailure(Box), } diff --git a/server/tests/integration_tests/bearer_auth.rs b/server/tests/integration_tests/bearer_auth.rs index 5ca8dd3..3ffaa60 100644 --- a/server/tests/integration_tests/bearer_auth.rs +++ b/server/tests/integration_tests/bearer_auth.rs @@ -1,10 +1,13 @@ +use std::{path::PathBuf, str::FromStr}; + use acceptxmr::{storage::stores::Sqlite, PaymentGatewayBuilder}; -use acceptxmr_server::{load_config, run_server}; -use hyper::StatusCode; +use acceptxmr_server::{build_server, load_config, run_server, Config}; +use hyper::{http::Uri, StatusCode}; use log::{debug, info}; use test_case::test_case; +use testing_utils::{init_logger, MockDaemon, PRIMARY_ADDRESS, PRIVATE_VIEW_KEY}; -use crate::common::{init_logger, GatewayClient, PRIMARY_ADDRESS, PRIVATE_VIEW_KEY}; +use crate::common::{GatewayClient, MockNewInvoicePayload}; #[test_case(Some("supersecrettoken") => StatusCode::OK; "Correct token")] #[test_case(Some("I am the wrong token!") => StatusCode::UNAUTHORIZED; "Wrong token")] @@ -12,6 +15,7 @@ use crate::common::{init_logger, GatewayClient, PRIMARY_ADDRESS, PRIVATE_VIEW_KE #[tokio::test] async fn bearer_auth(token: Option<&str>) -> StatusCode { init_logger(); + let mock_daemon = MockDaemon::new_mock_daemon().await; let store = Sqlite::new(":memory:", "invoices", "output keys", "height").unwrap(); let payment_gateway = PaymentGatewayBuilder::new( @@ -19,23 +23,31 @@ async fn bearer_auth(token: Option<&str>) -> StatusCode { PRIMARY_ADDRESS.to_string(), store, ) + .daemon_url(mock_daemon.url("")) .build() + .await .unwrap(); info!("Payment gateway created."); // Deliberately not starting the payment gateway itself, because we don't // need it for this test. - let config = load_config(); - tokio::spawn(run_server(config, payment_gateway)); + let config = load_config(&PathBuf::from(Config::DEFAULT_PATH)); + let server = build_server(&config, payment_gateway).await; + let address = server.internal_ipv4_address().unwrap(); + tokio::spawn(async { + run_server(server).await; + }); let mut client = GatewayClient::default(); - client.token = token.map(|s| s.to_string()); - let checkout_response = client - .checkout() + client.url = Uri::from_str(&format!("https://{}:{}", address.ip(), address.port())).unwrap(); + client.token = token.map(ToString::to_string); + + let new_invoice_response = client + .new_invoice(MockNewInvoicePayload::default()) .await - .expect("failed to call `checkout` endpoint"); - debug!("Checkout response: {:?}", checkout_response); - checkout_response.status() + .expect("failed to call new invoice endpoint"); + debug!("Checkout response: {:?}", new_invoice_response); + new_invoice_response.status() } diff --git a/server/tests/integration_tests/callback.rs b/server/tests/integration_tests/callback.rs new file mode 100644 index 0000000..9d6dffe --- /dev/null +++ b/server/tests/integration_tests/callback.rs @@ -0,0 +1,153 @@ +use std::{path::PathBuf, str::FromStr, time::Duration}; + +use acceptxmr::{storage::stores::Sqlite, PaymentGatewayBuilder}; +use acceptxmr_server::{build_server, load_config, run_server, spawn_gateway, Config}; +use hyper::http::Uri; +use log::{debug, info}; +use serde_json::json; +use testing_utils::{init_logger, MockDaemon, PRIMARY_ADDRESS, PRIVATE_VIEW_KEY}; + +use crate::common::{CallbackListener, GatewayClient, MockNewInvoicePayload}; + +#[tokio::test] +async fn callback() { + init_logger(); + let mock_daemon = MockDaemon::new_mock_daemon().await; + + let store = Sqlite::new(":memory:", "invoices", "output keys", "height").unwrap(); + let payment_gateway = PaymentGatewayBuilder::new( + PRIVATE_VIEW_KEY.to_string(), + PRIMARY_ADDRESS.to_string(), + store, + ) + // Faster scan rate so the update is received sooner. + .scan_interval(Duration::from_millis(100)) + .daemon_url(mock_daemon.url("")) + .seed(1) + .build() + .await + .unwrap(); + info!("Payment gateway created."); + + let config = load_config(&PathBuf::from(Config::DEFAULT_PATH)); + let payment_gateway = spawn_gateway(payment_gateway, &config).await; + + let server = build_server(&config, payment_gateway).await; + let address = server.internal_ipv4_address().unwrap(); + tokio::spawn(run_server(server)); + + let mut client = GatewayClient::default(); + client.token = Some("supersecrettoken".to_string()); + client.url = Uri::from_str(&format!("https://{}:{}", address.ip(), address.port())).unwrap(); + + let mut callback_listener = CallbackListener::init().await; + let callback_url = callback_listener.url(); + + let new_invoice_payload = MockNewInvoicePayload { + callback: Some(callback_url.to_string()), + ..Default::default() + }; + let new_invoice_response = client + .new_invoice(new_invoice_payload) + .await + .expect("failed to call `checkout` endpoint"); + debug!("Checkout response: {:?}", new_invoice_response); + + // Listen for callback from initial update. + let callback = callback_listener + .recv_timeout(Duration::from_secs(120)) + .await + .expect("timeout waiting for callback") + .expect("channel to callback listener closed"); + + assert_eq!( + json!(callback), + json!({ + "address": "82ZZhxB2dAtGwRQSSzvc9fUfM2oFWCUBUFJUAYDsureAB57RZEXm7fyZjwVXGyDGMA3wMtZjMSzECjfbkk5jYkA1SDmWWkx", + "amount_paid": 0, + "amount_requested": 2_234_345, + "callback": format!("http://127.0.0.1:{}/", callback_listener.port()), + "confirmations": None::, + "confirmations_required": 2, + "current_height": 2_477_657, + "expiration_in": 20, + "id": "AAAAAAAAAGEAAAAAACXOWQ", + "order": "I am a test order", + "uri": "monero:82ZZhxB2dAtGwRQSSzvc9fUfM2oFWCUBUFJUAYDsureAB57RZEXm7fyZjwVXGyDGMA3wMtZjMSzECjfbkk5jYkA1SDmWWkx?tx_amount=0.000002234345" + }) + ); +} + +/// Fail the first callback and assert that it is retried. +#[tokio::test] +async fn callback_retry() { + init_logger(); + let mock_daemon = MockDaemon::new_mock_daemon().await; + + let store = Sqlite::new(":memory:", "invoices", "output keys", "height").unwrap(); + let payment_gateway = PaymentGatewayBuilder::new( + PRIVATE_VIEW_KEY.to_string(), + PRIMARY_ADDRESS.to_string(), + store, + ) + // Faster scan rate so the update is received sooner. + .scan_interval(Duration::from_millis(1000)) + .daemon_url(mock_daemon.url("")) + .seed(1) + .build() + .await + .unwrap(); + info!("Payment gateway created."); + + let config = load_config(&PathBuf::from(Config::DEFAULT_PATH)); + let payment_gateway = spawn_gateway(payment_gateway, &config).await; + + let server = build_server(&config, payment_gateway).await; + info!("Built AcceptXMR server."); + let address = server.internal_ipv4_address().unwrap(); + info!("Starting with internal address {address}"); + tokio::spawn(run_server(server)); + + let mut client = GatewayClient::default(); + client.token = Some("supersecrettoken".to_string()); + client.url = Uri::from_str(&format!("https://{}:{}", address.ip(), address.port())).unwrap(); + + info!("Starting callback listener."); + let mut callback_listener = CallbackListener::init().await; + info!("Started callback listener."); + callback_listener.fail_one_callback().await; + callback_listener.fail_one_callback().await; + let callback_url = callback_listener.url(); + + let new_invoice_payload = MockNewInvoicePayload { + callback: Some(callback_url.to_string()), + ..Default::default() + }; + info!("Creating new invoice."); + let new_invoice_response = client + .new_invoice(new_invoice_payload) + .await + .expect("failed to call `checkout` endpoint"); + info!("Checkout response: {:?}", new_invoice_response); + + // This one will have been failed. + callback_listener + .recv_timeout(Duration::from_secs(120)) + .await + .unwrap(); + + // This one will also have been failed. + callback_listener + .recv_timeout(Duration::from_secs(120)) + .await + .unwrap(); + + // Now ensure it gets retried. + let callback = callback_listener + .recv_timeout(Duration::from_secs(120)) + .await + .expect("timeout waiting for callback") + .expect("channel to callback listener closed"); + assert_eq!(callback.order, "I am a test order"); + assert_eq!(callback.uri, "monero:82ZZhxB2dAtGwRQSSzvc9fUfM2oFWCUBUFJUAYDsureAB57RZEXm7fyZjwVXGyDGMA3wMtZjMSzECjfbkk5jYkA1SDmWWkx?tx_amount=0.000002234345"); +} diff --git a/server/tests/integration_tests/mod.rs b/server/tests/integration_tests/mod.rs index 5d46ef0..9f6417a 100644 --- a/server/tests/integration_tests/mod.rs +++ b/server/tests/integration_tests/mod.rs @@ -1 +1,3 @@ mod bearer_auth; +mod callback; +mod websocket; diff --git a/server/tests/integration_tests/websocket.rs b/server/tests/integration_tests/websocket.rs new file mode 100644 index 0000000..9512bf1 --- /dev/null +++ b/server/tests/integration_tests/websocket.rs @@ -0,0 +1,149 @@ +use std::{path::PathBuf, str::FromStr, time::Duration}; + +use acceptxmr::{storage::stores::Sqlite, PaymentGatewayBuilder}; +use acceptxmr_server::{ + api::types::invoice_id::Base64InvoiceId, build_server, load_config, run_server, spawn_gateway, + Config, +}; +use futures::StreamExt; +use http_body_util::BodyExt; +use hyper::http::Uri; +use log::{debug, info}; +use serde_json::{json, Value}; +use testing_utils::{init_logger, MockDaemon, PRIMARY_ADDRESS, PRIVATE_VIEW_KEY}; +use tokio::time::timeout; +use tokio_tungstenite::tungstenite; + +use crate::common::{CallbackListener, GatewayClient, MockInvoiceIdPayload, MockNewInvoicePayload}; + +#[tokio::test] +async fn websocket() { + init_logger(); + let mock_daemon = MockDaemon::new_mock_daemon().await; + + let store = Sqlite::new(":memory:", "invoices", "output keys", "height").unwrap(); + let payment_gateway = PaymentGatewayBuilder::new( + PRIVATE_VIEW_KEY.to_string(), + PRIMARY_ADDRESS.to_string(), + store, + ) + // Faster scan rate so the update is received sooner. + .scan_interval(Duration::from_millis(100)) + .daemon_url(mock_daemon.url("")) + .seed(1) + .build() + .await + .unwrap(); + info!("Payment gateway created."); + + let config = load_config(&PathBuf::from(Config::DEFAULT_PATH)); + let payment_gateway = spawn_gateway(payment_gateway, &config).await; + + let server = build_server(&config, payment_gateway).await; + let internal_address = server.internal_ipv4_address().unwrap(); + let external_address = server.external_ipv4_address().unwrap(); + tokio::spawn(run_server(server)); + + let mut internal_client = GatewayClient::default(); + internal_client.token = Some("supersecrettoken".to_string()); + internal_client.url = Uri::from_str(&format!( + "https://{}:{}", + internal_address.ip(), + internal_address.port() + )) + .unwrap(); + + let mut callback_listener = CallbackListener::init().await; + + let base64_invoice_id = new_invoice(&internal_client, &callback_listener).await; + + // Listen for callback from initial update. + let callback = callback_listener + .recv_timeout(Duration::from_secs(120)) + .await + .expect("timeout waiting for callback") + .expect("channel to callback listener closed"); + assert_eq!(callback.order, "I am a test order"); + assert_eq!(callback.uri, "monero:82ZZhxB2dAtGwRQSSzvc9fUfM2oFWCUBUFJUAYDsureAB57RZEXm7fyZjwVXGyDGMA3wMtZjMSzECjfbkk5jYkA1SDmWWkx?tx_amount=0.000002234345"); + + let mut external_client = GatewayClient::default(); + external_client.url = Uri::from_str(&format!( + "http://{}:{}", + external_address.ip(), + external_address.port() + )) + .unwrap(); + + // Add transfer to txpool. + let txpool_hashes_mock = mock_daemon.mock_txpool_hashes( + "../testing-utils/rpc_resources/txpools/hashes_with_payment_account_0.json", + ); + let txpool_transactions_mock = mock_daemon.mock_txpool_transactions( + "../testing-utils/rpc_resources/transactions/hashes_with_payment_account_0.json", + "../testing-utils/rpc_resources/transactions/txs_with_payment_account_0.json", + ); + + let mut websocket = external_client + .subscribe_to_websocket(base64_invoice_id.clone()) + .await + .expect("failed to call `/invoice/ws` endpoint"); + + let msg = match timeout(Duration::from_secs(120), websocket.next()) + .await + .unwrap() + .expect("websocket closed unexpectedly") + .unwrap() + { + tungstenite::Message::Text(msg) => msg, + other => panic!("Unexpected message type: {other}"), + }; + debug!("{msg}"); + + assert!(txpool_hashes_mock.hits() > 0); + assert!(txpool_transactions_mock.hits() > 0); + + assert_eq!( + Value::from_str(&msg).unwrap(), + json!({ + "address": "82ZZhxB2dAtGwRQSSzvc9fUfM2oFWCUBUFJUAYDsureAB57RZEXm7fyZjwVXGyDGMA3wMtZjMSzECjfbkk5jYkA1SDmWWkx", + "amount_paid": 1_468_383_460, + "amount_requested": 2_234_345, + "callback": format!("http://127.0.0.1:{}/", callback_listener.port()), + "confirmations": 0, + "confirmations_required": 2, + "current_height": 2_477_657, + "expiration_in": 20, + "id": "AAAAAAAAAGEAAAAAACXOWQ", + "order": "I am a test order", + "uri": "monero:82ZZhxB2dAtGwRQSSzvc9fUfM2oFWCUBUFJUAYDsureAB57RZEXm7fyZjwVXGyDGMA3wMtZjMSzECjfbkk5jYkA1SDmWWkx?tx_amount=0.0" + }) + ); +} + +async fn new_invoice( + client: &GatewayClient, + callback_listener: &CallbackListener, +) -> Base64InvoiceId { + let new_invoice_payload = MockNewInvoicePayload { + callback: Some(callback_listener.url().to_string()), + ..Default::default() + }; + let new_invoice_response = client + .new_invoice(new_invoice_payload) + .await + .expect("failed to call `checkout` endpoint"); + debug!("Checkout response: {:?}", new_invoice_response); + let MockInvoiceIdPayload { + invoice_id: base64_invoice_id, + } = serde_json::from_slice( + &new_invoice_response + .into_body() + .collect() + .await + .unwrap() + .to_bytes(), + ) + .unwrap(); + + base64_invoice_id +} diff --git a/server/tests/testdata/config/config_full.yaml b/server/tests/testdata/config/config_full.yaml index a4c1d42..4f0e92a 100644 --- a/server/tests/testdata/config/config_full.yaml +++ b/server/tests/testdata/config/config_full.yaml @@ -11,6 +11,9 @@ internal-api: cert: "/path/to/cert.pem" key: "/path/to/key.pem" static_dir: server/static/ +callback: + queue-size: 500 + max-retries: 25 wallet: primary-address: "4613YiHLM6JMH4zejMB2zJY5TwQCxL8p65ufw8kBP5yxX9itmuGLqp1dS4tkVoTxjyH3aYhYNrtGHbQzJQP5bFus3KHVdmf" private-viewkey: "ad2093a5705b9f33e6f0f0c1bc1f5f639c756cdfc168c8f2ac6127ccbdab3a03" @@ -20,7 +23,10 @@ daemon: login: username: "pinkpanther" password: "supersecretpassword" + rpc-timeout: 20 + connection-timeout: 10 database: path: "server/tests/AcceptXMR_DB/" + delete-expired: true logging: verbosity: "Debug" diff --git a/server/tests/testdata/config/config_no_secrets.yaml b/server/tests/testdata/config/config_no_secrets.yaml index d2c695b..7ec8b3a 100644 --- a/server/tests/testdata/config/config_no_secrets.yaml +++ b/server/tests/testdata/config/config_no_secrets.yaml @@ -10,6 +10,9 @@ internal-api: cert: "/path/to/cert.pem" key: "/path/to/key.pem" static_dir: server/static/ +callback: + queue-size: 500 + max-retries: 25 wallet: primary-address: "4613YiHLM6JMH4zejMB2zJY5TwQCxL8p65ufw8kBP5yxX9itmuGLqp1dS4tkVoTxjyH3aYhYNrtGHbQzJQP5bFus3KHVdmf" restore-height: 2947000 @@ -17,7 +20,10 @@ daemon: url: "https://node.example.com:18081" login: username: "pinkpanther" + rpc-timeout: 20 + connection-timeout: 10 database: path: "server/tests/AcceptXMR_DB/" + delete-expired: true logging: verbosity: "Debug" diff --git a/testing-utils/Cargo.toml b/testing-utils/Cargo.toml new file mode 100644 index 0000000..54fee07 --- /dev/null +++ b/testing-utils/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "testing-utils" +publish = false +version = "0.1.0" +edition = "2021" +rust-version = "1.70" +license = "MIT OR Apache-2.0" +description = "Testing utilities for AcceptXMR" +repository = "https://github.com/busyboredom/acceptxmr" +readme = "README.md" +keywords = ["crypto", "gateway", "monero", "payment", "xmr"] +categories = ["cryptography::cryptocurrencies"] + +[lints] +workspace = true + +[lib] +name = "testing_utils" +path = "src/lib.rs" + +[dependencies] +acceptxmr.workspace = true +httpmock.workspace = true +log.workspace = true +serde_json.workspace = true +tempfile.workspace = true +tracing-subscriber = { workspace = true, features = ["env-filter"] } diff --git a/library/tests/rpc_resources/blocks/2477647/block.json b/testing-utils/rpc_resources/blocks/2477647/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477647/block.json rename to testing-utils/rpc_resources/blocks/2477647/block.json diff --git a/library/tests/rpc_resources/blocks/2477647/transactions_0.json b/testing-utils/rpc_resources/blocks/2477647/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477647/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477647/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477647/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477647/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477647/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477647/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477648/block.json b/testing-utils/rpc_resources/blocks/2477648/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477648/block.json rename to testing-utils/rpc_resources/blocks/2477648/block.json diff --git a/library/tests/rpc_resources/blocks/2477648/transactions_0.json b/testing-utils/rpc_resources/blocks/2477648/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477648/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477648/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477648/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477648/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477648/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477648/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477649/block.json b/testing-utils/rpc_resources/blocks/2477649/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477649/block.json rename to testing-utils/rpc_resources/blocks/2477649/block.json diff --git a/library/tests/rpc_resources/blocks/2477649/transactions_0.json b/testing-utils/rpc_resources/blocks/2477649/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477649/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477649/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477649/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477649/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477649/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477649/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477650/block.json b/testing-utils/rpc_resources/blocks/2477650/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477650/block.json rename to testing-utils/rpc_resources/blocks/2477650/block.json diff --git a/library/tests/rpc_resources/blocks/2477650/transactions_0.json b/testing-utils/rpc_resources/blocks/2477650/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477650/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477650/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477650/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477650/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477650/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477650/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477651/block.json b/testing-utils/rpc_resources/blocks/2477651/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477651/block.json rename to testing-utils/rpc_resources/blocks/2477651/block.json diff --git a/library/tests/rpc_resources/blocks/2477651/transactions_0.json b/testing-utils/rpc_resources/blocks/2477651/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477651/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477651/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477651/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477651/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477651/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477651/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477652/block.json b/testing-utils/rpc_resources/blocks/2477652/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477652/block.json rename to testing-utils/rpc_resources/blocks/2477652/block.json diff --git a/library/tests/rpc_resources/blocks/2477652/transactions_0.json b/testing-utils/rpc_resources/blocks/2477652/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477652/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477652/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477652/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477652/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477652/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477652/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477653/block.json b/testing-utils/rpc_resources/blocks/2477653/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477653/block.json rename to testing-utils/rpc_resources/blocks/2477653/block.json diff --git a/library/tests/rpc_resources/blocks/2477653/transactions_0.json b/testing-utils/rpc_resources/blocks/2477653/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477653/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477653/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477653/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477653/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477653/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477653/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477654/block.json b/testing-utils/rpc_resources/blocks/2477654/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477654/block.json rename to testing-utils/rpc_resources/blocks/2477654/block.json diff --git a/library/tests/rpc_resources/blocks/2477654/transactions_0.json b/testing-utils/rpc_resources/blocks/2477654/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477654/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477654/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477654/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477654/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477654/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477654/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477655/block.json b/testing-utils/rpc_resources/blocks/2477655/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477655/block.json rename to testing-utils/rpc_resources/blocks/2477655/block.json diff --git a/library/tests/rpc_resources/blocks/2477655/transactions_0.json b/testing-utils/rpc_resources/blocks/2477655/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477655/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477655/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477655/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477655/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477655/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477655/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477656/block.json b/testing-utils/rpc_resources/blocks/2477656/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477656/block.json rename to testing-utils/rpc_resources/blocks/2477656/block.json diff --git a/library/tests/rpc_resources/blocks/2477656/daemon_height.json b/testing-utils/rpc_resources/blocks/2477656/daemon_height.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477656/daemon_height.json rename to testing-utils/rpc_resources/blocks/2477656/daemon_height.json diff --git a/library/tests/rpc_resources/blocks/2477656/transactions_0.json b/testing-utils/rpc_resources/blocks/2477656/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477656/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477656/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477656/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477656/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477656/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477656/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477657/block.json b/testing-utils/rpc_resources/blocks/2477657/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477657/block.json rename to testing-utils/rpc_resources/blocks/2477657/block.json diff --git a/library/tests/rpc_resources/blocks/2477657/daemon_height.json b/testing-utils/rpc_resources/blocks/2477657/daemon_height.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477657/daemon_height.json rename to testing-utils/rpc_resources/blocks/2477657/daemon_height.json diff --git a/library/tests/rpc_resources/blocks/2477657/transactions_0.json b/testing-utils/rpc_resources/blocks/2477657/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477657/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477657/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477657/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477657/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477657/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477657/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477657_alt/block.json b/testing-utils/rpc_resources/blocks/2477657_alt/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477657_alt/block.json rename to testing-utils/rpc_resources/blocks/2477657_alt/block.json diff --git a/library/tests/rpc_resources/blocks/2477657_alt/daemon_height.json b/testing-utils/rpc_resources/blocks/2477657_alt/daemon_height.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477657_alt/daemon_height.json rename to testing-utils/rpc_resources/blocks/2477657_alt/daemon_height.json diff --git a/library/tests/rpc_resources/blocks/2477657_alt/transactions_0.json b/testing-utils/rpc_resources/blocks/2477657_alt/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477657_alt/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477657_alt/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477657_alt/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477657_alt/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477657_alt/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477657_alt/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477658/block.json b/testing-utils/rpc_resources/blocks/2477658/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477658/block.json rename to testing-utils/rpc_resources/blocks/2477658/block.json diff --git a/library/tests/rpc_resources/blocks/2477658/daemon_height.json b/testing-utils/rpc_resources/blocks/2477658/daemon_height.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477658/daemon_height.json rename to testing-utils/rpc_resources/blocks/2477658/daemon_height.json diff --git a/library/tests/rpc_resources/blocks/2477658/transactions_0.json b/testing-utils/rpc_resources/blocks/2477658/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477658/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477658/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477658/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477658/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477658/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477658/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477658_alt/block.json b/testing-utils/rpc_resources/blocks/2477658_alt/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477658_alt/block.json rename to testing-utils/rpc_resources/blocks/2477658_alt/block.json diff --git a/library/tests/rpc_resources/blocks/2477658_alt/daemon_height.json b/testing-utils/rpc_resources/blocks/2477658_alt/daemon_height.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477658_alt/daemon_height.json rename to testing-utils/rpc_resources/blocks/2477658_alt/daemon_height.json diff --git a/library/tests/rpc_resources/blocks/2477658_alt/transactions_0.json b/testing-utils/rpc_resources/blocks/2477658_alt/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477658_alt/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477658_alt/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477658_alt/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477658_alt/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477658_alt/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477658_alt/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477659/block.json b/testing-utils/rpc_resources/blocks/2477659/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477659/block.json rename to testing-utils/rpc_resources/blocks/2477659/block.json diff --git a/library/tests/rpc_resources/blocks/2477659/daemon_height.json b/testing-utils/rpc_resources/blocks/2477659/daemon_height.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477659/daemon_height.json rename to testing-utils/rpc_resources/blocks/2477659/daemon_height.json diff --git a/library/tests/rpc_resources/blocks/2477659/transactions_0.json b/testing-utils/rpc_resources/blocks/2477659/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477659/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477659/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477659/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477659/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477659/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477659/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477660/block.json b/testing-utils/rpc_resources/blocks/2477660/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477660/block.json rename to testing-utils/rpc_resources/blocks/2477660/block.json diff --git a/library/tests/rpc_resources/blocks/2477660/daemon_height.json b/testing-utils/rpc_resources/blocks/2477660/daemon_height.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477660/daemon_height.json rename to testing-utils/rpc_resources/blocks/2477660/daemon_height.json diff --git a/library/tests/rpc_resources/blocks/2477660/transactions_0.json b/testing-utils/rpc_resources/blocks/2477660/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477660/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477660/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477660/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477660/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477660/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477660/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477661/block.json b/testing-utils/rpc_resources/blocks/2477661/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477661/block.json rename to testing-utils/rpc_resources/blocks/2477661/block.json diff --git a/library/tests/rpc_resources/blocks/2477661/daemon_height.json b/testing-utils/rpc_resources/blocks/2477661/daemon_height.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477661/daemon_height.json rename to testing-utils/rpc_resources/blocks/2477661/daemon_height.json diff --git a/library/tests/rpc_resources/blocks/2477661/transactions_0.json b/testing-utils/rpc_resources/blocks/2477661/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477661/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477661/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477661/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477661/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477661/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477661/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477662/block.json b/testing-utils/rpc_resources/blocks/2477662/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477662/block.json rename to testing-utils/rpc_resources/blocks/2477662/block.json diff --git a/library/tests/rpc_resources/blocks/2477662/daemon_height.json b/testing-utils/rpc_resources/blocks/2477662/daemon_height.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477662/daemon_height.json rename to testing-utils/rpc_resources/blocks/2477662/daemon_height.json diff --git a/library/tests/rpc_resources/blocks/2477662/transactions_0.json b/testing-utils/rpc_resources/blocks/2477662/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477662/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477662/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477662/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477662/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477662/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477662/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477663/block.json b/testing-utils/rpc_resources/blocks/2477663/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477663/block.json rename to testing-utils/rpc_resources/blocks/2477663/block.json diff --git a/library/tests/rpc_resources/blocks/2477663/daemon_height.json b/testing-utils/rpc_resources/blocks/2477663/daemon_height.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477663/daemon_height.json rename to testing-utils/rpc_resources/blocks/2477663/daemon_height.json diff --git a/library/tests/rpc_resources/blocks/2477663/transactions_0.json b/testing-utils/rpc_resources/blocks/2477663/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477663/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477663/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477663/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477663/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477663/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477663/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477664/block.json b/testing-utils/rpc_resources/blocks/2477664/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477664/block.json rename to testing-utils/rpc_resources/blocks/2477664/block.json diff --git a/library/tests/rpc_resources/blocks/2477664/daemon_height.json b/testing-utils/rpc_resources/blocks/2477664/daemon_height.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477664/daemon_height.json rename to testing-utils/rpc_resources/blocks/2477664/daemon_height.json diff --git a/library/tests/rpc_resources/blocks/2477664/transactions_0.json b/testing-utils/rpc_resources/blocks/2477664/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477664/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477664/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477664/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477664/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477664/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477664/txs_hashes_0.json diff --git a/library/tests/rpc_resources/blocks/2477665/block.json b/testing-utils/rpc_resources/blocks/2477665/block.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477665/block.json rename to testing-utils/rpc_resources/blocks/2477665/block.json diff --git a/library/tests/rpc_resources/blocks/2477665/daemon_height.json b/testing-utils/rpc_resources/blocks/2477665/daemon_height.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477665/daemon_height.json rename to testing-utils/rpc_resources/blocks/2477665/daemon_height.json diff --git a/library/tests/rpc_resources/blocks/2477665/transactions_0.json b/testing-utils/rpc_resources/blocks/2477665/transactions_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477665/transactions_0.json rename to testing-utils/rpc_resources/blocks/2477665/transactions_0.json diff --git a/library/tests/rpc_resources/blocks/2477665/txs_hashes_0.json b/testing-utils/rpc_resources/blocks/2477665/txs_hashes_0.json similarity index 100% rename from library/tests/rpc_resources/blocks/2477665/txs_hashes_0.json rename to testing-utils/rpc_resources/blocks/2477665/txs_hashes_0.json diff --git a/library/tests/rpc_resources/transactions/hashes_with_payment.json b/testing-utils/rpc_resources/transactions/hashes_with_payment.json similarity index 100% rename from library/tests/rpc_resources/transactions/hashes_with_payment.json rename to testing-utils/rpc_resources/transactions/hashes_with_payment.json diff --git a/library/tests/rpc_resources/transactions/hashes_with_payment_2.json b/testing-utils/rpc_resources/transactions/hashes_with_payment_2.json similarity index 100% rename from library/tests/rpc_resources/transactions/hashes_with_payment_2.json rename to testing-utils/rpc_resources/transactions/hashes_with_payment_2.json diff --git a/library/tests/rpc_resources/transactions/hashes_with_payment_account_0.json b/testing-utils/rpc_resources/transactions/hashes_with_payment_account_0.json similarity index 100% rename from library/tests/rpc_resources/transactions/hashes_with_payment_account_0.json rename to testing-utils/rpc_resources/transactions/hashes_with_payment_account_0.json diff --git a/library/tests/rpc_resources/transactions/hashes_with_payment_timelock.json b/testing-utils/rpc_resources/transactions/hashes_with_payment_timelock.json similarity index 100% rename from library/tests/rpc_resources/transactions/hashes_with_payment_timelock.json rename to testing-utils/rpc_resources/transactions/hashes_with_payment_timelock.json diff --git a/library/tests/rpc_resources/transactions/txs_with_payment.json b/testing-utils/rpc_resources/transactions/txs_with_payment.json similarity index 100% rename from library/tests/rpc_resources/transactions/txs_with_payment.json rename to testing-utils/rpc_resources/transactions/txs_with_payment.json diff --git a/library/tests/rpc_resources/transactions/txs_with_payment_2.json b/testing-utils/rpc_resources/transactions/txs_with_payment_2.json similarity index 100% rename from library/tests/rpc_resources/transactions/txs_with_payment_2.json rename to testing-utils/rpc_resources/transactions/txs_with_payment_2.json diff --git a/library/tests/rpc_resources/transactions/txs_with_payment_account_0.json b/testing-utils/rpc_resources/transactions/txs_with_payment_account_0.json similarity index 100% rename from library/tests/rpc_resources/transactions/txs_with_payment_account_0.json rename to testing-utils/rpc_resources/transactions/txs_with_payment_account_0.json diff --git a/library/tests/rpc_resources/transactions/txs_with_payment_timelock.json b/testing-utils/rpc_resources/transactions/txs_with_payment_timelock.json similarity index 100% rename from library/tests/rpc_resources/transactions/txs_with_payment_timelock.json rename to testing-utils/rpc_resources/transactions/txs_with_payment_timelock.json diff --git a/library/tests/rpc_resources/txpools/hashes.json b/testing-utils/rpc_resources/txpools/hashes.json similarity index 100% rename from library/tests/rpc_resources/txpools/hashes.json rename to testing-utils/rpc_resources/txpools/hashes.json diff --git a/library/tests/rpc_resources/txpools/hashes_with_payment.json b/testing-utils/rpc_resources/txpools/hashes_with_payment.json similarity index 100% rename from library/tests/rpc_resources/txpools/hashes_with_payment.json rename to testing-utils/rpc_resources/txpools/hashes_with_payment.json diff --git a/library/tests/rpc_resources/txpools/hashes_with_payment_2.json b/testing-utils/rpc_resources/txpools/hashes_with_payment_2.json similarity index 100% rename from library/tests/rpc_resources/txpools/hashes_with_payment_2.json rename to testing-utils/rpc_resources/txpools/hashes_with_payment_2.json diff --git a/library/tests/rpc_resources/txpools/hashes_with_payment_account_0.json b/testing-utils/rpc_resources/txpools/hashes_with_payment_account_0.json similarity index 100% rename from library/tests/rpc_resources/txpools/hashes_with_payment_account_0.json rename to testing-utils/rpc_resources/txpools/hashes_with_payment_account_0.json diff --git a/library/tests/rpc_resources/txpools/hashes_with_payment_timelock.json b/testing-utils/rpc_resources/txpools/hashes_with_payment_timelock.json similarity index 100% rename from library/tests/rpc_resources/txpools/hashes_with_payment_timelock.json rename to testing-utils/rpc_resources/txpools/hashes_with_payment_timelock.json diff --git a/library/tests/rpc_resources/txpools/txpool.json b/testing-utils/rpc_resources/txpools/txpool.json similarity index 100% rename from library/tests/rpc_resources/txpools/txpool.json rename to testing-utils/rpc_resources/txpools/txpool.json diff --git a/library/tests/rpc_resources/txpools/txpool_with_payment.json b/testing-utils/rpc_resources/txpools/txpool_with_payment.json similarity index 100% rename from library/tests/rpc_resources/txpools/txpool_with_payment.json rename to testing-utils/rpc_resources/txpools/txpool_with_payment.json diff --git a/library/tests/rpc_resources/txpools/txpool_with_payment_2.json b/testing-utils/rpc_resources/txpools/txpool_with_payment_2.json similarity index 100% rename from library/tests/rpc_resources/txpools/txpool_with_payment_2.json rename to testing-utils/rpc_resources/txpools/txpool_with_payment_2.json diff --git a/library/tests/rpc_resources/txpools/txpool_with_payment_account_0.json b/testing-utils/rpc_resources/txpools/txpool_with_payment_account_0.json similarity index 100% rename from library/tests/rpc_resources/txpools/txpool_with_payment_account_0.json rename to testing-utils/rpc_resources/txpools/txpool_with_payment_account_0.json diff --git a/library/tests/rpc_resources/txpools/txpool_with_payment_timelock.json b/testing-utils/rpc_resources/txpools/txpool_with_payment_timelock.json similarity index 100% rename from library/tests/rpc_resources/txpools/txpool_with_payment_timelock.json rename to testing-utils/rpc_resources/txpools/txpool_with_payment_timelock.json diff --git a/testing-utils/src/daemon.rs b/testing-utils/src/daemon.rs new file mode 100644 index 0000000..73b724d --- /dev/null +++ b/testing-utils/src/daemon.rs @@ -0,0 +1,233 @@ +use std::{collections::HashMap, fs, ops::Deref, sync::Mutex}; + +use httpmock::{Mock, MockServer}; +use serde_json::{json, Value}; + +pub struct MockDaemon { + server: MockServer, + daemon_height_id: Mutex>, + block_ids: Mutex>, + txpool_id: Mutex>, + txpool_hashes_id: Mutex>, + txpool_transactions_id: Mutex>, +} + +impl Deref for MockDaemon { + type Target = MockServer; + + fn deref(&self) -> &MockServer { + &self.server + } +} + +impl MockDaemon { + pub async fn new_mock_daemon() -> MockDaemon { + let mock_daemon = MockDaemon { + server: MockServer::start_async().await, + daemon_height_id: Mutex::new(None), + block_ids: Mutex::new(HashMap::new()), + txpool_id: Mutex::new(None), + txpool_hashes_id: Mutex::new(None), + txpool_transactions_id: Mutex::new(None), + }; + // Mock daemon height request. + mock_daemon.mock_daemon_height(2_477_657); + // Mock txpool request. + mock_daemon.mock_txpool("../testing-utils/rpc_resources/txpools/txpool.json"); + // Mock txpool hashes. + mock_daemon.mock_txpool_hashes("../testing-utils/rpc_resources/txpools/hashes.json"); + + // Mock blocks. + for i in 2_477_647..2_477_666 { + // Mock block requests. + let response_path = "../testing-utils/rpc_resources/blocks/".to_owned() + + &i.to_string() + + "/block.json"; + mock_daemon.mock_block(i, &response_path); + + // Skip block 2477661 when mocking transactions, because it has none. + if i == 2_477_661 { + continue; + } + + // Mock block transaction requests. + let request_path = "../testing-utils/rpc_resources/blocks/".to_owned() + + &i.to_string() + + "/txs_hashes_0.json"; + let response_path = "../testing-utils/rpc_resources/blocks/".to_owned() + + &i.to_string() + + "/transactions_0.json"; + mock_daemon.mock_transactions(&request_path, &response_path); + } + mock_daemon + } + + pub fn mock_daemon_height(&self, height: u64) -> Mock { + // Use mock ID to delete old daemon height mock. + if let Some(id) = *self + .daemon_height_id + .lock() + .expect("PoisonError when reading daemon height mock ID") + { + Mock::new(id, self).delete(); + }; + + // Create the new daemon height mock. + let mock = self.mock(|when, then| { + when.path("/json_rpc") + .body(r#"{"jsonrpc":"2.0","id":"0","method":"get_block_count"}"#); + then.status(200) + .header("content-type", "application/json") + .json_body(json!({ + "id": "0", + "jsonrpc": "2.0", + "result": { + "count": height, + "status": "OK" + } + })); + }); + *self + .daemon_height_id + .lock() + .expect("PoisonError when writing daemon height mock ID") = Some(mock.id); + mock + } + + pub fn mock_alt_2477657(&self) { + // Mock block requests. + let response_path = "../testing-utils/rpc_resources/blocks/2477657_alt/block.json"; + self.mock_block(2_477_657, response_path); + + // Mock block transaction requests. + let request_path = "../testing-utils/rpc_resources/blocks/2477657_alt/txs_hashes_0.json"; + let response_path = "../testing-utils/rpc_resources/blocks/2477657_alt/transactions_0.json"; + self.mock_transactions(request_path, response_path); + } + + pub fn mock_alt_2477658(&self) { + // Mock block requests. + let response_path = "../testing-utils/rpc_resources/blocks/2477658_alt/block.json"; + self.mock_block(2_477_658, response_path); + + // Mock block transaction requests. + let request_path = "../testing-utils/rpc_resources/blocks/2477658_alt/txs_hashes_0.json"; + let response_path = "../testing-utils/rpc_resources/blocks/2477658_alt/transactions_0.json"; + self.mock_transactions(request_path, response_path); + } + + pub fn mock_txpool(&self, path: &str) -> Mock { + // Use ID to delete old mock. + if let Some(id) = *self + .txpool_id + .lock() + .expect("PoisonError when reading txpool mock ID") + { + Mock::new(id, self).delete(); + }; + + // Create new mock. + let mock = self.mock(|when, then| { + when.path("/get_transaction_pool").body(""); + then.status(200) + .header("content-type", "application/json") + .body_from_file(path); + }); + *self + .txpool_id + .lock() + .expect("PoisonError when writing txpool mock ID") = Some(mock.id); + mock + } + + pub fn mock_transactions(&self, request_path: &str, response_path: &str) -> Mock { + let when_body: Value = serde_json::from_str( + &fs::read_to_string(request_path) + .expect("failed to read transaction request from file when preparing mock"), + ) + .expect("failed to parse transaction request as json"); + let when_txs: Vec<&str> = when_body["txs_hashes"] + .as_array() + .into_iter() + .flatten() + .map(|v| v.as_str().expect("failed to parse tx hash as string")) + .collect(); + self.mock(|when, then| { + let mut when = when.path("/get_transactions"); + for hash in when_txs { + // Ensure the request contains the hashes of all the expected transactions. + when = when.body_contains(hash); + } + then.status(200) + .header("content-type", "application/json") + .body_from_file(response_path); + }) + } + + pub fn mock_block(&self, height: u64, response_path: &str) { + // Use ID to delete old mock. + if let Some(id) = self + .block_ids + .lock() + .expect("PoisonError when reading txpool mock ID") + .get(&height) + { + Mock::new(*id, self).delete(); + }; + let mock = self.mock(|when, then| { + when.path("/json_rpc").body( + r#"{"jsonrpc":"2.0","id":"0","method":"get_block","params":{"height":"#.to_owned() + + &height.to_string() + + "}}", + ); + then.status(200) + .header("content-type", "application/json") + .body_from_file(response_path); + }); + self.block_ids + .lock() + .expect("PoisonError when writing daemon height mock ID") + .insert(height, mock.id); + } + + pub fn mock_txpool_hashes(&self, response_path: &str) -> Mock { + // Use ID to delete old mock. + if let Some(id) = *self + .txpool_hashes_id + .lock() + .expect("PoisonError when reading txpool hashes mock ID") + { + Mock::new(id, self).delete(); + }; + + // Create new mock. + let mock = self.mock(|when, then| { + when.path("/get_transaction_pool_hashes").body(""); + then.status(200) + .header("content-type", "application/json") + .body_from_file(response_path); + }); + *self + .txpool_hashes_id + .lock() + .expect("PoisonError when writing txpool hashes mock ID") = Some(mock.id); + mock + } + + pub fn mock_txpool_transactions(&self, request_path: &str, response_path: &str) -> Mock { + // Use ID to delete old mock. + if let Some(id) = *self + .txpool_transactions_id + .lock() + .expect("PoisonError when reading txpool transactions mock ID") + { + Mock::new(id, self).delete(); + }; + let mock = self.mock_transactions(request_path, response_path); + *self + .txpool_transactions_id + .lock() + .expect("PoisonError when writing txpool transactions mock ID") = Some(mock.id); + mock + } +} diff --git a/testing-utils/src/invoice.rs b/testing-utils/src/invoice.rs new file mode 100644 index 0000000..d228c71 --- /dev/null +++ b/testing-utils/src/invoice.rs @@ -0,0 +1,79 @@ +use std::cmp::max; + +use acceptxmr::{Invoice, SubIndex}; + +#[derive(Clone)] +pub struct MockInvoice { + pub address: Option, + pub index: SubIndex, + pub creation_height: u64, + pub amount_requested: u64, + pub amount_paid: u64, + pub paid_height: Option, + pub confirmations_required: u64, + pub current_height: u64, + pub expiration_height: u64, + pub description: String, + + // Calculated fields. + pub is_expired: bool, + pub expires_in: u64, + pub is_confirmed: bool, + pub confirmations: Option, +} + +impl MockInvoice { + #[must_use] + pub fn new( + address: Option, + index: SubIndex, + creation_height: u64, + amount_requested: u64, + confirmations_required: u64, + expires_in: u64, + description: String, + ) -> MockInvoice { + MockInvoice { + address, + index, + creation_height, + amount_requested, + amount_paid: 0, + paid_height: None, + confirmations_required, + current_height: creation_height, + expiration_height: creation_height + expires_in, + description, + + is_expired: false, + expires_in, + is_confirmed: false, + confirmations: None, + } + } + + pub fn assert_eq(&self, update: &Invoice) { + if let Some(address) = &self.address { + assert_eq!(update.address(), address); + } + assert_eq!(update.index(), self.index); + assert_eq!(update.creation_height(), self.creation_height); + assert_eq!(update.amount_requested(), self.amount_requested); + assert_eq!(update.amount_paid(), self.amount_paid); + assert_eq!(update.confirmations_required(), self.confirmations_required); + assert_eq!(update.current_height(), self.current_height); + assert_eq!(update.expiration_height(), self.expiration_height); + assert_eq!(update.expiration_height(), self.expiration_height); + assert_eq!( + update.expiration_height() - max(update.creation_height(), update.current_height()), + self.expires_in + ); + assert_eq!(update.description(), self.description); + + // Calculated fields. + assert_eq!(update.is_expired(), self.is_expired); + assert_eq!(update.expiration_in(), self.expires_in); + assert_eq!(update.is_confirmed(), self.is_confirmed); + assert_eq!(update.confirmations(), self.confirmations); + } +} diff --git a/testing-utils/src/lib.rs b/testing-utils/src/lib.rs new file mode 100644 index 0000000..364f2b2 --- /dev/null +++ b/testing-utils/src/lib.rs @@ -0,0 +1,43 @@ +#![allow(missing_docs)] +#![allow(clippy::missing_panics_doc)] + +mod daemon; +mod invoice; + +pub use daemon::MockDaemon; +pub use invoice::MockInvoice; +use tempfile::Builder; +use tracing_subscriber::{filter::LevelFilter, prelude::*, EnvFilter}; + +pub const PRIVATE_VIEW_KEY: &str = + "ad2093a5705b9f33e6f0f0c1bc1f5f639c756cdfc168c8f2ac6127ccbdab3a03"; +pub const PRIMARY_ADDRESS: &str = + "4613YiHLM6JMH4zejMB2zJY5TwQCxL8p65ufw8kBP5yxX9itmuGLqp1dS4tkVoTxjyH3aYhYNrtGHbQzJQP5bFus3KHVdmf"; + +#[must_use] +pub fn new_temp_dir() -> String { + Builder::new() + .prefix("temp_db_") + .rand_bytes(16) + .tempdir() + .expect("failed to generate temporary directory") + .path() + .to_str() + .expect("failed to get temporary directory path") + .to_string() +} + +/// Initialize the logging implementation. +pub fn init_logger() { + // let console_layer = console_subscriber::spawn(); + let filter = EnvFilter::builder() + .with_default_directive(LevelFilter::DEBUG.into()) + .from_env_lossy(); + let fmt_layer = tracing_subscriber::fmt::layer() + .with_test_writer() + .with_filter(filter); + let _ = tracing_subscriber::registry() + //.with(console_layer) + .with(fmt_layer) + .try_init(); +} diff --git a/typos.toml b/typos.toml new file mode 100644 index 0000000..15b2db5 --- /dev/null +++ b/typos.toml @@ -0,0 +1,8 @@ +[files] +extend-exclude = ["testing-utils/rpc_resources/**/*.json"] + +[default] +extend-ignore-identifiers-re = [ + "4A1WSBQdCbUCqt3DaGfmqVFchXScF43M6c5r4B6JXT3dUwuALncU9XTEnRPmUMcB3c16kVP9Y7thFLCJ5BaMW3UmSy93w3w", + "84pKaXBd9biTwA7wihzUvrXN2YHoJBdFC4ZxEHQqaPuMFDa8Nyg1mywMXgzvjWBiTCfim7ZRfuJhvHavJrZ4Y7z3THW2Hmf" +]