From d05a773980588851c6a0001b8c156e696a23d73a Mon Sep 17 00:00:00 2001 From: Stan Bondi Date: Thu, 25 Sep 2025 10:59:18 +0400 Subject: [PATCH] chore: upgrade axum and related deps --- Cargo.lock | 645 ++++++++++-------- Cargo.toml | 35 +- applications/tari_app_utilities/Cargo.toml | 6 +- applications/tari_app_utilities/src/lib.rs | 1 + applications/tari_app_utilities/src/tcp.rs | 23 + applications/tari_indexer/Cargo.toml | 3 +- .../tari_indexer/src/graphql/server.rs | 14 +- .../tari_indexer/src/http_ui/server.rs | 14 +- .../tari_indexer/src/json_rpc/error.rs | 4 +- .../tari_indexer/src/json_rpc/handlers.rs | 80 +-- .../tari_indexer/src/json_rpc/server.rs | 87 +-- applications/tari_indexer/src/lib.rs | 2 +- .../src/network_state_sync/sync_progress.rs | 2 +- applications/tari_signaling_server/Cargo.toml | 3 +- .../tari_signaling_server/src/data.rs | 5 +- .../tari_signaling_server/src/jrpc_server.rs | 43 +- applications/tari_swarm_daemon/Cargo.toml | 4 +- .../src/webserver/handler.rs | 2 +- .../tari_swarm_daemon/src/webserver/server.rs | 29 +- applications/tari_validator_node/Cargo.toml | 2 +- applications/tari_validator_node/src/cli.rs | 2 +- .../tari_validator_node/src/http_ui/server.rs | 16 +- .../src/json_rpc/handlers.rs | 106 +-- .../src/json_rpc/jrpc_errors.rs | 12 +- .../src/json_rpc/server.rs | 22 +- applications/tari_validator_node/src/lib.rs | 3 +- .../tari_wallet_cli/src/command/proof.rs | 3 +- .../src/command/transaction.rs | 11 +- .../tari_wallet_cli/src/from_base64.rs | 4 +- applications/tari_walletd/Cargo.toml | 4 +- .../tari_walletd/src/handlers/accounts.rs | 2 +- .../tari_walletd/src/handlers/auth/jwt.rs | 2 +- .../tari_walletd/src/handlers/confidential.rs | 2 +- .../tari_walletd/src/handlers/context.rs | 2 +- .../tari_walletd/src/handlers/keys.rs | 2 +- applications/tari_walletd/src/handlers/mod.rs | 3 +- .../tari_walletd/src/handlers/nfts.rs | 2 +- applications/tari_walletd/src/handlers/rpc.rs | 2 +- .../tari_walletd/src/handlers/settings.rs | 2 +- .../src/handlers/stealth_utxos.rs | 2 +- .../tari_walletd/src/handlers/substates.rs | 2 +- .../tari_walletd/src/handlers/templates.rs | 2 +- .../tari_walletd/src/handlers/transaction.rs | 2 +- .../tari_walletd/src/handlers/validator.rs | 2 +- .../tari_walletd/src/handlers/wallet.rs | 2 +- .../tari_walletd/src/handlers/webauthn.rs | 2 +- .../tari_walletd/src/handlers/webrtc.rs | 10 +- .../tari_walletd/src/http_ui/server.rs | 17 +- applications/tari_walletd/src/jrpc_server.rs | 19 +- applications/tari_walletd/src/lib.rs | 3 +- applications/tari_walletd/src/webrtc.rs | 3 +- .../libp2p-messaging/src/codec/prost.rs | 2 +- networking/rpc_framework/Cargo.toml | 3 +- utilities/db_inspector/Cargo.toml | 1 - .../src/webserver/handlers/tables.rs | 3 +- .../db_inspector/src/webserver/server.rs | 25 +- 56 files changed, 656 insertions(+), 650 deletions(-) create mode 100644 applications/tari_app_utilities/src/tcp.rs diff --git a/Cargo.lock b/Cargo.lock index c93df875f6..5d96f266b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -168,9 +168,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.98" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "anymap2" @@ -421,75 +421,76 @@ dependencies = [ [[package]] name = "async-graphql" -version = "5.0.10" +version = "7.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35ef8f9be23ee30fe1eb1cf175c689bc33517c6c6d0fd0669dade611e5ced7f" +checksum = "036618f842229ba0b89652ffe425f96c7c16a49f7e3cb23b56fca7f61fd74980" dependencies = [ "async-graphql-derive", "async-graphql-parser", "async-graphql-value", "async-stream", "async-trait", - "base64 0.13.1", + "base64 0.22.1", "bytes 1.10.1", "fast_chemail", "fnv", + "futures-timer", "futures-util", "handlebars", - "http 0.2.12", - "indexmap 1.9.3", + "http 1.3.1", + "indexmap 2.11.4", "mime", "multer", "num-traits", - "once_cell", "pin-project-lite", "regex", "serde", "serde_json", "serde_urlencoded", - "static_assertions", + "static_assertions_next", "tempfile", "thiserror 1.0.69", ] [[package]] name = "async-graphql-axum" -version = "5.0.10" +version = "7.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "777d02b4b35c1eb15bb63391f45b4622206fe1199940fa8b4b6136904fae035c" +checksum = "8725874ecfbf399e071150b8619c4071d7b2b7a2f117e173dddef53c6bdb6bb1" dependencies = [ "async-graphql", - "async-trait", - "axum 0.6.20", + "axum 0.8.4", "bytes 1.10.1", "futures-util", - "http-body 0.4.6", "serde_json", + "tokio", + "tokio-stream", "tokio-util 0.7.15", "tower-service", ] [[package]] name = "async-graphql-derive" -version = "5.0.10" +version = "7.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a0f6ceed3640b4825424da70a5107e79d48d9b2bc6318dfc666b2fc4777f8c4" +checksum = "fd45deb3dbe5da5cdb8d6a670a7736d735ba65b455328440f236dfb113727a3d" dependencies = [ "Inflector", "async-graphql-parser", - "darling 0.14.4", - "proc-macro-crate 1.1.3", + "darling 0.20.11", + "proc-macro-crate 3.3.0", "proc-macro2", "quote", - "syn 1.0.109", + "strum 0.26.3", + "syn 2.0.103", "thiserror 1.0.69", ] [[package]] name = "async-graphql-parser" -version = "5.0.10" +version = "7.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc308cd3bc611ee86c9cf19182d2b5ee583da40761970e41207f088be3db18f" +checksum = "60b7607e59424a35dadbc085b0d513aa54ec28160ee640cf79ec3b634eba66d3" dependencies = [ "async-graphql-value", "pest", @@ -499,12 +500,12 @@ dependencies = [ [[package]] name = "async-graphql-value" -version = "5.0.10" +version = "7.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d461325bfb04058070712296601dfe5e5bd6cdff84780a0a8c569ffb15c87eb3" +checksum = "34ecdaff7c9cffa3614a9f9999bf9ee4c3078fe3ce4d6a6e161736b56febf2de" dependencies = [ "bytes 1.10.1", - "indexmap 1.9.3", + "indexmap 2.11.4", "serde", "serde_json", ] @@ -717,43 +718,6 @@ dependencies = [ "cc", ] -[[package]] -name = "axum" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" -dependencies = [ - "async-trait", - "axum-core 0.3.4", - "base64 0.21.7", - "bitflags 1.3.2", - "bytes 1.10.1", - "futures-util", - "headers 0.3.9", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.32", - "itoa", - "matchit 0.7.3", - "memchr", - "mime", - "multer", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "serde_json", - "serde_path_to_error", - "serde_urlencoded", - "sha1 0.10.6", - "sync_wrapper 0.1.2", - "tokio", - "tokio-tungstenite", - "tower 0.4.13", - "tower-layer", - "tower-service", -] - [[package]] name = "axum" version = "0.7.9" @@ -788,6 +752,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5" dependencies = [ "axum-core 0.5.2", + "base64 0.22.1", "bytes 1.10.1", "form_urlencoded", "futures-util", @@ -800,6 +765,7 @@ dependencies = [ "matchit 0.8.4", "memchr", "mime", + "multer", "percent-encoding", "pin-project-lite", "rustversion", @@ -807,8 +773,10 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", + "sha1 0.10.6", "sync_wrapper 1.0.2", "tokio", + "tokio-tungstenite", "tower 0.5.2", "tower-layer", "tower-service", @@ -817,30 +785,32 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.3.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" dependencies = [ "async-trait", "bytes 1.10.1", "futures-util", - "http 0.2.12", - "http-body 0.4.6", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", "mime", + "pin-project-lite", "rustversion", + "sync_wrapper 1.0.2", "tower-layer", "tower-service", ] [[package]] name = "axum-core" -version = "0.4.5" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6" dependencies = [ - "async-trait", "bytes 1.10.1", - "futures-util", + "futures-core", "http 1.3.1", "http-body 1.0.1", "http-body-util", @@ -850,40 +820,45 @@ dependencies = [ "sync_wrapper 1.0.2", "tower-layer", "tower-service", + "tracing", ] [[package]] -name = "axum-core" -version = "0.5.2" +name = "axum-extra" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6" +checksum = "45bf463831f5131b7d3c756525b305d40f1185b688565648a92e1392ca35713d" dependencies = [ + "axum 0.8.4", + "axum-core 0.5.2", "bytes 1.10.1", - "futures-core", + "futures-util", + "headers", "http 1.3.1", "http-body 1.0.1", "http-body-util", "mime", "pin-project-lite", "rustversion", - "sync_wrapper 1.0.2", + "serde", + "tower 0.5.2", "tower-layer", "tower-service", - "tracing", ] [[package]] name = "axum-jrpc" -version = "0.3.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "163372a0c1cb179c5b3a9ac5edbb01501b4d4ad247b971712d0559e832819e3a" +checksum = "5cb21d7d20818a26499e6c1cd20418a4bf17c7bcf3ec54594498081151edcf03" dependencies = [ "anyhow", - "async-trait", - "axum 0.6.20", + "axum 0.8.4", + "cfg-if", + "mime", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.12", ] [[package]] @@ -928,12 +903,6 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" -[[package]] -name = "base64" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" - [[package]] name = "base64" version = "0.21.7" @@ -1017,26 +986,6 @@ dependencies = [ "virtue", ] -[[package]] -name = "bindgen" -version = "0.69.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" -dependencies = [ - "bitflags 2.9.2", - "cexpr", - "clang-sys", - "itertools 0.12.1", - "lazy_static", - "lazycell", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex", - "syn 2.0.103", -] - [[package]] name = "bindgen" version = "0.70.1" @@ -1059,9 +1008,9 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.71.1" +version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ "bitflags 2.9.2", "cexpr", @@ -1215,7 +1164,7 @@ checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" dependencies = [ "borsh-derive", "cfg_aliases 0.2.1", - "indexmap 2.9.0", + "indexmap 2.11.4", ] [[package]] @@ -1453,6 +1402,16 @@ dependencies = [ "toml 0.8.23", ] +[[package]] +name = "cargo_toml" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" +dependencies = [ + "serde", + "toml 0.9.6", +] + [[package]] name = "cassowary" version = "0.3.0" @@ -1699,19 +1658,19 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.40" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" +checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" dependencies = [ "clap_builder", - "clap_derive 4.5.40", + "clap_derive 4.5.47", ] [[package]] name = "clap_builder" -version = "4.5.40" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" +checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" dependencies = [ "anstream", "anstyle", @@ -1735,9 +1694,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.40" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -2344,7 +2303,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6cd12917efc3a8b069a4975ef3cb2f2d835d42d04b3814d90838488f9dd9bf69" dependencies = [ "anyhow", - "clap 4.5.40", + "clap 4.5.48", "console", "cucumber-codegen", "cucumber-expressions", @@ -2463,7 +2422,7 @@ version = "1.0.158" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f44296c8693e9ea226a48f6a122727f77aa9e9e338380cb021accaeeb7ee279" dependencies = [ - "clap 4.5.40", + "clap 4.5.48", "codespan-reporting", "proc-macro2", "quote", @@ -2508,6 +2467,16 @@ dependencies = [ "darling_macro 0.20.11", ] +[[package]] +name = "darling" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +dependencies = [ + "darling_core 0.21.3", + "darling_macro 0.21.3", +] + [[package]] name = "darling_core" version = "0.14.4" @@ -2536,6 +2505,20 @@ dependencies = [ "syn 2.0.103", ] +[[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.11.1", + "syn 2.0.103", +] + [[package]] name = "darling_macro" version = "0.14.4" @@ -2558,6 +2541,17 @@ dependencies = [ "syn 2.0.103", ] +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core 0.21.3", + "quote", + "syn 2.0.103", +] + [[package]] name = "dashmap" version = "5.5.3" @@ -2616,7 +2610,7 @@ name = "db_inspector" version = "0.11.2" dependencies = [ "anyhow", - "axum 0.6.20", + "axum 0.8.4", "clap 3.2.25", "fern", "hex", @@ -2624,15 +2618,14 @@ dependencies = [ "include_dir", "log", "mime_guess", - "reqwest 0.11.27", "serde", "serde_json", "tari_ootle_common_types", "tari_ootle_storage", "tari_state_store_rocksdb", "tokio", - "toml 0.8.23", - "tower-http 0.4.4", + "toml 0.9.6", + "tower-http", ] [[package]] @@ -3826,7 +3819,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" dependencies = [ "fallible-iterator", - "indexmap 2.9.0", + "indexmap 2.11.4", "stable_deref_trait", ] @@ -3914,7 +3907,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.9.0", + "indexmap 2.11.4", "slab", "tokio", "tokio-util 0.7.15", @@ -3933,7 +3926,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.3.1", - "indexmap 2.9.0", + "indexmap 2.11.4", "slab", "tokio", "tokio-util 0.7.15", @@ -3958,9 +3951,9 @@ dependencies = [ [[package]] name = "handlebars" -version = "4.5.0" +version = "5.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa67bab9ff362228eb3d00bd024a4965d8231bbb7921167f0cfa66c6626b225" +checksum = "d08485b96a0e6393e9e4d1b8d48cf74ad6c063cd905eb33f42c1ce3f0377539b" dependencies = [ "log", "pest", @@ -4037,21 +4030,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "headers" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" -dependencies = [ - "base64 0.21.7", - "bytes 1.10.1", - "headers-core 0.2.0", - "http 0.2.12", - "httpdate", - "mime", - "sha1 0.10.6", -] - [[package]] name = "headers" version = "0.4.1" @@ -4060,22 +4038,13 @@ checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" dependencies = [ "base64 0.22.1", "bytes 1.10.1", - "headers-core 0.3.0", + "headers-core", "http 1.3.1", "httpdate", "mime", "sha1 0.10.6", ] -[[package]] -name = "headers-core" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" -dependencies = [ - "http 0.2.12", -] - [[package]] name = "headers-core" version = "0.3.0" @@ -4345,9 +4314,9 @@ dependencies = [ [[package]] name = "http-range-header" -version = "0.3.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" +checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c" [[package]] name = "httparse" @@ -4377,7 +4346,7 @@ dependencies = [ "form_urlencoded", "futures-timer", "futures-util", - "headers 0.4.1", + "headers", "http 1.3.1", "http-body-util", "hyper 1.6.0", @@ -4913,13 +4882,14 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.9.0" +version = "2.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "equivalent", "hashbrown 0.15.4", "serde", + "serde_core", ] [[package]] @@ -4997,7 +4967,7 @@ dependencies = [ "config", "cucumber", "httpmock", - "indexmap 2.9.0", + "indexmap 2.11.4", "libp2p", "log", "log4rs", @@ -5406,12 +5376,6 @@ dependencies = [ "spin 0.9.8", ] -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "leb128" version = "0.2.5" @@ -5757,7 +5721,7 @@ dependencies = [ "futures-bounded", "libp2p", "prometheus-client", - "prost 0.13.5", + "prost 0.14.1", "smallvec 2.0.0-alpha.11", "tracing", ] @@ -6043,11 +6007,11 @@ dependencies = [ [[package]] name = "librocksdb-sys" -version = "0.17.1+9.9.3" +version = "0.17.3+10.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b7869a512ae9982f4d46ba482c2a304f1efd80c6412a3d4bf57bb79a619679f" +checksum = "cef2a00ee60fe526157c9023edab23943fae1ce2ab6f4abb2a807c1746835de9" dependencies = [ - "bindgen 0.69.5", + "bindgen 0.72.1", "bzip2-sys", "cc", "libc", @@ -6740,7 +6704,7 @@ dependencies = [ "thiserror 1.0.69", "tokio", "tonic 0.13.1", - "tower-http 0.6.6", + "tower-http", "url", "utoipa", "utoipa-swagger-ui", @@ -6919,16 +6883,15 @@ checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" [[package]] name = "multer" -version = "2.1.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" +checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" dependencies = [ "bytes 1.10.1", "encoding_rs", "futures-util", - "http 0.2.12", + "http 1.3.1", "httparse", - "log", "memchr", "mime", "spin 0.9.8", @@ -7472,7 +7435,7 @@ dependencies = [ "crc32fast", "flate2", "hashbrown 0.14.5", - "indexmap 2.9.0", + "indexmap 2.11.4", "memchr", "ruzstd", ] @@ -7894,7 +7857,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset 0.4.2", - "indexmap 2.9.0", + "indexmap 2.11.4", ] [[package]] @@ -7904,7 +7867,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" dependencies = [ "fixedbitset 0.5.7", - "indexmap 2.9.0", + "indexmap 2.11.4", ] [[package]] @@ -8311,6 +8274,16 @@ dependencies = [ "prost-derive 0.13.5", ] +[[package]] +name = "prost" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7231bd9b3d3d33c86b58adbac74b5ec0ad9f496b19d22801d773636feaa95f3d" +dependencies = [ + "bytes 1.10.1", + "prost-derive 0.14.1", +] + [[package]] name = "prost-build" version = "0.11.9" @@ -8353,6 +8326,26 @@ dependencies = [ "tempfile", ] +[[package]] +name = "prost-build" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac6c3320f9abac597dcbc668774ef006702672474aad53c6d596b62e487b40b1" +dependencies = [ + "heck 0.5.0", + "itertools 0.14.0", + "log", + "multimap 0.10.1", + "once_cell", + "petgraph 0.7.1", + "prettyplease 0.2.34", + "prost 0.14.1", + "prost-types 0.14.1", + "regex", + "syn 2.0.103", + "tempfile", +] + [[package]] name = "prost-derive" version = "0.11.9" @@ -8379,6 +8372,19 @@ dependencies = [ "syn 2.0.103", ] +[[package]] +name = "prost-derive" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9120690fafc389a67ba3803df527d0ec9cbbc9cc45e4cc20b332996dfb672425" +dependencies = [ + "anyhow", + "itertools 0.14.0", + "proc-macro2", + "quote", + "syn 2.0.103", +] + [[package]] name = "prost-types" version = "0.11.9" @@ -8397,11 +8403,20 @@ dependencies = [ "prost 0.13.5", ] +[[package]] +name = "prost-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9b4db3d6da204ed77bb26ba83b6122a73aeb2e87e25fbf7ad2e84c4ccbf8f72" +dependencies = [ + "prost 0.14.1", +] + [[package]] name = "proto_builder" version = "0.11.2" dependencies = [ - "prost-build 0.13.5", + "prost-build 0.14.1", "sha2", ] @@ -9011,7 +9026,7 @@ dependencies = [ "tokio", "tokio-native-tls", "tower 0.5.2", - "tower-http 0.6.6", + "tower-http", "tower-service", "url", "wasm-bindgen", @@ -9082,7 +9097,7 @@ dependencies = [ "bytecheck 0.8.1", "bytes 1.10.1", "hashbrown 0.15.4", - "indexmap 2.9.0", + "indexmap 2.11.4", "munge", "ptr_meta 0.3.0", "rancor", @@ -9105,9 +9120,9 @@ dependencies = [ [[package]] name = "rocksdb" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26ec73b20525cb235bad420f911473b69f9fe27cc856c5461bccd7e4af037f43" +checksum = "ddb7af00d2b17dbd07d82c0063e25411959748ff03e8d4f96134c2ff41fce34f" dependencies = [ "libc", "librocksdb-sys", @@ -9665,10 +9680,11 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.219" +version = "1.0.226" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd" dependencies = [ + "serde_core", "serde_derive", ] @@ -9703,11 +9719,20 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_core" +version = "1.0.226" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba2ba63999edb9dac981fb34b3e5c0d111a69b0924e253ed29d83f7c99e966a4" +dependencies = [ + "serde_derive", +] + [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.226" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "8db53ae22f34573731bafa1db20f04027b2d25e02d8205921b569171699cdb33" dependencies = [ "proc-macro2", "quote", @@ -9766,6 +9791,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5417783452c2be558477e104686f7de5dae53dba813c28435e0e70f82d9b04ee" +dependencies = [ + "serde_core", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -9784,7 +9818,7 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b615bed66931a7a9809b273937adc8a402d038b1e509d027fcaf62f084d33d1" dependencies = [ - "indexmap 2.9.0", + "indexmap 2.11.4", "itertools 0.13.0", "num-traits", "once_cell", @@ -9825,15 +9859,15 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.14.0" +version = "3.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" +checksum = "c522100790450cf78eeac1507263d0a350d4d5b30df0c8e1fe051a10c22b376e" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.9.0", + "indexmap 2.11.4", "schemars 0.9.0", "schemars 1.0.4", "serde", @@ -9845,11 +9879,11 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.14.0" +version = "3.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" +checksum = "327ada00f7d64abaac1e55a6911e90cf665aa051b9a561c7006c157f4633135e" dependencies = [ - "darling 0.20.11", + "darling 0.21.3", "proc-macro2", "quote", "syn 2.0.103", @@ -9861,7 +9895,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.9.0", + "indexmap 2.11.4", "itoa", "ryu", "serde", @@ -10246,7 +10280,7 @@ name = "state_store_tests" version = "0.11.2" dependencies = [ "env_logger 0.11.8", - "indexmap 2.9.0", + "indexmap 2.11.4", "log", "rand 0.8.5", "tari_bor", @@ -10270,6 +10304,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "static_assertions_next" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7beae5182595e9a8b683fa98c4317f956c9a2dec3b9716990d20023cc60c766" + [[package]] name = "std-semaphore" version = "0.1.0" @@ -10354,6 +10394,15 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros 0.26.4", +] + [[package]] name = "strum_macros" version = "0.22.0" @@ -10379,6 +10428,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.103", +] + [[package]] name = "stun" version = "0.5.1" @@ -10661,7 +10723,7 @@ version = "5.1.0-pre.0" source = "git+https://github.com/tari-project/tari.git?branch=feature%2Fwallet-stateless-burn-proof#8674633d4413a98d19e41a878ac650fe051f5107" dependencies = [ "anyhow", - "cargo_toml", + "cargo_toml 0.20.5", "config", "dirs-next 1.0.2", "git2", @@ -10831,7 +10893,7 @@ name = "tari_consensus" version = "0.11.2" dependencies = [ "anyhow", - "indexmap 2.9.0", + "indexmap 2.11.4", "log", "serde", "tari_common_types", @@ -10957,8 +11019,8 @@ name = "tari_engine" version = "0.11.2" dependencies = [ "blake2", - "cargo_toml", - "indexmap 2.9.0", + "cargo_toml 0.22.3", + "indexmap 2.11.4", "log", "rand 0.8.5", "semver", @@ -10992,7 +11054,7 @@ dependencies = [ "bounded-vec", "digest", "hex", - "indexmap 2.9.0", + "indexmap 2.11.4", "lazy_static", "log", "rand 0.8.5", @@ -11078,7 +11140,7 @@ dependencies = [ "anyhow", "async-graphql", "async-graphql-axum", - "axum 0.6.20", + "axum 0.8.4", "axum-jrpc", "bincode 2.0.1", "cacache", @@ -11089,6 +11151,7 @@ dependencies = [ "futures 0.3.31", "hex", "include_dir", + "indexmap 2.11.4", "libp2p", "log", "log4rs", @@ -11126,7 +11189,7 @@ dependencies = [ "thiserror 1.0.69", "time", "tokio", - "tower-http 0.4.4", + "tower-http", "url", ] @@ -11174,7 +11237,7 @@ source = "git+https://github.com/tari-project/tari.git?branch=feature%2Fwallet-s dependencies = [ "borsh", "digest", - "indexmap 2.9.0", + "indexmap 2.11.4", "serde", "tari_crypto", "tari_hashing", @@ -11318,7 +11381,7 @@ dependencies = [ "tari_transaction_components", "thiserror 1.0.69", "tokio", - "toml 0.8.23", + "toml 0.9.6", "url", ] @@ -11331,11 +11394,11 @@ dependencies = [ "bounded-vec", "digest", "ethnum", - "indexmap 2.9.0", + "indexmap 2.11.4", "libp2p-identity", "newtype-ops", - "prost 0.13.5", - "prost-types 0.13.5", + "prost 0.14.1", + "prost-types 0.14.1", "rand 0.8.5", "serde", "tari_bor", @@ -11355,7 +11418,7 @@ name = "tari_ootle_p2p" version = "0.11.2" dependencies = [ "anyhow", - "prost 0.13.5", + "prost 0.14.1", "proto_builder", "serde", "tari_bor", @@ -11379,7 +11442,7 @@ dependencies = [ "anyhow", "bitflags 2.9.2", "borsh", - "indexmap 2.9.0", + "indexmap 2.11.4", "log", "rand 0.8.5", "serde", @@ -11422,7 +11485,7 @@ name = "tari_ootle_wallet_cli" version = "0.11.2" dependencies = [ "anyhow", - "base64 0.20.0", + "base64 0.22.1", "clap 3.2.25", "log", "multiaddr 0.18.1", @@ -11549,7 +11612,9 @@ name = "tari_ootle_walletd" version = "0.11.2" dependencies = [ "anyhow", - "axum 0.6.20", + "async-trait", + "axum 0.8.4", + "axum-extra", "axum-jrpc", "clap 3.2.25", "config", @@ -11558,7 +11623,7 @@ dependencies = [ "futures-bounded", "humantime-serde", "include_dir", - "indexmap 2.9.0", + "indexmap 2.11.4", "jsonwebtoken", "libsqlite3-sys", "log", @@ -11592,7 +11657,7 @@ dependencies = [ "tempfile", "thiserror 1.0.69", "tokio", - "tower-http 0.4.4", + "tower-http", "url", "uuid 1.17.0", "wasm-opt", @@ -11642,15 +11707,14 @@ dependencies = [ "log", "once_cell", "pin-project 1.1.10", - "prost 0.13.5", - "prost-build 0.13.5", + "prost 0.14.1", "proto_builder", "tari_metrics", "tari_shutdown", "thiserror 1.0.69", "tokio", "tokio-util 0.7.15", - "tower 0.4.13", + "tower 0.5.2", "tracing", ] @@ -11760,10 +11824,11 @@ name = "tari_signaling_server" version = "0.11.2" dependencies = [ "anyhow", - "axum 0.6.20", + "axum 0.8.4", + "axum-extra", "axum-jrpc", "chrono", - "clap 4.5.40", + "clap 4.5.48", "dirs", "jsonwebtoken", "log", @@ -11776,7 +11841,7 @@ dependencies = [ "tari_utilities", "thiserror 1.0.69", "tokio", - "tower-http 0.4.4", + "tower-http", "webrtc", ] @@ -11788,7 +11853,7 @@ dependencies = [ "bincode 2.0.1", "borsh", "hex", - "indexmap 2.9.0", + "indexmap 2.11.4", "log", "rand 0.8.5", "rocksdb", @@ -11810,7 +11875,7 @@ dependencies = [ name = "tari_state_tree" version = "0.11.2" dependencies = [ - "indexmap 2.9.0", + "indexmap 2.11.4", "log", "serde", "tari_common_types", @@ -11849,14 +11914,15 @@ version = "0.11.2" dependencies = [ "anyhow", "async-trait", - "axum 0.6.20", + "axum 0.8.4", + "axum-extra", "axum-jrpc", "clap 3.2.25", "fern", "futures 0.3.31", "humantime 2.2.0", "include_dir", - "indexmap 2.9.0", + "indexmap 2.11.4", "json5", "lockfile", "log", @@ -11864,7 +11930,6 @@ dependencies = [ "minotari_node_grpc_client", "minotari_wallet_grpc_client", "nix 0.28.0", - "reqwest 0.11.27", "serde", "serde_json", "slug", @@ -11883,9 +11948,9 @@ dependencies = [ "tari_wallet_daemon_client", "thiserror 1.0.69", "tokio", - "toml 0.8.23", + "toml 0.9.6", "tonic 0.13.1", - "tower-http 0.4.4", + "tower-http", "url", ] @@ -12023,7 +12088,7 @@ version = "0.11.2" dependencies = [ "borsh", "hex", - "indexmap 2.9.0", + "indexmap 2.11.4", "log", "rand 0.8.5", "serde", @@ -12143,7 +12208,7 @@ name = "tari_validator_node" version = "0.11.2" dependencies = [ "anyhow", - "axum 0.6.20", + "axum 0.8.4", "axum-jrpc", "clap 3.2.25", "config", @@ -12151,7 +12216,7 @@ dependencies = [ "either", "futures 0.3.31", "include_dir", - "indexmap 2.9.0", + "indexmap 2.11.4", "json5", "libp2p", "libsqlite3-sys", @@ -12161,7 +12226,6 @@ dependencies = [ "minotari_app_utilities", "prometheus-client", "rand 0.8.5", - "reqwest 0.11.27", "serde", "serde_json", "sqlite_message_logger", @@ -12197,7 +12261,8 @@ dependencies = [ "tari_validator_node_rpc", "thiserror 1.0.69", "tokio", - "tower-http 0.4.4", + "tower-http", + "url", ] [[package]] @@ -12255,7 +12320,7 @@ name = "tari_validator_node_rpc" version = "0.11.2" dependencies = [ "anyhow", - "prost 0.13.5", + "prost 0.14.1", "proto_builder", "serde", "tari_bor", @@ -12326,7 +12391,7 @@ name = "tariswap_bench" version = "0.11.2" dependencies = [ "anyhow", - "clap 4.5.40", + "clap 4.5.48", "fern", "log", "tari_crypto", @@ -12620,9 +12685,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.20.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084" dependencies = [ "futures-util", "log", @@ -12675,11 +12740,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", - "serde_spanned", - "toml_datetime", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", "toml_edit", ] +[[package]] +name = "toml" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae2a4cf385da23d1d53bc15cdfa5c2109e93d8d362393c801e87da2f72f0e201" +dependencies = [ + "indexmap 2.11.4", + "serde_core", + "serde_spanned 1.0.2", + "toml_datetime 0.7.2", + "toml_parser", + "toml_writer", + "winnow", +] + [[package]] name = "toml_datetime" version = "0.6.11" @@ -12689,26 +12769,50 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1" +dependencies = [ + "serde_core", +] + [[package]] name = "toml_edit" version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.9.0", + "indexmap 2.11.4", "serde", - "serde_spanned", - "toml_datetime", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", "toml_write", "winnow", ] +[[package]] +name = "toml_parser" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10" +dependencies = [ + "winnow", +] + [[package]] name = "toml_write" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +[[package]] +name = "toml_writer" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109" + [[package]] name = "tonic" version = "0.12.3" @@ -12826,7 +12930,7 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", - "indexmap 2.9.0", + "indexmap 2.11.4", "pin-project-lite", "slab", "sync_wrapper 1.0.2", @@ -12839,46 +12943,30 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.4.4" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ "bitflags 2.9.2", "bytes 1.10.1", "futures-core", "futures-util", - "http 0.2.12", - "http-body 0.4.6", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", "http-range-header", "httpdate", + "iri-string", "mime", "mime_guess", "percent-encoding", "pin-project-lite", "tokio", "tokio-util 0.7.15", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-http" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" -dependencies = [ - "bitflags 2.9.2", - "bytes 1.10.1", - "futures-util", - "http 1.3.1", - "http-body 1.0.1", - "http-body-util", - "iri-string", - "pin-project-lite", "tower 0.5.2", "tower-layer", "tower-service", + "tracing", ] [[package]] @@ -12962,7 +13050,7 @@ dependencies = [ "anyhow", "bincode 2.0.1", "bytes 1.10.1", - "clap 4.5.40", + "clap 4.5.48", "once_cell", "rand 0.8.5", "rayon", @@ -12980,7 +13068,7 @@ name = "transaction_submitter" version = "0.11.2" dependencies = [ "anyhow", - "clap 4.5.40", + "clap 4.5.48", "tari_ootle_common_types", "tari_transaction", "tari_validator_node_client", @@ -13007,7 +13095,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ef1b7a6d914a34127ed8e1fa927eb7088903787bcded4fa3eef8f85ee1568be" dependencies = [ "chrono", - "indexmap 2.9.0", + "indexmap 2.11.4", "thiserror 2.0.12", "ts-rs-macros", ] @@ -13039,20 +13127,18 @@ dependencies = [ [[package]] name = "tungstenite" -version = "0.20.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" dependencies = [ - "byteorder", "bytes 1.10.1", "data-encoding", - "http 0.2.12", + "http 1.3.1", "httparse", "log", - "rand 0.8.5", + "rand 0.9.1", "sha1 0.10.6", - "thiserror 1.0.69", - "url", + "thiserror 2.0.12", "utf-8", ] @@ -13309,7 +13395,7 @@ version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fcc29c80c21c31608227e0912b2d7fddba57ad76b606890627ba8ee7964e993" dependencies = [ - "indexmap 2.9.0", + "indexmap 2.11.4", "serde", "serde_json", "utoipa-gen", @@ -13586,7 +13672,7 @@ dependencies = [ "cmake", "derive_more 1.0.0", "idna_adapter", - "indexmap 2.9.0", + "indexmap 2.11.4", "js-sys", "more-asserts", "paste", @@ -13695,7 +13781,7 @@ dependencies = [ "enumset", "getrandom 0.2.16", "hex", - "indexmap 2.9.0", + "indexmap 2.11.4", "more-asserts", "rkyv", "sha2", @@ -13718,7 +13804,7 @@ dependencies = [ "dashmap 6.1.0", "enum-iterator", "fnv", - "indexmap 2.9.0", + "indexmap 2.11.4", "libc", "libunwind", "mach2", @@ -13747,7 +13833,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "161296c618fa2d63f6ed5fffd1112937e803cb9ec71b32b01a76321555660917" dependencies = [ "bitflags 2.9.2", - "indexmap 2.9.0", + "indexmap 2.11.4", "semver", ] @@ -14921,7 +15007,7 @@ dependencies = [ "arbitrary", "crc32fast", "flate2", - "indexmap 2.9.0", + "indexmap 2.11.4", "memchr", "zopfli", ] @@ -14950,7 +15036,6 @@ version = "2.0.15+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" dependencies = [ - "bindgen 0.71.1", "cc", "pkg-config", ] diff --git a/Cargo.toml b/Cargo.toml index 07e9959f68..b7b086d0be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -152,15 +152,16 @@ libp2p-messaging = { path = "networking/libp2p-messaging" } libp2p-substream = { path = "networking/libp2p-substream" } # third-party dependencies -anyhow = "1.0.75" -async-graphql = "5.0.7" -async-graphql-axum = "5.0.7" -async-semaphore = "1.2.0" +anyhow = "1.0.100" +async-graphql = "7.0.17" +async-graphql-axum = "7.0.17" +async-semaphore = "1.2.1" async-trait = "0.1.74" asynchronous-codec = "0.7.0" -axum = "0.6" -axum-jrpc = "0.3.2" -base64 = "0.20.0" +axum = "0.8" +axum-extra = "0.10.1" +axum-jrpc = "0.8" +base64 = "0.22.1" bigdecimal = "0.4.1" bincode = "2.0.1" bitflags = "2.9.2" @@ -170,7 +171,7 @@ bytes = "1.10.0" bnum = "0.13.0" bech32 = "0.11.0" bounded-vec = "0.9.0" -cargo_toml = "0.20.5" +cargo_toml = "0.22.3" ciborium = { version = "0.2.2", default-features = false } ciborium-io = { version = "0.2.2", default-features = false } clap = "3.2.25" @@ -196,7 +197,7 @@ hex = "0.4" humantime = "2.1.0" humantime-serde = "1.1.1" include_dir = "0.7.2" -indexmap = "2.6.0" +indexmap = "2.11.4" indoc = "1.0.6" lazy_static = "1.4.0" # Use Tari's libp2p fork that adds support for Schnorr-Ristretto @@ -216,20 +217,20 @@ once_cell = "1.18.0" pin-project = "1.1" proc-macro2 = "1.0" prometheus-client = { version = "0.23", default-features = false } -prost = "0.13" -prost-build = "0.13" -prost-types = "0.13" +prost = "0.14" +prost-build = "0.14" +prost-types = "0.14" quick-protobuf = "0.8" quick-protobuf-codec = "0.3.1" quote = "1.0.7" rand = "0.8.5" rayon = "1.7.0" reqwest = "0.11.16" -rocksdb = "0.23.0" +rocksdb = "0.24.0" semver = "1.0" serde = { version = "1.0", default-features = false } serde_json = "1.0" -serde_with = "3.14.0" +serde_with = "3.14.1" sha2 = "0.10.8" smallvec = "2.0.0-alpha.11" std-semaphore = "0.1.0" @@ -241,10 +242,10 @@ tokio = { version = "1.44.1", default-features = false } tokio-stream = "0.1.7" tokio-util = "0.7.10" tonic = "0.13.1" -tower = "0.4" -tower-http = { version = "0.4", default-features = false } +tower = "0.5" +tower-http = { version = "0.6", default-features = false } tracing = "0.1.40" -toml = "0.8" +toml = "0.9" ts-rs = { version = "11.0", features = ["chrono-impl", "no-serde-warnings", "indexmap-impl"] } url = "2.4.1" urlencoding = "2.1.3" diff --git a/applications/tari_app_utilities/Cargo.toml b/applications/tari_app_utilities/Cargo.toml index 6ec3700364..aeba9856ed 100644 --- a/applications/tari_app_utilities/Cargo.toml +++ b/applications/tari_app_utilities/Cargo.toml @@ -9,7 +9,7 @@ license.workspace = true [dependencies] tari_common = { workspace = true } tari_common_types = { workspace = true } -tari_crypto = { workspace = true } +tari_crypto = { workspace = true, features = ["serde"] } tari_ootle_common_types = { workspace = true } tari_engine = { workspace = true } tari_ootle_storage = { workspace = true } @@ -34,10 +34,10 @@ libp2p-identity = { workspace = true } log = { workspace = true, features = ["std"] } multiaddr = { workspace = true } rand = { workspace = true } -serde = { workspace = true, features = ["default", "derive"] } +serde = { workspace = true, features = ["default", "derive", "rc"] } serde_json = { workspace = true } thiserror = { workspace = true } -tokio = { workspace = true, features = ["default", "macros", "time", "sync", "rt-multi-thread", "fs"] } +tokio = { workspace = true, features = ["default", "macros", "time", "sync", "rt-multi-thread", "fs", "net"] } url = { workspace = true, features = ["serde"] } toml = { workspace = true } config = { workspace = true } diff --git a/applications/tari_app_utilities/src/lib.rs b/applications/tari_app_utilities/src/lib.rs index 3df3afbe5e..87294949e8 100644 --- a/applications/tari_app_utilities/src/lib.rs +++ b/applications/tari_app_utilities/src/lib.rs @@ -28,5 +28,6 @@ pub mod fee_tables; pub mod keypair; pub mod p2p_config; pub mod seed_peer; +pub mod tcp; pub mod template_download_queue; pub mod transaction_executor; diff --git a/applications/tari_app_utilities/src/tcp.rs b/applications/tari_app_utilities/src/tcp.rs new file mode 100644 index 0000000000..93dea046aa --- /dev/null +++ b/applications/tari_app_utilities/src/tcp.rs @@ -0,0 +1,23 @@ +// Copyright 2025 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use std::{io, net::SocketAddr}; + +use log::warn; +use tokio::net::TcpListener; + +const LOG_TARGET: &str = "tari::ootle::app_utilities::tcp"; + +pub async fn try_bind_with_fallback(mut preferred_address: SocketAddr) -> io::Result { + match TcpListener::bind(preferred_address).await { + Ok(l) => Ok(l), + Err(e) => { + warn!( + target: LOG_TARGET, + "πŸ•ΈοΈ Failed to bind on preferred address ({e}). Trying OS-assigned", + ); + preferred_address.set_port(0); + TcpListener::bind(preferred_address).await + }, + } +} diff --git a/applications/tari_indexer/Cargo.toml b/applications/tari_indexer/Cargo.toml index c1e884bbfa..dcdee687bf 100644 --- a/applications/tari_indexer/Cargo.toml +++ b/applications/tari_indexer/Cargo.toml @@ -49,6 +49,7 @@ diesel = { workspace = true, default-features = false, features = [ "returning_clauses_for_sqlite_3_35", "time", ] } +indexmap = { workspace = true } diesel_migrations = { workspace = true } futures = { workspace = true } include_dir = { workspace = true, optional = true } @@ -64,7 +65,7 @@ log4rs = { workspace = true, features = [ mime_guess = { workspace = true } serde = { workspace = true, features = ["default", "derive"] } serde_json = { workspace = true } -serde_with = { workspace = true, features = ["indexmap"] } +serde_with = { workspace = true, features = ["indexmap_2"] } thiserror = { workspace = true } time = { workspace = true, features = ["serde"] } tokio = { workspace = true, features = [ diff --git a/applications/tari_indexer/src/graphql/server.rs b/applications/tari_indexer/src/graphql/server.rs index 8f8fffba19..3cf6bc27ea 100644 --- a/applications/tari_indexer/src/graphql/server.rs +++ b/applications/tari_indexer/src/graphql/server.rs @@ -39,6 +39,7 @@ use axum::{ }; use log::*; use serde::Serialize; +use tari_ootle_app_utilities::tcp::try_bind_with_fallback; use tower_http::cors::CorsLayer; use crate::{ @@ -64,16 +65,9 @@ pub async fn run_graphql( .layer(CorsLayer::permissive()) .layer(Extension(schema)); - let server = axum::Server::try_bind(&preferred_address) - .or_else(|_| { - warn!( - target: LOG_TARGET, - "🌐 Failed to bind on preferred address {}. Trying OS-assigned", preferred_address - ); - axum::Server::try_bind(&"127.0.0.1:0".parse().unwrap()) - })? - .serve(router.into_make_service()); - let bind_addr = server.local_addr(); + let listener = try_bind_with_fallback(preferred_address).await?; + let server = axum::serve(listener, router); + let bind_addr = server.local_addr()?; info!(target: LOG_TARGET, "🌐 GraphQL listening on {bind_addr}"); server.await?; diff --git a/applications/tari_indexer/src/http_ui/server.rs b/applications/tari_indexer/src/http_ui/server.rs index e9baa50875..407e3bc201 100644 --- a/applications/tari_indexer/src/http_ui/server.rs +++ b/applications/tari_indexer/src/http_ui/server.rs @@ -30,6 +30,7 @@ use axum::{ }; use include_dir::{include_dir, Dir}; use log::*; +use tari_ootle_app_utilities::tcp::try_bind_with_fallback; use url::Url; const LOG_TARGET: &str = "tari::indexer::web_ui::server"; @@ -50,16 +51,9 @@ pub async fn run_http_ui_server( .fallback(handler); info!(target: LOG_TARGET, "πŸ•ΈοΈ Web UI started at http://{}", address); - let server = axum::Server::try_bind(&address).or_else(|_| { - warn!( - target: LOG_TARGET, - "πŸ•ΈοΈ Failed to bind on preferred address {}. Trying OS-assigned", address - ); - axum::Server::try_bind(&"127.0.0.1:0".parse().unwrap()) - })?; - - let server = server.serve(router.into_make_service()); - info!(target: LOG_TARGET, "πŸ•ΈοΈ Web UI listening on {}", server.local_addr()); + let listener = try_bind_with_fallback(address).await?; + let server = axum::serve(listener, router); + info!(target: LOG_TARGET, "πŸ•ΈοΈ Web UI listening on {}", server.local_addr()?); server.await?; info!(target: LOG_TARGET, "Stopping Web UI"); diff --git a/applications/tari_indexer/src/json_rpc/error.rs b/applications/tari_indexer/src/json_rpc/error.rs index fac4eb7207..f23e308202 100644 --- a/applications/tari_indexer/src/json_rpc/error.rs +++ b/applications/tari_indexer/src/json_rpc/error.rs @@ -10,7 +10,7 @@ use axum_jrpc::{ const LOG_TARGET: &str = "tari::indexer::json_rpc"; -pub fn internal_error(answer_id: i64) -> impl Fn(T) -> JsonRpcResponse { +pub fn internal_error(answer_id: axum_jrpc::Id) -> impl Fn(T) -> JsonRpcResponse { move |err| { let msg = if cfg!(debug_assertions) || option_env!("CI").is_some() { err.to_string() @@ -19,7 +19,7 @@ pub fn internal_error(answer_id: i64) -> impl Fn(T) -> JsonRpcRespon "Something went wrong".to_string() }; JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new(JsonRpcErrorReason::InternalError, msg, serde_json::Value::Null), ) } diff --git a/applications/tari_indexer/src/json_rpc/handlers.rs b/applications/tari_indexer/src/json_rpc/handlers.rs index 9a35defd47..849a781f03 100644 --- a/applications/tari_indexer/src/json_rpc/handlers.rs +++ b/applications/tari_indexer/src/json_rpc/handlers.rs @@ -149,7 +149,7 @@ impl JsonRpcHandlers { impl JsonRpcHandlers { pub fn rpc_discover(&self, value: JsonRpcExtractor) -> JrpcResult { Ok(JsonRpcResponse::success( - value.id, + value.id.clone(), serde_json::from_str::>(include_str!("../../openrpc.json")).map_err(|e| { JsonRpcResponse::error( value.id, @@ -165,7 +165,7 @@ impl JsonRpcHandlers { .networking .get_local_peer_info() .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; let response = GetIdentityResponse { peer_id: info.peer_id.to_string(), public_key: self.keypair.public_key().to_byte_type(), @@ -185,7 +185,7 @@ impl JsonRpcHandlers { if let Some(unsupported) = addresses.iter().find(|a| !is_supported_multiaddr(a)) { return Err(JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::InvalidParams, format!("Unsupported multiaddr {unsupported}"), @@ -197,7 +197,7 @@ impl JsonRpcHandlers { let mut networking = self.networking.clone(); let public_key = RistrettoPublicKey::convert_from_byte_type(&public_key).map_err(|_| { JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::InvalidParams, "Public key is malformed".to_string(), @@ -215,10 +215,10 @@ impl JsonRpcHandlers { .build(), ) .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; if wait_for_dial { - dial_wait.await.map_err(internal_error(answer_id))?; + dial_wait.await.map_err(internal_error(answer_id.clone()))?; } Ok(JsonRpcResponse::success(answer_id, AddPeerResponse {})) @@ -231,7 +231,7 @@ impl JsonRpcHandlers { .clone() .get_connected_peers() .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; let status = if peers.is_empty() { "Offline" } else { "Online" }; Ok(JsonRpcResponse::success(answer_id, GetCommsStatsResponse { @@ -245,7 +245,7 @@ impl JsonRpcHandlers { .networking .get_active_connections() .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; let connections = active_connections .into_iter() @@ -283,7 +283,7 @@ impl JsonRpcHandlers { .get_stored_substates_by_filters(filter_by_type, filter_by_template, limit, offset) .map_err(|e| { warn!(target: LOG_TARGET, "Error getting substate: {}", e); - Self::internal_error(answer_id, format!("Error getting substate: {}", e)) + Self::internal_error(answer_id.clone(), format!("Error getting substate: {}", e)) })?; Ok(JsonRpcResponse::success(answer_id, ListSubstatesResponse { substates })) @@ -299,7 +299,7 @@ impl JsonRpcHandlers { .await .map_err(|e| { warn!(target: LOG_TARGET, "Error getting substate: {}", e); - Self::internal_error(answer_id, format!("Error getting substate: {}", e)) + Self::internal_error(answer_id.clone(), format!("Error getting substate: {}", e)) })?; match maybe_substate { @@ -331,7 +331,7 @@ impl JsonRpcHandlers { .map_err(|e| { warn!(target: LOG_TARGET, "Error asking network for substate: {}", e); JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::ApplicationError(501), format!("Error asking network for substate:{}", e), @@ -396,7 +396,7 @@ impl JsonRpcHandlers { let substates = self.substate_manager.get_substates(requests.as_slice()).map_err(|e| { warn!(target: LOG_TARGET, "Error getting substate: {}", e); - Self::internal_error(answer_id, format!("Error getting substate: {}", e)) + Self::internal_error(answer_id.clone(), format!("Error getting substate: {}", e)) })?; Ok(JsonRpcResponse::success(answer_id, GetSubstatesResponse { substates })) @@ -412,11 +412,11 @@ impl JsonRpcHandlers { .await .map_err(|e| { warn!(target: LOG_TARGET, "Error getting substate: {}", e); - Self::internal_error(answer_id, format!("Error getting substate: {}", e)) + Self::internal_error(answer_id.clone(), format!("Error getting substate: {}", e)) })? .ok_or_else(|| { JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::ApplicationError(404), format!( @@ -441,7 +441,7 @@ impl JsonRpcHandlers { let request: GetNonFungiblesRequest = value.parse_params()?; let limit = usize::try_from(request.end_index.saturating_sub(request.start_index)).map_err(|e| { JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::InvalidParams, format!("Invalid end_index: {}", e), @@ -451,7 +451,7 @@ impl JsonRpcHandlers { })?; let offset = usize::try_from(request.start_index).map_err(|e| { JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::InvalidParams, format!("Invalid start_index: {}", e), @@ -463,7 +463,7 @@ impl JsonRpcHandlers { let non_fungibles = self .substate_manager .get_non_fungibles_by_resource_address(request.address, limit, offset) - .map_err(|e| Self::internal_error(answer_id, format!("Error getting non fungibles: {}", e)))?; + .map_err(|e| Self::internal_error(answer_id.clone(), format!("Error getting non fungibles: {}", e)))?; Ok(JsonRpcResponse::success(answer_id, GetNonFungiblesResponse { non_fungibles, })) @@ -503,7 +503,7 @@ impl JsonRpcHandlers { .any(|shard| shard.is_global() || *shard > NumPreshards::MAX_SHARD) { return Err(JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::InvalidParams, format!( @@ -524,7 +524,7 @@ impl JsonRpcHandlers { .get_utxo_updates(req.resource_address, shard, state_version, req.per_shard_limit) .map_err(|e| { Self::internal_error( - answer_id, + answer_id.clone(), format!( "Error getting UTXO updates for resource_address {}, shard {}, state_version {}: {}", req.resource_address, shard, state_version, e @@ -539,7 +539,7 @@ impl JsonRpcHandlers { .get_max_state_version(&req.resource_address, shard) .map_err(|e| { Self::internal_error( - answer_id, + answer_id.clone(), format!( "Error getting max state version for resource_address {}, shard {}: {}", req.resource_address, shard, e @@ -584,7 +584,7 @@ impl JsonRpcHandlers { .get_unspent_utxos(&req.resource_address, &req.tag_and_nonce_pairs) .map_err(|e| { Self::internal_error( - answer_id, + answer_id.clone(), format!( "Error getting UTXOs for resource_address {}, with {} tag/nonce pair(s): {}", req.resource_address, @@ -607,7 +607,7 @@ impl JsonRpcHandlers { .dry_run_transaction_processor .process_transaction(request.transaction) .await - .map_err(|e| Self::internal_error(answer_id, e))?; + .map_err(|e| Self::internal_error(answer_id.clone(), e))?; return Ok(JsonRpcResponse::success(answer_id, SubmitTransactionResponse { result: IndexerTransactionFinalizedResult::Finalized { @@ -629,7 +629,7 @@ impl JsonRpcHandlers { .map_err(|e| match e { TransactionManagerError::NetworkClientError(NetworkClientError::AllValidatorsFailed { .. }) => { JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::ApplicationError(400), format!("All validators failed: {}", e), @@ -641,14 +641,14 @@ impl JsonRpcHandlers { transaction_id, details, } => JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::ApplicationError(400), format!("Transaction {} is invalid: {}", transaction_id, details), json::Value::Null, ), ), - e => Self::internal_error(answer_id, e), + e => Self::internal_error(answer_id.clone(), e), })?; info!(target: LOG_TARGET, "βœ… Transaction submitted: {}", transaction_id); @@ -666,7 +666,7 @@ impl JsonRpcHandlers { .epoch_manager .get_current_epoch_hash() .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; let current_block_height = self .global_db @@ -678,7 +678,7 @@ impl JsonRpcHandlers { }) .map_err(|e| { JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::InternalError, format!("Could not get current block height: {}", e), @@ -709,26 +709,26 @@ impl JsonRpcHandlers { status: Some(TemplateStatus::Pending) }) { Self::not_found( - answer_id, + answer_id.clone(), format!( "Template with address {} is still being downloaded. Try again later.", request.template_address ), ) } else { - Self::internal_error(answer_id, format!("Error fetching template: {}", err)) + Self::internal_error(answer_id.clone(), format!("Error fetching template: {}", err)) } })? .ok_or_else(|| { Self::not_found( - answer_id, + answer_id.clone(), format!("Template with address {} not found", request.template_address), ) })?; let template = match template.executable { TemplateExecutable::CompiledWasm(code) => WasmModule::from_code(code) .load_template() - .map_err(|e| Self::internal_error(answer_id, format!("Error loading template: {}", e)))?, + .map_err(|e| Self::internal_error(answer_id.clone(), format!("Error loading template: {}", e)))?, // TemplateExecutable::DownloadableWasm is never returned ad there is no DB type for that TemplateExecutable::DownloadableWasm(_, _) | TemplateExecutable::Manifest(_) => { return Err(JsonRpcResponse::error( @@ -754,7 +754,7 @@ impl JsonRpcHandlers { let templates = self .template_manager .fetch_template_metadata(req.limit as usize) - .map_err(|e| Self::internal_error(answer_id, e))?; + .map_err(|e| Self::internal_error(answer_id.clone(), e))?; Ok(JsonRpcResponse::success(answer_id, ListTemplatesResponse { templates: templates @@ -777,8 +777,8 @@ impl JsonRpcHandlers { .get_transaction_result(request.transaction_id) .await .optional() - .map_err(|e| Self::internal_error(answer_id, e))? - .ok_or_else(|| Self::not_found(answer_id, "Transaction not found"))?; + .map_err(|e| Self::internal_error(answer_id.clone(), e))? + .ok_or_else(|| Self::not_found(answer_id.clone(), "Transaction not found"))?; let resp = match result { TransactionResultStatus::Pending => GetTransactionResultResponse { @@ -817,7 +817,7 @@ impl JsonRpcHandlers { let transactions = self .transaction_manager .list_recent_transactions(None, limit as usize) - .map_err(|e| Self::internal_error(answer_id, e))?; + .map_err(|e| Self::internal_error(answer_id.clone(), e))?; let resp = ListRecentTransactionsResponse { transactions }; Ok(JsonRpcResponse::success(answer_id, resp)) @@ -829,27 +829,27 @@ impl JsonRpcHandlers { self.epoch_manager .wait_for_initial_scanning_to_complete() .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; Ok(JsonRpcResponse::success(answer_id, IndexerReadyResponse {})) } - fn error_response(answer_id: i64, reason: JsonRpcErrorReason, message: T) -> JsonRpcResponse { + fn error_response(answer_id: axum_jrpc::Id, reason: JsonRpcErrorReason, message: T) -> JsonRpcResponse { JsonRpcResponse::error( answer_id, JsonRpcError::new(reason, message.to_string(), json::Value::Null), ) } - fn not_found(answer_id: i64, details: T) -> JsonRpcResponse { + fn not_found(answer_id: axum_jrpc::Id, details: T) -> JsonRpcResponse { Self::error_response(answer_id, JsonRpcErrorReason::ApplicationError(404), details) } - fn invalid_params(answer_id: i64, details: T) -> JsonRpcResponse { + fn invalid_params(answer_id: axum_jrpc::Id, details: T) -> JsonRpcResponse { Self::error_response(answer_id, JsonRpcErrorReason::InvalidParams, details) } - fn internal_error(answer_id: i64, error: T) -> JsonRpcResponse { + fn internal_error(answer_id: axum_jrpc::Id, error: T) -> JsonRpcResponse { error!(target: LOG_TARGET, "Internal error: {}", error); Self::error_response(answer_id, JsonRpcErrorReason::InternalError, error) } diff --git a/applications/tari_indexer/src/json_rpc/server.rs b/applications/tari_indexer/src/json_rpc/server.rs index 514af881c5..c445e6717f 100644 --- a/applications/tari_indexer/src/json_rpc/server.rs +++ b/applications/tari_indexer/src/json_rpc/server.rs @@ -20,43 +20,36 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use std::{net::SocketAddr, sync::Arc}; +use std::{future::IntoFuture, net::SocketAddr, sync::Arc}; use axum::{ extract::{DefaultBodyLimit, Extension}, - middleware, routing::post, Router, }; use axum_jrpc::{JrpcResult, JsonRpcExtractor}; use log::*; +use tari_ootle_app_utilities::tcp::try_bind_with_fallback; use tower_http::cors::CorsLayer; use super::handlers::JsonRpcHandlers; const LOG_TARGET: &str = "tari::indexer::json_rpc"; -pub fn spawn_json_rpc(preferred_address: SocketAddr, handlers: JsonRpcHandlers) -> anyhow::Result { +pub async fn spawn_json_rpc(preferred_address: SocketAddr, handlers: JsonRpcHandlers) -> anyhow::Result { let router = Router::new() .route("/", post(handler)) .route("/json_rpc", post(handler)) - .layer(middleware::from_fn(logger::middleware_fn)) .layer(Extension(Arc::new(handlers))) // Limit the body size to 5MB to allow for large transactions (wasm uploads) .layer(DefaultBodyLimit::max(5*1024*1024)) .layer(CorsLayer::permissive()); - let server = axum::Server::try_bind(&preferred_address).or_else(|_| { - warn!( - target: LOG_TARGET, - "🌐 Failed to bind on preferred address {}. Trying OS-assigned", preferred_address - ); - axum::Server::try_bind(&"127.0.0.1:0".parse().unwrap()) - })?; - let server = server.serve(router.into_make_service()); - let listen_addr = server.local_addr(); + let listener = try_bind_with_fallback(preferred_address).await?; + let server = axum::serve(listener, router); + let listen_addr = server.local_addr()?; info!(target: LOG_TARGET, "🌐 JSON-RPC listening on {listen_addr}"); - tokio::spawn(server); + tokio::spawn(server.into_future()); Ok(listen_addr) } @@ -96,69 +89,3 @@ async fn handler(Extension(handlers): Extension>, value: Js method => Ok(value.method_not_found(method)), } } - -// TODO: this is a janky and fairly costly logger found on SO, replace with tracing middleware -mod logger { - use async_graphql::futures_util; - use axum::{ - body::{Body, Bytes, HttpBody}, - http::{Request, Response, StatusCode}, - middleware::Next, - response::IntoResponse, - }; - use libp2p::bytes::{Buf, BufMut}; - - use super::*; - - // use Body as type here - pub async fn middleware_fn( - req: Request, - next: Next, - ) -> Result { - let (parts, body) = req.into_parts(); - let req = Request::from_parts(parts, body); - - let res = next.run(req).await; - - let (parts, body) = res.into_parts(); - let body_bytes = to_bytes(body).await.unwrap(); - debug!(target: LOG_TARGET, "🌐 Response: {}", String::from_utf8_lossy(&body_bytes)); - - Ok(Response::from_parts(parts, Body::from(body_bytes))) - } - - async fn to_bytes(body: T) -> Result - where T: HttpBody { - futures_util::pin_mut!(body); - - // If there's only 1 chunk, we can just return Buf::to_bytes() - let mut first = if let Some(buf) = body.data().await { - buf? - } else { - return Ok(Bytes::new()); - }; - - let second = if let Some(buf) = body.data().await { - buf? - } else { - return Ok(first.copy_to_bytes(first.remaining())); - }; - - // Don't pre-emptively reserve *too* much. - let rest = (body.size_hint().lower() as usize).min(1024 * 16); - let cap = first - .remaining() - .saturating_add(second.remaining()) - .saturating_add(rest); - // With more than 1 buf, we gotta flatten into a Vec first. - let mut vec = Vec::with_capacity(cap); - vec.put(first); - vec.put(second); - - while let Some(buf) = body.data().await { - vec.put(buf?); - } - - Ok(vec.into()) - } -} diff --git a/applications/tari_indexer/src/lib.rs b/applications/tari_indexer/src/lib.rs index cee49a4dd6..22360aee21 100644 --- a/applications/tari_indexer/src/lib.rs +++ b/applications/tari_indexer/src/lib.rs @@ -155,7 +155,7 @@ pub async fn run_indexer(config: ApplicationConfig, mut shutdown_signal: Shutdow services.template_manager.clone(), dry_run_transaction_processor, ); - let jrpc_address = spawn_json_rpc(jrpc_address, handlers)?; + let jrpc_address = spawn_json_rpc(jrpc_address, handlers).await?; debug!(target: LOG_TARGET, "JSON-RPC address {}", jrpc_address); // Run the web ui #[cfg(feature = "web_ui")] diff --git a/applications/tari_indexer/src/network_state_sync/sync_progress.rs b/applications/tari_indexer/src/network_state_sync/sync_progress.rs index 4b04b462a0..a14b5c7d75 100644 --- a/applications/tari_indexer/src/network_state_sync/sync_progress.rs +++ b/applications/tari_indexer/src/network_state_sync/sync_progress.rs @@ -1,7 +1,7 @@ // Copyright 2025 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use async_graphql::indexmap::IndexMap; +use indexmap::IndexMap; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, Seq}; use tari_ootle_common_types::{shard::Shard, Epoch, ShardGroup, StateVersion}; diff --git a/applications/tari_signaling_server/Cargo.toml b/applications/tari_signaling_server/Cargo.toml index b721bab110..b47b66fe55 100644 --- a/applications/tari_signaling_server/Cargo.toml +++ b/applications/tari_signaling_server/Cargo.toml @@ -15,7 +15,8 @@ tari_engine_types = { workspace = true } tari_utilities = { workspace = true } anyhow = { workspace = true } -axum = { workspace = true, features = ["headers"] } +axum = { workspace = true } +axum-extra = { workspace = true, features = ["typed-header"] } axum-jrpc = { workspace = true, features = ["anyhow_error"] } # if we set clap version 4 in the workspace it would break other crates clap = { version = "4.1.4", features = ["derive", "env"] } diff --git a/applications/tari_signaling_server/src/data.rs b/applications/tari_signaling_server/src/data.rs index eb83556c98..25a3ee05de 100644 --- a/applications/tari_signaling_server/src/data.rs +++ b/applications/tari_signaling_server/src/data.rs @@ -3,6 +3,7 @@ use std::{collections::HashMap, time::Duration}; +use axum_extra::headers::authorization::Bearer; use chrono::Utc; use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, TokenData, Validation}; use serde::{Deserialize, Serialize}; @@ -68,9 +69,9 @@ impl Data { .map_err(anyhow::Error::new) } - pub fn check_jwt(&self, token: String) -> anyhow::Result { + pub fn check_jwt(&self, token: Bearer) -> anyhow::Result { let token: TokenData = decode( - &token, + token.token(), &DecodingKey::from_secret(self.secret_key.reveal()), &Validation::default(), )?; diff --git a/applications/tari_signaling_server/src/jrpc_server.rs b/applications/tari_signaling_server/src/jrpc_server.rs index 6c66755475..fe8952c282 100644 --- a/applications/tari_signaling_server/src/jrpc_server.rs +++ b/applications/tari_signaling_server/src/jrpc_server.rs @@ -9,14 +9,8 @@ use std::{ sync::{Arc, Mutex, MutexGuard}, }; -use axum::{ - extract::Extension, - http::{Request, StatusCode}, - middleware::Next, - response::Response, - routing::post, - Router, -}; +use axum::{extract::Extension, routing::post, Router}; +use axum_extra::{headers, headers::authorization::Bearer, TypedHeader}; use axum_jrpc::{ error::{JsonRpcError, JsonRpcErrorReason}, JrpcResult, @@ -34,21 +28,6 @@ use crate::{data::Data, permissions::JrpcPermissions}; const LOG_TARGET: &str = "tari::signaling_server::json_rpc"; -// We need to extract the token, because the first call is without any token. So we don't have to have two handlers. -async fn extract_token(mut request: Request, next: Next) -> Result { - let mut token_ext = None; - if let Some(token) = request.headers().get("authorization") { - if let Ok(token) = token.to_str() { - if let Some(token) = token.strip_prefix("Bearer ") { - token_ext = Some(token.to_string()); - } - } - } - request.extensions_mut().insert::>(token_ext); - let response = next.run(request).await; - Ok(response) -} - pub async fn listen( base_dir: PathBuf, preferred_address: SocketAddr, @@ -59,12 +38,11 @@ pub async fn listen( .route("/", post(handler)) .route("/json_rpc", post(handler)) .layer(Extension(Arc::new(Mutex::new(data)))) - .layer(CorsLayer::permissive()) - .layer(axum::middleware::from_fn(extract_token)); + .layer(CorsLayer::permissive()); - let server = axum::Server::try_bind(&preferred_address)?; - let server = server.serve(router.into_make_service()); - info!(target: LOG_TARGET, "🌐 JSON-RPC listening on {}", server.local_addr()); + let listener = tokio::net::TcpListener::bind(preferred_address).await?; + let server = axum::serve(listener, router); + info!(target: LOG_TARGET, "🌐 JSON-RPC listening on {}", server.local_addr()?); let server = server.with_graceful_shutdown(shutdown_signal); fs::write(base_dir.join("pid"), process::id().to_string())?; server.await?; @@ -195,9 +173,10 @@ fn get_answer_ice_candidates( async fn handler( Extension(data): Extension>>, - Extension(token): Extension>, + authorization_header: Option>>, value: JsonRpcExtractor, ) -> JrpcResult { + let token = authorization_header.map(|auth| auth.0 .0); let answer_id = value.get_answer_id(); let mut data = data.lock().unwrap(); let payload; @@ -206,7 +185,7 @@ async fn handler( Ok(id) => id, Err(e) => { return Ok(JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new(JsonRpcErrorReason::ApplicationError(401), format!("{}", e), json!({})), )); }, @@ -235,14 +214,14 @@ async fn handler( let permissions: JrpcPermissions = value.parse_params()?; let jwt = data.generate_jwt(permissions).map_err(|e| { JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new(JsonRpcErrorReason::InternalError, e.to_string(), json!({})), ) })?; json::to_value(jwt).map_err(|e| { JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new(JsonRpcErrorReason::InternalError, e.to_string(), json!({})), ) })? diff --git a/applications/tari_swarm_daemon/Cargo.toml b/applications/tari_swarm_daemon/Cargo.toml index e71faa93d2..3ffb3616af 100644 --- a/applications/tari_swarm_daemon/Cargo.toml +++ b/applications/tari_swarm_daemon/Cargo.toml @@ -27,7 +27,8 @@ tari_ootle_wallet_sdk = { workspace = true } anyhow = { workspace = true } async-trait = { workspace = true } -axum = { workspace = true, features = ["multipart", "headers"] } +axum = { workspace = true, features = ["multipart"] } +axum-extra = { workspace = true, features = ["typed-header"] } axum-jrpc = { workspace = true } clap = { workspace = true, features = ["derive", "env"] } fern = { workspace = true, features = ["colored", "date-based"] } @@ -40,7 +41,6 @@ indexmap = { workspace = true } slug = "0.1.6" log = { workspace = true } mime_guess = { workspace = true } -reqwest = { workspace = true, features = ["json"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } thiserror = { workspace = true } diff --git a/applications/tari_swarm_daemon/src/webserver/handler.rs b/applications/tari_swarm_daemon/src/webserver/handler.rs index d48940f555..7850451a82 100644 --- a/applications/tari_swarm_daemon/src/webserver/handler.rs +++ b/applications/tari_swarm_daemon/src/webserver/handler.rs @@ -3,7 +3,7 @@ use std::future::Future; -use axum::async_trait; +use async_trait::async_trait; use super::{context::HandlerContext, error::HandlerError}; diff --git a/applications/tari_swarm_daemon/src/webserver/server.rs b/applications/tari_swarm_daemon/src/webserver/server.rs index 61416ae6da..4cc11dde53 100644 --- a/applications/tari_swarm_daemon/src/webserver/server.rs +++ b/applications/tari_swarm_daemon/src/webserver/server.rs @@ -6,12 +6,14 @@ use std::{str::FromStr, sync::Arc}; use anyhow::Context; use axum::{ handler::HandlerWithoutStateExt, - headers::{authorization::Basic, Authorization}, - http::{HeaderValue, Response, Uri}, + http::{header, HeaderValue, Response, StatusCode, Uri}, response::IntoResponse, routing::post, Extension, Router, +}; +use axum_extra::{ + headers::{authorization::Basic, Authorization}, TypedHeader, }; use axum_jrpc::{ @@ -23,9 +25,9 @@ use axum_jrpc::{ }; use include_dir::{include_dir, Dir}; use log::*; -use reqwest::{header, StatusCode}; use serde::{de::DeserializeOwned, Serialize}; use serde_json::json; +use tari_ootle_app_utilities::tcp::try_bind_with_fallback; use tokio::fs; use tower_http::{cors::CorsLayer, services::ServeDir}; @@ -64,16 +66,9 @@ pub async fn run(context: HandlerContext) -> anyhow::Result<()> { .layer(Extension(Arc::new(context))) .layer(CorsLayer::permissive()); - let server = axum::Server::try_bind(&bind_address).or_else(|_| { - warn!( - target: LOG_TARGET, - "πŸ•ΈοΈ Failed to bind on preferred address {}. Trying OS-assigned", bind_address - ); - axum::Server::try_bind(&"127.0.0.1:0".parse().unwrap()) - })?; - - let server = server.serve(router.into_make_service()); - info!(target: LOG_TARGET, "πŸ•ΈοΈ Webserver listening on {}", server.local_addr()); + let listener = try_bind_with_fallback(bind_address).await?; + let server = axum::serve(listener, router); + info!(target: LOG_TARGET, "πŸ•ΈοΈ Webserver listening on {}", server.local_addr()?); server.await?; Ok(()) @@ -114,7 +109,7 @@ async fn handler( .body(body.to_owned()) .unwrap(); } - log::warn!(target: LOG_TARGET, "Not found {:?}", path); + warn!(target: LOG_TARGET, "Not found {:?}", path); Response::builder() .status(StatusCode::NOT_FOUND) .body(String::new()) @@ -178,11 +173,11 @@ where let resp = handler .handle(&context, params) .await - .map_err(|e| resolve_handler_error(answer_id, &e))?; + .map_err(|e| resolve_handler_error(answer_id.clone(), &e))?; Ok(JsonRpcResponse::success(answer_id, resp)) } -fn resolve_handler_error(answer_id: i64, e: &HandlerError) -> JsonRpcResponse { +fn resolve_handler_error(answer_id: axum_jrpc::Id, e: &HandlerError) -> JsonRpcResponse { match e { HandlerError::Anyhow(e) => resolve_any_error(answer_id, e), // HandlerError::NotFound => JsonRpcResponse::error( @@ -192,7 +187,7 @@ fn resolve_handler_error(answer_id: i64, e: &HandlerError) -> JsonRpcResponse { } } -fn resolve_any_error(answer_id: i64, e: &anyhow::Error) -> JsonRpcResponse { +fn resolve_any_error(answer_id: axum_jrpc::Id, e: &anyhow::Error) -> JsonRpcResponse { warn!(target: LOG_TARGET, "🌐 JSON-RPC error: {}", e); if let Some(handler_err) = e.downcast_ref::() { return resolve_handler_error(answer_id, handler_err); diff --git a/applications/tari_validator_node/Cargo.toml b/applications/tari_validator_node/Cargo.toml index 1a244157e1..a3232e800d 100644 --- a/applications/tari_validator_node/Cargo.toml +++ b/applications/tari_validator_node/Cargo.toml @@ -71,7 +71,7 @@ log4rs = { workspace = true, features = [ mime_guess = { workspace = true } prometheus-client = { workspace = true, optional = true } rand = { workspace = true } -reqwest = { workspace = true } +url = { workspace = true } serde = { workspace = true, features = ["default", "derive"] } serde_json = { workspace = true } thiserror = { workspace = true } diff --git a/applications/tari_validator_node/src/cli.rs b/applications/tari_validator_node/src/cli.rs index cbbdf1291c..0fb86a3996 100644 --- a/applications/tari_validator_node/src/cli.rs +++ b/applications/tari_validator_node/src/cli.rs @@ -24,10 +24,10 @@ use std::{net::SocketAddr, path::PathBuf}; use clap::Parser; use minotari_app_utilities::common_cli_args::CommonCliArgs; -use reqwest::Url; use tari_common::configuration::{ConfigOverrideProvider, Network as L1Network}; use tari_ootle_app_utilities::{configuration::convert_l1_network_to_network, p2p_config::ReachabilityMode}; use tari_ootle_common_types::Network; +use url::Url; #[derive(Parser, Debug)] #[clap(author, version, about, long_about = None)] diff --git a/applications/tari_validator_node/src/http_ui/server.rs b/applications/tari_validator_node/src/http_ui/server.rs index 92b6509f3a..ed45112989 100644 --- a/applications/tari_validator_node/src/http_ui/server.rs +++ b/applications/tari_validator_node/src/http_ui/server.rs @@ -23,14 +23,14 @@ use std::{net::SocketAddr, str::FromStr, sync::Arc}; use axum::{ - http::{Response, Uri}, + http::{header, HeaderValue, Response, StatusCode, Uri}, response::IntoResponse, routing::get, Router, }; use include_dir::{include_dir, Dir}; use log::*; -use reqwest::{header, header::HeaderValue, StatusCode}; +use tari_ootle_app_utilities::tcp::try_bind_with_fallback; const LOG_TARGET: &str = "tari::validator_node::web_ui::server"; @@ -41,16 +41,10 @@ pub async fn run_http_ui_server(address: SocketAddr, json_rpc_address: String) - .fallback(handler); info!(target: LOG_TARGET, "πŸ•ΈοΈ Web UI started at http://{}", address); - let server = axum::Server::try_bind(&address).or_else(|_| { - warn!( - target: LOG_TARGET, - "πŸ•ΈοΈ Failed to bind on preferred address {}. Trying OS-assigned", address - ); - axum::Server::try_bind(&"127.0.0.1:0".parse().unwrap()) - })?; + let listener = try_bind_with_fallback(address).await?; + let server = axum::serve(listener, router); - let server = server.serve(router.into_make_service()); - info!(target: LOG_TARGET, "πŸ•ΈοΈ Web UI listening on {}", server.local_addr()); + info!(target: LOG_TARGET, "πŸ•ΈοΈ Web UI listening on {}", server.local_addr()?); server.await?; info!(target: LOG_TARGET, "Stopping Web UI"); diff --git a/applications/tari_validator_node/src/json_rpc/handlers.rs b/applications/tari_validator_node/src/json_rpc/handlers.rs index 9f3ce69810..0a662e460f 100644 --- a/applications/tari_validator_node/src/json_rpc/handlers.rs +++ b/applications/tari_validator_node/src/json_rpc/handlers.rs @@ -163,7 +163,7 @@ impl JsonRpcHandlers { .networking .get_local_peer_info() .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; let fee_claim_public_key = self.config.validator_node.fee_claim_public_key.to_byte_type(); let response = GetIdentityResponse { peer_id: info.peer_id.to_string(), @@ -192,7 +192,7 @@ impl JsonRpcHandlers { if transaction.is_dry_run() { return Err(invalid_operation( - answer_id, + answer_id.clone(), "Dry-run transactions cannot be submitted via this endpoint.", )); } @@ -202,7 +202,7 @@ impl JsonRpcHandlers { if e.is_transaction_validator_error() { warn!(target: LOG_TARGET, "❌ Mempool rejected the transaction: {}", e); JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::InvalidRequest, format!("Mempool rejected the transaction: {}", e), @@ -212,7 +212,7 @@ impl JsonRpcHandlers { } else { error!(target: LOG_TARGET, "🚨 Mempool error: {}", e); JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::InternalError, format!("Mempool error: {}", e), @@ -271,7 +271,10 @@ impl JsonRpcHandlers { pub async fn get_recent_transactions(&self, value: JsonRpcExtractor) -> JrpcResult { let answer_id = value.get_answer_id(); - let tx = self.state_store.create_read_tx().map_err(internal_error(answer_id))?; + let tx = self + .state_store + .create_read_tx() + .map_err(internal_error(answer_id.clone()))?; match tx.transactions_get_paginated(1000, 0, Some(Ordering::Descending)) { Ok(recent_transactions) => { let res = GetRecentTransactionsResponse { @@ -298,26 +301,29 @@ impl JsonRpcHandlers { .epoch_manager .current_epoch() .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; - let tx = self.state_store.create_read_tx().map_err(internal_error(answer_id))?; + let tx = self + .state_store + .create_read_tx() + .map_err(internal_error(answer_id.clone()))?; let start_block = match req.from_id { Some(id) => Block::get(&tx, &id) .optional() - .map_err(internal_error(answer_id))? - .ok_or_else(|| not_found(answer_id, format!("Block {} not found", id)))?, + .map_err(internal_error(answer_id.clone()))? + .ok_or_else(|| not_found(answer_id.clone(), format!("Block {} not found", id)))?, None => { let leaf = LeafBlock::get(&tx, current_epoch) .optional() - .map_err(internal_error(answer_id))? - .ok_or_else(|| not_found(answer_id, format!("No leaf block for epoch {current_epoch}")))?; - Block::get(&tx, leaf.block_id()).map_err(internal_error(answer_id))? + .map_err(internal_error(answer_id.clone()))? + .ok_or_else(|| not_found(answer_id.clone(), format!("No leaf block for epoch {current_epoch}")))?; + Block::get(&tx, leaf.block_id()).map_err(internal_error(answer_id.clone()))? }, }; let blocks = tx .blocks_get_parent_chain(start_block.id(), req.limit) - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; let res = ListBlocksResponse { blocks }; Ok(JsonRpcResponse::success(answer_id, res)) @@ -335,7 +341,7 @@ impl JsonRpcHandlers { let tx_pool = self .state_store .with_read_tx(|tx| tx.transaction_pool_get_all()) - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; let res = json!({ "tx_pool": tx_pool }); Ok(JsonRpcResponse::success(answer_id, res)) } @@ -352,8 +358,13 @@ impl JsonRpcHandlers { Ok::<_, StorageError>((exec, time)) }) .optional() - .map_err(internal_error(answer_id))? - .ok_or_else(|| not_found(answer_id, format!("Transaction {} not found", request.transaction_id)))?; + .map_err(internal_error(answer_id.clone()))? + .ok_or_else(|| { + not_found( + answer_id.clone(), + format!("Transaction {} not found", request.transaction_id), + ) + })?; let response = GetTransactionResultResponse { final_decision: Decision::from(&execution.result.finalize.result), @@ -370,8 +381,13 @@ impl JsonRpcHandlers { let transaction = self .state_store .with_read_tx(|tx| TransactionRecord::get(tx, &data.transaction_id).optional()) - .map_err(internal_error(answer_id))? - .ok_or_else(|| not_found(answer_id, format!("Transaction {} not found", data.transaction_id)))?; + .map_err(internal_error(answer_id.clone()))? + .ok_or_else(|| { + not_found( + answer_id.clone(), + format!("Transaction {} not found", data.transaction_id), + ) + })?; Ok(JsonRpcResponse::success(answer_id, GetTransactionResponse { transaction: transaction.into_transaction(), @@ -388,7 +404,7 @@ impl JsonRpcHandlers { let address = SubstateAddress::from_substate_id(&data.address, data.version); SubstateRecord::get(tx, &address).optional() }) - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; match maybe_substate { Some(substate) if substate.is_destroyed() => Ok(JsonRpcResponse::success(answer_id, GetSubstateResponse { @@ -412,8 +428,8 @@ impl JsonRpcHandlers { let block = self .state_store .with_read_tx(|tx| Block::get(tx, &data.block_id).optional()) - .map_err(internal_error(answer_id))? - .ok_or_else(|| not_found(answer_id, format!("Block {} not found", data.block_id)))?; + .map_err(internal_error(answer_id.clone()))? + .ok_or_else(|| not_found(answer_id.clone(), format!("Block {} not found", data.block_id)))?; let res = GetBlockResponse { block }; Ok(JsonRpcResponse::success(answer_id, res)) @@ -425,7 +441,7 @@ impl JsonRpcHandlers { let count = self .state_store .with_read_tx(|tx| tx.filtered_blocks_get_count(req.filter_index, req.filter)) - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; let res = GetBlocksCountResponse { count }; Ok(JsonRpcResponse::success(answer_id, res)) } @@ -446,7 +462,7 @@ impl JsonRpcHandlers { req.ordering, ) }) - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; let res = GetBlocksResponse { blocks }; Ok(JsonRpcResponse::success(answer_id, res)) } @@ -459,7 +475,7 @@ impl JsonRpcHandlers { .template_manager .get_templates(req.limit as usize) .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; Ok(JsonRpcResponse::success(answer_id, GetTemplatesResponse { templates: templates @@ -481,13 +497,13 @@ impl JsonRpcHandlers { .template_manager .get_template(req.template_address) .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; let loaded = self .template_manager .load_template_abi(req.template_address) .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; let abi = TemplateAbi { template_name: loaded.template_def().template_name().to_string(), functions: loaded @@ -520,7 +536,7 @@ impl JsonRpcHandlers { .networking .get_active_connections() .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; let connections = active_connections .into_iter() @@ -549,7 +565,7 @@ impl JsonRpcHandlers { let size = self.mempool.get_mempool_size().await.map_err(|err| { error!(target: LOG_TARGET, "Error getting mempool size: {}", err); JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::InvalidParams, "Something went wrong".to_string(), @@ -565,13 +581,13 @@ impl JsonRpcHandlers { self.epoch_manager .wait_for_initial_scanning_to_complete() .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; let current_epoch = self.epoch_manager.get_current_epoch(); let current_epoch_hash = self .epoch_manager .get_current_epoch_hash() .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; let current_block_height = self .global_db @@ -583,7 +599,7 @@ impl JsonRpcHandlers { }) .map_err(|e| { JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::InternalError, format!("Could not get current block height: {}", e), @@ -602,7 +618,7 @@ impl JsonRpcHandlers { Ok(None) } else { Err(JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::InternalError, format!("Could not get committee shard:{}", err), @@ -621,7 +637,7 @@ impl JsonRpcHandlers { Ok(None) } else { Err(JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::InternalError, format!("Could not get committee shard:{}", err), @@ -634,7 +650,7 @@ impl JsonRpcHandlers { .epoch_manager .is_initial_scanning_complete() .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; let response = GetEpochManagerStatsResponse { current_epoch, current_block_height: current_block_height.unwrap_or(0), @@ -688,10 +704,10 @@ impl JsonRpcHandlers { .build(), ) .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; if wait_for_dial { - dial_wait.await.map_err(internal_error(answer_id))?; + dial_wait.await.map_err(internal_error(answer_id.clone()))?; } Ok(JsonRpcResponse::success(answer_id, AddPeerResponse {})) @@ -704,7 +720,7 @@ impl JsonRpcHandlers { .clone() .get_connected_peers() .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; let status = if peers.is_empty() { "Offline" } else { "Online" }; Ok(JsonRpcResponse::success(answer_id, GetCommsStatsResponse { @@ -720,7 +736,7 @@ impl JsonRpcHandlers { .get_our_validator_node(request.epoch) .await .optional() - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; Ok(JsonRpcResponse::success(answer_id, GetShardKeyResponse { shard_key: maybe_vn.map(|vn| vn.shard_key), @@ -756,7 +772,7 @@ impl JsonRpcHandlers { .epoch_manager .get_all_validator_nodes(epoch) .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; let vns = vns .into_iter() @@ -793,12 +809,12 @@ impl JsonRpcHandlers { .epoch_manager .current_epoch() .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; if self .epoch_manager .is_this_validator_registered_for_epoch(current_epoch) .await - .map_err(internal_error(answer_id))? + .map_err(internal_error(answer_id.clone()))? { return Err(invalid_operation( answer_id, @@ -853,19 +869,19 @@ impl JsonRpcHandlers { self.layer_one_transaction_submitter .submit_transaction(l1_tx) .await - .map_err(internal_error(answer_id))? + .map_err(internal_error(answer_id.clone()))? }, LayerOneTransactionParams::Exit => { let current_epoch = self .epoch_manager .current_epoch() .await - .map_err(internal_error(answer_id))?; + .map_err(internal_error(answer_id.clone()))?; if !self .epoch_manager .is_this_validator_registered_for_epoch(current_epoch) .await - .map_err(internal_error(answer_id))? + .map_err(internal_error(answer_id.clone()))? { return Err(invalid_operation( answer_id, @@ -899,7 +915,7 @@ impl JsonRpcHandlers { self.layer_one_transaction_submitter .submit_transaction(l1_tx) .await - .map_err(internal_error(answer_id))? + .map_err(internal_error(answer_id.clone()))? }, }; diff --git a/applications/tari_validator_node/src/json_rpc/jrpc_errors.rs b/applications/tari_validator_node/src/json_rpc/jrpc_errors.rs index 1df5f7fe55..603cdb7001 100644 --- a/applications/tari_validator_node/src/json_rpc/jrpc_errors.rs +++ b/applications/tari_validator_node/src/json_rpc/jrpc_errors.rs @@ -29,8 +29,8 @@ use axum_jrpc::{ JsonRpcResponse, }; -// pub fn invalid_params(answer_id: i64, details: S) -> impl Fn(T) -> JsonRpcResponse { -// move |err| { +// pub fn invalid_params(answer_id: axum_jrpc::Id, details: S) -> impl Fn(T) -> JsonRpcResponse +// { move |err| { // log::error!(target: LOG_TARGET, "⚠️ Request has invalid params: {details}. Error: {}", err); // JsonRpcResponse::error( // answer_id, @@ -44,7 +44,7 @@ use axum_jrpc::{ // } /// Creates a handler for internal errors. This will log the error and return a generic message to the user. -pub fn internal_error(answer_id: i64) -> impl Fn(T) -> JsonRpcResponse { +pub fn internal_error(answer_id: axum_jrpc::Id) -> impl FnOnce(T) -> JsonRpcResponse { move |err| { let msg = if cfg!(debug_assertions) || option_env!("CI").is_some() { err.to_string() @@ -59,7 +59,7 @@ pub fn internal_error(answer_id: i64) -> impl Fn(T) -> JsonRpcRespon } } -pub fn not_found>(answer_id: i64, details: T) -> JsonRpcResponse { +pub fn not_found>(answer_id: axum_jrpc::Id, details: T) -> JsonRpcResponse { JsonRpcResponse::error( answer_id, JsonRpcError::new( @@ -71,7 +71,7 @@ pub fn not_found>(answer_id: i64, details: T) -> JsonRpcResponse } /// Creates a handler for general errors. The error will be sent to the client as a JSON-RPC error response. -pub fn general_error>(answer_id: i64, details: T) -> JsonRpcResponse { +pub fn general_error>(answer_id: axum_jrpc::Id, details: T) -> JsonRpcResponse { JsonRpcResponse::error( answer_id, JsonRpcError::new( @@ -82,7 +82,7 @@ pub fn general_error>(answer_id: i64, details: T) -> JsonRpcResp ) } -pub fn invalid_operation>(answer_id: i64, details: T) -> JsonRpcResponse { +pub fn invalid_operation>(answer_id: axum_jrpc::Id, details: T) -> JsonRpcResponse { JsonRpcResponse::error( answer_id, JsonRpcError::new( diff --git a/applications/tari_validator_node/src/json_rpc/server.rs b/applications/tari_validator_node/src/json_rpc/server.rs index e8d20f0684..0b7d4ae0fb 100644 --- a/applications/tari_validator_node/src/json_rpc/server.rs +++ b/applications/tari_validator_node/src/json_rpc/server.rs @@ -20,19 +20,20 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use std::{net::SocketAddr, sync::Arc}; +use std::{future::IntoFuture, net::SocketAddr, sync::Arc}; use axum::{extract::Extension, routing::post, Router}; use axum_jrpc::{error::JsonRpcErrorReason, JrpcResult, JsonRpcAnswer, JsonRpcExtractor}; use log::*; +use tari_ootle_app_utilities::tcp::try_bind_with_fallback; use tower_http::cors::CorsLayer; use super::handlers::JsonRpcHandlers; const LOG_TARGET: &str = "tari::validator_node::json_rpc"; -pub fn spawn_json_rpc( - mut preferred_address: SocketAddr, +pub async fn spawn_json_rpc( + preferred_address: SocketAddr, handlers: JsonRpcHandlers, #[cfg(feature = "metrics")] registry: prometheus_client::registry::Registry, ) -> Result { @@ -48,18 +49,11 @@ pub fn spawn_json_rpc( .layer(Extension(Arc::new(handlers))) .layer(CorsLayer::permissive()); - let server = axum::Server::try_bind(&preferred_address).or_else(|_| { - warn!( - target: LOG_TARGET, - "🌐 Failed to bind on preferred address {}. Trying OS-assigned", preferred_address - ); - preferred_address.set_port(0); - axum::Server::try_bind(&preferred_address) - })?; - let server = server.serve(router.into_make_service()); - let addr = server.local_addr(); + let listener = try_bind_with_fallback(preferred_address).await?; + let server = axum::serve(listener, router); + let addr = server.local_addr()?; info!(target: LOG_TARGET, "🌐 JSON-RPC listening on {}", addr); - tokio::spawn(server); + tokio::spawn(server.into_future()); Ok(addr) } diff --git a/applications/tari_validator_node/src/lib.rs b/applications/tari_validator_node/src/lib.rs index 41f34af135..b936ead61f 100644 --- a/applications/tari_validator_node/src/lib.rs +++ b/applications/tari_validator_node/src/lib.rs @@ -140,7 +140,8 @@ pub async fn run_validator_node( handlers, #[cfg(feature = "metrics")] base_registry, - )?; + ) + .await?; // Run the web ui #[cfg(feature = "web_ui")] if let Some(address) = config.validator_node.web_ui_listener_address { diff --git a/applications/tari_wallet_cli/src/command/proof.rs b/applications/tari_wallet_cli/src/command/proof.rs index d1bdd8cb7a..dcc9af4286 100644 --- a/applications/tari_wallet_cli/src/command/proof.rs +++ b/applications/tari_wallet_cli/src/command/proof.rs @@ -22,6 +22,7 @@ use std::str::FromStr; +use base64::{prelude::BASE64_STANDARD, Engine}; use clap::{Args, Subcommand}; use tari_bor::encode; use tari_wallet_daemon_client::{types::ConfidentialCreateOutputProofRequest, WalletDaemonClient}; @@ -76,7 +77,7 @@ impl ProofsSubcommand { }, OutputType::Base64 => { let encode_proof = encode(&resp.proof)?; - println!("{}", base64::encode(encode_proof)); + println!("{}", BASE64_STANDARD.encode(encode_proof)); }, } }, diff --git a/applications/tari_wallet_cli/src/command/transaction.rs b/applications/tari_wallet_cli/src/command/transaction.rs index a876471b4d..723b3bfa39 100644 --- a/applications/tari_wallet_cli/src/command/transaction.rs +++ b/applications/tari_wallet_cli/src/command/transaction.rs @@ -753,7 +753,7 @@ impl FromStr for CliArg { fn from_str(s: &str) -> Result { if let Some(file) = s.strip_prefix('@') { let base64_data = fs::read_to_string(file).map_err(|e| anyhow!("Failed to read file {}: {}", file, e))?; - return Ok(CliArg::Blob(decode_exact(&base64::decode(base64_data)?)?)); + return Ok(CliArg::Blob(decode_exact(&base64_decode(base64_data)?)?)); } if let Ok(v) = s.parse::() { @@ -934,11 +934,11 @@ fn parse_globals(globals: Vec) -> Result, let contents = fs::read_to_string(url.path()) .map_err(|err| anyhow!("Failed to read file '{}': {}", &url, err))?; - base64::decode(contents.trim()) + base64_decode(contents.trim()) .map_err(|err| anyhow!("Failed to decode base64 file '{}': {}", url, err))? }, "data" => { - base64::decode(url.path()).map_err(|err| anyhow!("Failed to decode base64 '{}': {}", url, err))? + base64_decode(url.path()).map_err(|err| anyhow!("Failed to decode base64 '{}': {}", url, err))? }, scheme => anyhow::bail!("Unsupported scheme '{}'", scheme), }; @@ -952,3 +952,8 @@ fn parse_globals(globals: Vec) -> Result, } Ok(result) } + +fn base64_decode>(s: T) -> Result, base64::DecodeError> { + use base64::Engine; + base64::prelude::BASE64_STANDARD.decode(s) +} diff --git a/applications/tari_wallet_cli/src/from_base64.rs b/applications/tari_wallet_cli/src/from_base64.rs index cd59f9c174..a0a3d0219c 100644 --- a/applications/tari_wallet_cli/src/from_base64.rs +++ b/applications/tari_wallet_cli/src/from_base64.rs @@ -22,7 +22,7 @@ use std::{convert::TryFrom, str::FromStr}; -use base64; +use base64::{self, Engine}; #[derive(Debug, Clone, Copy)] pub struct FromBase64(pub T); @@ -41,7 +41,7 @@ where type Err = anyhow::Error; fn from_str(s: &str) -> Result { - let a = base64::decode(s)?; + let a = base64::prelude::BASE64_STANDARD.decode(s)?; let b = T::try_from(a)?; Ok(Self(b)) } diff --git a/applications/tari_walletd/Cargo.toml b/applications/tari_walletd/Cargo.toml index 246a4e5f97..d7844d0e03 100644 --- a/applications/tari_walletd/Cargo.toml +++ b/applications/tari_walletd/Cargo.toml @@ -30,8 +30,10 @@ tari_template_abi = { workspace = true } tari_transaction_components = { workspace = true } tari_transaction_manifest = { workspace = true } +async-trait = { workspace = true } anyhow = { workspace = true } -axum = { workspace = true, features = ["headers"] } +axum = { workspace = true } +axum-extra = { workspace = true, features = ["typed-header"] } axum-jrpc = { workspace = true, features = ["anyhow_error"] } clap = { workspace = true, features = ["derive", "env"] } config = { workspace = true } diff --git a/applications/tari_walletd/src/handlers/accounts.rs b/applications/tari_walletd/src/handlers/accounts.rs index b64b4dbc0a..8630e36c31 100644 --- a/applications/tari_walletd/src/handlers/accounts.rs +++ b/applications/tari_walletd/src/handlers/accounts.rs @@ -3,7 +3,7 @@ use std::{array, collections::HashSet}; -use axum::headers::authorization::Bearer; +use axum_extra::headers::authorization::Bearer; use indexmap::IndexMap; use log::*; use rand::rngs::OsRng; diff --git a/applications/tari_walletd/src/handlers/auth/jwt.rs b/applications/tari_walletd/src/handlers/auth/jwt.rs index d8ba08f05e..d88d74bd22 100644 --- a/applications/tari_walletd/src/handlers/auth/jwt.rs +++ b/applications/tari_walletd/src/handlers/auth/jwt.rs @@ -3,7 +3,7 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH}; -use axum::headers::authorization::Bearer; +use axum_extra::headers::authorization::Bearer; use jsonwebtoken::{errors, DecodingKey, EncodingKey, Header, Validation}; use serde::{Deserialize, Serialize}; use tari_crypto::tari_utilities::SafePassword; diff --git a/applications/tari_walletd/src/handlers/confidential.rs b/applications/tari_walletd/src/handlers/confidential.rs index 7e78e39aee..247097626f 100644 --- a/applications/tari_walletd/src/handlers/confidential.rs +++ b/applications/tari_walletd/src/handlers/confidential.rs @@ -4,7 +4,7 @@ use std::fs; use anyhow::anyhow; -use axum::headers::authorization::Bearer; +use axum_extra::headers::authorization::Bearer; use axum_jrpc::error::{JsonRpcError, JsonRpcErrorReason}; use log::*; use rand::rngs::OsRng; diff --git a/applications/tari_walletd/src/handlers/context.rs b/applications/tari_walletd/src/handlers/context.rs index 240ca2855b..9e7213e79f 100644 --- a/applications/tari_walletd/src/handlers/context.rs +++ b/applications/tari_walletd/src/handlers/context.rs @@ -1,7 +1,7 @@ // Copyright 2023 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use axum::headers::authorization::Bearer; +use axum_extra::headers::authorization::Bearer; use tari_ootle_wallet_sdk::WalletSdk; use tari_ootle_wallet_sdk_services::indexer_jrpc_impl::IndexerJsonRpcNetworkInterface; use tari_ootle_wallet_storage_sqlite::SqliteWalletStore; diff --git a/applications/tari_walletd/src/handlers/keys.rs b/applications/tari_walletd/src/handlers/keys.rs index d3fc754365..f5ce2671d6 100644 --- a/applications/tari_walletd/src/handlers/keys.rs +++ b/applications/tari_walletd/src/handlers/keys.rs @@ -1,7 +1,7 @@ // Copyright 2023 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use axum::headers::authorization::Bearer; +use axum_extra::headers::authorization::Bearer; use tari_crypto::{keys::PublicKey as PublicKeyTrait, ristretto::RistrettoPublicKey}; use tari_engine_types::ToByteType; use tari_ootle_wallet_sdk::apis::key_manager::KeyBranch; diff --git a/applications/tari_walletd/src/handlers/mod.rs b/applications/tari_walletd/src/handlers/mod.rs index 6c150239e9..29219f1b6f 100644 --- a/applications/tari_walletd/src/handlers/mod.rs +++ b/applications/tari_walletd/src/handlers/mod.rs @@ -23,7 +23,8 @@ pub mod webrtc; use std::future::Future; -use axum::{async_trait, headers::authorization::Bearer}; +use async_trait::async_trait; +use axum_extra::headers::authorization::Bearer; pub use context::HandlerContext; use error::HandlerError; diff --git a/applications/tari_walletd/src/handlers/nfts.rs b/applications/tari_walletd/src/handlers/nfts.rs index 91fbd4da08..a076ac69ca 100644 --- a/applications/tari_walletd/src/handlers/nfts.rs +++ b/applications/tari_walletd/src/handlers/nfts.rs @@ -4,7 +4,7 @@ use std::{collections::HashSet, slice}; use anyhow::anyhow; -use axum::headers::authorization::Bearer; +use axum_extra::headers::authorization::Bearer; use log::{info, warn}; use tari_engine_types::{ component::derive_component_address_from_public_key, diff --git a/applications/tari_walletd/src/handlers/rpc.rs b/applications/tari_walletd/src/handlers/rpc.rs index 9fe12f1e3e..f5bde8a24b 100644 --- a/applications/tari_walletd/src/handlers/rpc.rs +++ b/applications/tari_walletd/src/handlers/rpc.rs @@ -1,7 +1,7 @@ // Copyright 2023 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use axum::headers::authorization::Bearer; +use axum_extra::headers::authorization::Bearer; use tari_wallet_daemon_client::{ permissions::JrpcPermission, types::{ diff --git a/applications/tari_walletd/src/handlers/settings.rs b/applications/tari_walletd/src/handlers/settings.rs index 87af1e2869..0475d7e06f 100644 --- a/applications/tari_walletd/src/handlers/settings.rs +++ b/applications/tari_walletd/src/handlers/settings.rs @@ -1,7 +1,7 @@ // Copyright 2023 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use axum::headers::authorization::Bearer; +use axum_extra::headers::authorization::Bearer; use tari_ootle_common_types::optional::Optional; use tari_ootle_wallet_sdk::apis::config::ConfigKey; use tari_wallet_daemon_client::{ diff --git a/applications/tari_walletd/src/handlers/stealth_utxos.rs b/applications/tari_walletd/src/handlers/stealth_utxos.rs index d3f8946e27..8c44f428d2 100644 --- a/applications/tari_walletd/src/handlers/stealth_utxos.rs +++ b/applications/tari_walletd/src/handlers/stealth_utxos.rs @@ -1,7 +1,7 @@ // Copyright 2025 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use axum::headers::authorization::Bearer; +use axum_extra::headers::authorization::Bearer; use tari_wallet_daemon_client::{ permissions::JrpcPermission, types::{StealthUtxosListRequest, StealthUtxosListResponse, UtxoInfo}, diff --git a/applications/tari_walletd/src/handlers/substates.rs b/applications/tari_walletd/src/handlers/substates.rs index 37c5562de9..ced603de52 100644 --- a/applications/tari_walletd/src/handlers/substates.rs +++ b/applications/tari_walletd/src/handlers/substates.rs @@ -1,7 +1,7 @@ // Copyright 2023 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use axum::headers::authorization::Bearer; +use axum_extra::headers::authorization::Bearer; use tari_engine_types::substate::Substate; use tari_ootle_common_types::optional::Optional; use tari_ootle_wallet_sdk::network::WalletNetworkInterface; diff --git a/applications/tari_walletd/src/handlers/templates.rs b/applications/tari_walletd/src/handlers/templates.rs index 7bcd67e050..11ba4bbfc7 100644 --- a/applications/tari_walletd/src/handlers/templates.rs +++ b/applications/tari_walletd/src/handlers/templates.rs @@ -1,7 +1,7 @@ // Copyright 2023 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use axum::headers::authorization::Bearer; +use axum_extra::headers::authorization::Bearer; use tari_ootle_wallet_sdk::network::WalletNetworkInterface; use tari_wallet_daemon_client::{ permissions::JrpcPermission, diff --git a/applications/tari_walletd/src/handlers/transaction.rs b/applications/tari_walletd/src/handlers/transaction.rs index f505e46348..d3be588f10 100644 --- a/applications/tari_walletd/src/handlers/transaction.rs +++ b/applications/tari_walletd/src/handlers/transaction.rs @@ -3,7 +3,7 @@ use std::time::Duration; use anyhow::anyhow; -use axum::headers::authorization::Bearer; +use axum_extra::headers::authorization::Bearer; use axum_jrpc::error::{JsonRpcError, JsonRpcErrorReason}; use futures::{future, future::Either}; use log::*; diff --git a/applications/tari_walletd/src/handlers/validator.rs b/applications/tari_walletd/src/handlers/validator.rs index 6be90d4ca2..0979d1ae29 100644 --- a/applications/tari_walletd/src/handlers/validator.rs +++ b/applications/tari_walletd/src/handlers/validator.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use anyhow::anyhow; -use axum::headers::authorization::Bearer; +use axum_extra::headers::authorization::Bearer; use either::Either; use log::*; use tari_crypto::{keys::PublicKey as _, ristretto::RistrettoPublicKey}; diff --git a/applications/tari_walletd/src/handlers/wallet.rs b/applications/tari_walletd/src/handlers/wallet.rs index b328adfd6e..8f31787c98 100644 --- a/applications/tari_walletd/src/handlers/wallet.rs +++ b/applications/tari_walletd/src/handlers/wallet.rs @@ -1,7 +1,7 @@ // Copyright 2025 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use axum::headers::authorization::Bearer; +use axum_extra::headers::authorization::Bearer; use tari_wallet_daemon_client::types::{WalletGetInfoRequest, WalletGetInfoResponse}; use crate::handlers::HandlerContext; diff --git a/applications/tari_walletd/src/handlers/webauthn.rs b/applications/tari_walletd/src/handlers/webauthn.rs index d2bafbb254..38f00b5fed 100644 --- a/applications/tari_walletd/src/handlers/webauthn.rs +++ b/applications/tari_walletd/src/handlers/webauthn.rs @@ -1,7 +1,7 @@ // Copyright 2025 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use axum::headers::authorization::Bearer; +use axum_extra::headers::authorization::Bearer; use tari_ootle_wallet_storage_sqlite::SqliteWalletStore; use tari_wallet_daemon_client::types::{ WebauthnAlreadyRegisteredRequest, diff --git a/applications/tari_walletd/src/handlers/webrtc.rs b/applications/tari_walletd/src/handlers/webrtc.rs index 48ff3d407e..612c3c4631 100644 --- a/applications/tari_walletd/src/handlers/webrtc.rs +++ b/applications/tari_walletd/src/handlers/webrtc.rs @@ -3,7 +3,7 @@ use std::{net::SocketAddr, sync::Arc}; -use axum::headers::authorization::Bearer; +use axum_extra::headers::authorization::Bearer; use axum_jrpc::{ error::{JsonRpcError, JsonRpcErrorReason}, JrpcResult, @@ -30,7 +30,7 @@ pub fn handle_start( let answer_id = value.get_answer_id(); context.check_auth(token, &[JrpcPermission::StartWebrtc]).map_err(|e| { JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::ApplicationError(401), format!("Not authorized: {e}"), @@ -41,7 +41,7 @@ pub fn handle_start( let webrtc_start_request = value.parse_params::()?; let permissions = serde_json::from_value::(webrtc_start_request.permissions).map_err(|e| { JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::InvalidRequest, e.to_string(), @@ -52,7 +52,7 @@ pub fn handle_start( let jwt = context.jwt_api(); let (auth_token, _expiry) = jwt.generate_auth_token(permissions, None).map_err(|e| { JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::InternalError, e.to_string(), @@ -62,7 +62,7 @@ pub fn handle_start( })?; let permissions_token = jwt.grant(webrtc_start_request.name, &auth_token).map_err(|e| { JsonRpcResponse::error( - answer_id, + answer_id.clone(), JsonRpcError::new( JsonRpcErrorReason::InternalError, e.to_string(), diff --git a/applications/tari_walletd/src/http_ui/server.rs b/applications/tari_walletd/src/http_ui/server.rs index 9fca45ca90..f37b0cd0cc 100644 --- a/applications/tari_walletd/src/http_ui/server.rs +++ b/applications/tari_walletd/src/http_ui/server.rs @@ -23,14 +23,14 @@ use std::{net::SocketAddr, str::FromStr, sync::Arc}; use axum::{ - http::{HeaderValue, Response, Uri}, + http::{header, HeaderValue, Response, StatusCode, Uri}, response::IntoResponse, routing::get, Router, }; use include_dir::{include_dir, Dir}; use log::*; -use reqwest::{header, StatusCode}; +use tari_ootle_app_utilities::tcp::try_bind_with_fallback; use url::Url; const LOG_TARGET: &str = "tari::ootle::wallet_daemon::web_ui::server"; @@ -42,16 +42,9 @@ pub async fn run_http_ui_server(address: SocketAddr, json_rpc_address: Url) -> R .fallback(handler); info!(target: LOG_TARGET, "πŸ•ΈοΈ Web UI started at http://{}", address); - let server = axum::Server::try_bind(&address).or_else(|_| { - warn!( - target: LOG_TARGET, - "πŸ•ΈοΈ Failed to bind on preferred address {}. Trying OS-assigned", address - ); - axum::Server::try_bind(&"127.0.0.1:0".parse().unwrap()) - })?; - - let server = server.serve(router.into_make_service()); - info!(target: LOG_TARGET, "πŸ•ΈοΈ Web UI listening on {}", server.local_addr()); + let listener = try_bind_with_fallback(address).await?; + let server = axum::serve(listener, router); + info!(target: LOG_TARGET, "πŸ•ΈοΈ Web UI listening on {}", server.local_addr()?); server.await?; info!(target: LOG_TARGET, "Stopping Web UI"); diff --git a/applications/tari_walletd/src/jrpc_server.rs b/applications/tari_walletd/src/jrpc_server.rs index 5aecf283ab..4116b92166 100644 --- a/applications/tari_walletd/src/jrpc_server.rs +++ b/applications/tari_walletd/src/jrpc_server.rs @@ -5,12 +5,10 @@ use std::{net::SocketAddr, sync::Arc}; use axum::{ extract::{DefaultBodyLimit, Extension}, - headers, - headers::authorization::Bearer, routing::post, Router, - TypedHeader, }; +use axum_extra::{headers, headers::authorization::Bearer, TypedHeader}; use axum_jrpc::{ error::{JsonRpcError, JsonRpcErrorReason}, JrpcResult, @@ -21,6 +19,7 @@ use axum_jrpc::{ use log::*; use serde::{de::DeserializeOwned, Serialize}; use serde_json::json; +use tari_ootle_app_utilities::tcp::try_bind_with_fallback; use tokio::task; use tower_http::{cors::CorsLayer, trace::TraceLayer}; @@ -42,7 +41,7 @@ use crate::handlers::{ const LOG_TARGET: &str = "tari::ootle::wallet_daemon::json_rpc"; -pub fn spawn_listener( +pub async fn spawn_listener( preferred_address: SocketAddr, signaling_server_address: SocketAddr, context: HandlerContext, @@ -59,9 +58,9 @@ pub fn spawn_listener( // Limit the body size to 5MB to allow for wasm uploads .layer(DefaultBodyLimit::max(5*1024*1024)); - let server = axum::Server::try_bind(&preferred_address)?; - let server = server.serve(router.into_make_service()); - let listen_addr = server.local_addr(); + let listener = try_bind_with_fallback(preferred_address).await?; + let server = axum::serve(listener, router); + let listen_addr = server.local_addr()?; info!(target: LOG_TARGET, "🌐 JSON-RPC listening on {listen_addr}"); let server = server.with_graceful_shutdown(shutdown_signal); let task = tokio::spawn(async move { @@ -222,11 +221,11 @@ where })?, ) .await - .map_err(|e| resolve_handler_error(answer_id, &e))?; + .map_err(|e| resolve_handler_error(answer_id.clone(), &e))?; Ok(JsonRpcResponse::success(answer_id, resp)) } -fn resolve_handler_error(answer_id: i64, e: &HandlerError) -> JsonRpcResponse { +fn resolve_handler_error(answer_id: axum_jrpc::Id, e: &HandlerError) -> JsonRpcResponse { match e { HandlerError::Anyhow(e) => resolve_any_error(answer_id, e), HandlerError::NotFound => JsonRpcResponse::error( @@ -240,7 +239,7 @@ fn resolve_handler_error(answer_id: i64, e: &HandlerError) -> JsonRpcResponse { } } -fn resolve_any_error(answer_id: i64, e: &anyhow::Error) -> JsonRpcResponse { +fn resolve_any_error(answer_id: axum_jrpc::Id, e: &anyhow::Error) -> JsonRpcResponse { warn!(target: LOG_TARGET, "🌐 JSON-RPC error: {}", e); if let Some(handler_err) = e.downcast_ref::() { return resolve_handler_error(answer_id, handler_err); diff --git a/applications/tari_walletd/src/lib.rs b/applications/tari_walletd/src/lib.rs index 28f6722e5c..706054eca2 100644 --- a/applications/tari_walletd/src/lib.rs +++ b/applications/tari_walletd/src/lib.rs @@ -119,7 +119,8 @@ pub async fn run_tari_ootle_walletd( authenticator, shutdown_signal, ); - let (jrpc_address, listen_fut) = jrpc_server::spawn_listener(jrpc_address, signaling_server_address, handlers)?; + let (jrpc_address, listen_fut) = + jrpc_server::spawn_listener(jrpc_address, signaling_server_address, handlers).await?; // Run the web ui #[cfg(feature = "web_ui")] diff --git a/applications/tari_walletd/src/webrtc.rs b/applications/tari_walletd/src/webrtc.rs index 080dd8271d..ed94f6051c 100644 --- a/applications/tari_walletd/src/webrtc.rs +++ b/applications/tari_walletd/src/webrtc.rs @@ -45,8 +45,7 @@ async fn make_request( let url = format!("http://{}", address); let client = reqwest::Client::new(); let body = JsonRpcRequest { - id: 0, - jsonrpc: "2.0".to_string(), + id: axum_jrpc::Id::Num(0), method, params: serde_json::to_value(params)?, }; diff --git a/networking/libp2p-messaging/src/codec/prost.rs b/networking/libp2p-messaging/src/codec/prost.rs index f67e5b195c..aff55e5575 100644 --- a/networking/libp2p-messaging/src/codec/prost.rs +++ b/networking/libp2p-messaging/src/codec/prost.rs @@ -22,7 +22,7 @@ impl Default for ProstCodec { #[async_trait] impl Codec for ProstCodec -where TMsg: prost::Message + Default +where TMsg: prost::Message + fmt::Debug + Default { type Message = TMsg; diff --git a/networking/rpc_framework/Cargo.toml b/networking/rpc_framework/Cargo.toml index 3b7bd94109..534e750d24 100644 --- a/networking/rpc_framework/Cargo.toml +++ b/networking/rpc_framework/Cargo.toml @@ -21,14 +21,13 @@ prost = { workspace = true, features = ["std"] } thiserror = { workspace = true } tokio = { workspace = true, features = ["default", "sync", "time", "rt", "macros"] } tokio-util = { workspace = true, features = ["compat", "codec"] } -tower = { workspace = true, features = ["default", "make", "util"] } +tower = { workspace = true, features = ["make", "util"] } tracing = { workspace = true } libp2p = { workspace = true } libp2p-substream = { workspace = true } [build-dependencies] -prost-build = { workspace = true } proto_builder = { workspace = true } [features] diff --git a/utilities/db_inspector/Cargo.toml b/utilities/db_inspector/Cargo.toml index 55b19eb513..4c66117165 100644 --- a/utilities/db_inspector/Cargo.toml +++ b/utilities/db_inspector/Cargo.toml @@ -19,7 +19,6 @@ humantime = { workspace = true } include_dir = { workspace = true } log = { workspace = true } mime_guess = { workspace = true } -reqwest = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } tokio = { workspace = true, features = ["macros", "rt-multi-thread", "signal"] } diff --git a/utilities/db_inspector/src/webserver/handlers/tables.rs b/utilities/db_inspector/src/webserver/handlers/tables.rs index 354408829d..ae6726d267 100644 --- a/utilities/db_inspector/src/webserver/handlers/tables.rs +++ b/utilities/db_inspector/src/webserver/handlers/tables.rs @@ -22,9 +22,8 @@ use crate::webserver::{ handlers::types::{decode_hex_prefix, Column, TableRequest, TableResponse}, }; -pub fn list(cf: F) -> impl Handler<(), S, B> +pub fn list(cf: F) -> impl Handler<(), S> where - B: axum::body::HttpBody + Send + 'static, S: Clone + Send + Sync + 'static, F: Fn() -> CF + Send + Sync + Clone + 'static, CF: Cf + Send + Sync + 'static, diff --git a/utilities/db_inspector/src/webserver/server.rs b/utilities/db_inspector/src/webserver/server.rs index 9d583f2744..cf915bd280 100644 --- a/utilities/db_inspector/src/webserver/server.rs +++ b/utilities/db_inspector/src/webserver/server.rs @@ -4,7 +4,7 @@ use std::{str::FromStr, sync::Arc}; use axum::{ - http::{HeaderValue, Response, Uri}, + http::{header, HeaderValue, Response, StatusCode, Uri}, response::IntoResponse, routing::get, Extension, @@ -12,7 +12,6 @@ use axum::{ }; use include_dir::{include_dir, Dir}; use log::*; -use reqwest::{header, StatusCode}; use tari_state_store_rocksdb::{column_families, traits::Cf}; use tower_http::cors::CorsLayer; @@ -118,16 +117,18 @@ pub async fn run(context: HandlerContext) -> anyhow::Result<()> { .layer(CorsLayer::permissive()) .layer(Extension(Arc::new(context))); - let server = axum::Server::try_bind(&bind_address).or_else(|_| { - warn!( - target: LOG_TARGET, - "πŸ•ΈοΈ Failed to bind on preferred address {}. Trying OS-assigned", bind_address - ); - axum::Server::try_bind(&"127.0.0.1:0".parse().unwrap()) - })?; - - let server = server.serve(router.into_make_service()); - info!(target: LOG_TARGET, "πŸ•ΈοΈ Webserver listening on http://{}", server.local_addr()); + let listener = match tokio::net::TcpListener::bind(bind_address).await { + Ok(l) => l, + Err(e) => { + warn!( + target: LOG_TARGET, + "πŸ•ΈοΈ Failed to bind on preferred address {} ({e}). Trying OS-assigned", bind_address + ); + tokio::net::TcpListener::bind(("127.0.0.1", 0u16)).await? + }, + }; + let server = axum::serve(listener, router); + info!(target: LOG_TARGET, "πŸ•ΈοΈ Webserver listening on http://{}", server.local_addr()?); server.await?; Ok(())