From 41fb17a31bb7b82bb7e73fa503970506a2209bae Mon Sep 17 00:00:00 2001 From: dynco-nym <173912580+dynco-nym@users.noreply.github.com> Date: Fri, 20 Dec 2024 12:18:45 +0100 Subject: [PATCH] Extend swagger docs (#5235) * WIP adding derive(ToSchema) * Derive ToSchema for more types * ContractBuildInformation on /nym_contracts_detailed * rustfmt * Add cfg_attr * A bunch of annotations * Compiles with utoipa 5.2 * WIP * Post rebase fixes * Gitattributes to ignore .sqlx diffs * generate Sqlx schema files * Improvements * Move ecash schema out of ecash crate * Move redocly config to nym-api/ * Move redocly config to nym-api/ * Remove ErrorResponse * Move generated openapi spec to .gitignore * Include BSL licence * Remove utoipa from ecash toml file * Remove placeholder annotations * Chain-watcher rebase changes * Update licence info * Treat Scalar as String in OpenAPI --- .gitattributes | 1 + .gitignore | 3 +- Cargo.lock | 142 ++++----- Cargo.toml | 6 +- LICENSES/BSL-1.0 | 23 ++ .../contracts-common/Cargo.toml | 4 +- .../contracts-common/src/types.rs | 1 + .../mixnet-contract/src/gateway.rs | 3 + .../mixnet-contract/src/mixnode.rs | 15 + .../mixnet-contract/src/nym_node.rs | 11 + .../mixnet-contract/src/reward_params.rs | 11 + .../mixnet-contract/src/rewarding/mod.rs | 5 + .../mixnet-contract/src/types.rs | 8 + common/credentials-interface/Cargo.toml | 1 + .../exit-policy/src/policy/address_policy.rs | 7 +- common/http-api-common/src/lib.rs | 1 - common/nym_offline_compact_ecash/Cargo.toml | 2 +- .../src/common_types.rs | 2 +- common/nym_offline_compact_ecash/src/lib.rs | 2 +- common/ticketbooks-merkle/Cargo.toml | 3 +- common/ticketbooks-merkle/src/lib.rs | 15 +- common/types/Cargo.toml | 1 + common/types/src/monitoring.rs | 6 +- deny.toml | 1 + nym-api/Cargo.toml | 2 +- nym-api/nym-api-requests/Cargo.toml | 2 +- nym-api/nym-api-requests/src/ecash/models.rs | 272 ++++++++++++++---- nym-api/nym-api-requests/src/legacy.rs | 2 +- nym-api/nym-api-requests/src/models.rs | 45 ++- nym-api/nym-api-requests/src/nym_nodes.rs | 10 +- nym-api/redocly/.redocly.lint-ignore.yaml | 47 +++ nym-api/redocly/.redocly.yaml | 12 + nym-api/redocly/readme.MD | 27 ++ nym-api/redocly/redocly.sh | 5 + nym-api/src/ecash/api_routes/issued.rs | 4 +- .../src/ecash/api_routes/partial_signing.rs | 6 +- nym-api/src/ecash/api_routes/spending.rs | 6 +- nym-api/src/network/handlers.rs | 18 +- nym-api/src/network/models.rs | 5 +- .../handlers/without_monitor.rs | 20 +- nym-api/src/node_status_api/models.rs | 14 +- nym-api/src/nym_nodes/handlers/legacy.rs | 4 +- .../nym_nodes/handlers/unstable/full_fat.rs | 2 +- .../src/nym_nodes/handlers/unstable/mod.rs | 1 + .../handlers/unstable/semi_skimmed.rs | 2 +- .../nym_nodes/handlers/unstable/skimmed.rs | 33 ++- nym-api/src/support/http/helpers.rs | 2 + nym-api/src/support/http/openapi.rs | 80 +----- .../src/api/v1/mod.rs | 2 - .../src/api/v1/ticketbook/models.rs | 3 + .../src/http/router/api/v1/openapi.rs | 3 - .../src/http/router/api/v1/ticketbook/mod.rs | 46 +-- .../http/router/api/v1/ticketbook/shares.rs | 12 +- .../nym-credential-proxy/src/http/types.rs | 5 +- .../src/http/api/gateways.rs | 4 +- .../src/http/api/metrics/sessions.rs | 2 +- .../src/http/api/mixnodes.rs | 2 +- .../src/http/api/services/mod.rs | 2 +- .../nym-node-status-api/src/http/api_docs.rs | 1 - .../nym-node-status-api/src/http/mod.rs | 20 +- nym-node/nym-node-requests/Cargo.toml | 2 +- nym-node/nym-node-requests/src/api/mod.rs | 18 +- .../src/api/v1/metrics/models.rs | 17 +- .../src/api/v1/node/models.rs | 3 + .../http/router/api/v1/authenticator/root.rs | 4 +- .../api/v1/gateway/client_interfaces/mod.rs | 12 +- .../node/http/router/api/v1/gateway/root.rs | 4 +- .../src/node/http/router/api/v1/health.rs | 4 +- .../router/api/v1/ip_packet_router/root.rs | 4 +- .../router/api/v1/metrics/legacy_mixing.rs | 4 +- .../router/api/v1/metrics/packets_stats.rs | 4 +- .../http/router/api/v1/metrics/sessions.rs | 4 +- .../node/http/router/api/v1/metrics/verloc.rs | 15 +- .../http/router/api/v1/metrics/wireguard.rs | 4 +- .../node/http/router/api/v1/mixnode/root.rs | 4 +- .../api/v1/network_requester/exit_policy.rs | 4 +- .../router/api/v1/network_requester/root.rs | 4 +- .../node/http/router/api/v1/node/auxiliary.rs | 4 +- .../router/api/v1/node/build_information.rs | 4 +- .../http/router/api/v1/node/description.rs | 4 +- .../node/http/router/api/v1/node/hardware.rs | 6 +- .../router/api/v1/node/host_information.rs | 6 +- .../src/node/http/router/api/v1/node/roles.rs | 4 +- .../src/node/http/router/api/v1/openapi.rs | 4 - nym-node/src/node/http/router/types.rs | 4 +- ...9146f8b40d46d14aa0ecb7237d5d78a9f463f.json | 12 + ...3381fe8e839998717e6d1a0502f54438fc9b0.json | 12 + ...e836c7cff2646b6b76559543b4e4056094d58.json | 12 + ...91d372e750a74e2eb5a252a787cf571c326e4.json | 12 + ...738f6bda8532a5bd2d944884cd87784eefe43.json | 26 ++ ...a93e944b0d44ed1f7c1036f306e34372da11c.json | 20 ++ ...c8643ae77e22ad908147b910d9406234911f0.json | 12 + ...b9036df67d74966a35d9af74d43e93d3524eb.json | 12 + ...36dcb76982d7859e406daa12c97f671e6fd3b.json | 20 ++ ...1cb75bd6df809fb1f17620ab888d184291f0b.json | 12 + ...3f419a849d4ec45af40b052a4cbf09b44f3ec.json | 20 ++ ...57ed06dbebb3615b912fa59d9e22a097ded57.json | 12 + ...8b10dd0f01a04f77634d09af260b97a155264.json | 12 + ...efa10eee3e1488f7bb990847374c09e8a5944.json | 12 + ...e35e94e172738678c7299334c47a54caf5c50.json | 12 + ...ecb9fbe7b3636feb0d36cbad0610a0685cccc.json | 12 + ...00a9e2b6064f2252c66882fd4a7dd17e187cc.json | 12 + ...8d33ad532e06c270adc6f62c4fd6c40ecabcb.json | 12 + ...18384da48966d5a2b2de842e747ee1d7a5769.json | 12 + ...b310d02d77083207b6a42eb1f8e4dd80b00a8.json | 12 + ...9ce71582635df47f52dcf3fd1df4e7be6b96d.json | 20 ++ ...7472d7a3c6080766ab0f02aba4c776545adad.json | 20 ++ ...873717ba4b9d8f83bcb05f8a39094f0ff7c32.json | 20 ++ ...4f40adb4d74539bfe36432ae62a2b5268f5fd.json | 12 + ...a989aecff01e835cb8fc04acee1b83480a970.json | 20 ++ ...ab220797a39071754ad20bc14819fcced6c56.json | 12 + ...bb5ca4bbbb50e7a7fcaacc5361dde3157247a.json | 20 ++ nyx-chain-watcher/src/db/models.rs | 2 +- nyx-chain-watcher/src/models.rs | 11 + 114 files changed, 1116 insertions(+), 443 deletions(-) create mode 100644 .gitattributes create mode 100644 LICENSES/BSL-1.0 create mode 100644 nym-api/redocly/.redocly.lint-ignore.yaml create mode 100644 nym-api/redocly/.redocly.yaml create mode 100644 nym-api/redocly/readme.MD create mode 100755 nym-api/redocly/redocly.sh create mode 100644 nym-validator-rewarder/.sqlx/query-0a802236d0b9cc7679971f884a89146f8b40d46d14aa0ecb7237d5d78a9f463f.json create mode 100644 nym-validator-rewarder/.sqlx/query-0e03fcbde46a0296e029624ae083381fe8e839998717e6d1a0502f54438fc9b0.json create mode 100644 nym-validator-rewarder/.sqlx/query-1d3938bc8d8d6829289ef7ff78ee836c7cff2646b6b76559543b4e4056094d58.json create mode 100644 nym-validator-rewarder/.sqlx/query-1ebd5510a96bc84a88cc91316f891d372e750a74e2eb5a252a787cf571c326e4.json create mode 100644 nym-validator-rewarder/.sqlx/query-227e0cd05334ac228ca55f309f3738f6bda8532a5bd2d944884cd87784eefe43.json create mode 100644 nym-validator-rewarder/.sqlx/query-2561fb016951ea4cd29e43fb9a4a93e944b0d44ed1f7c1036f306e34372da11c.json create mode 100644 nym-validator-rewarder/.sqlx/query-2db92c21c933bc1eadc486867f7c8643ae77e22ad908147b910d9406234911f0.json create mode 100644 nym-validator-rewarder/.sqlx/query-3227631b516dd16b8474e050393b9036df67d74966a35d9af74d43e93d3524eb.json create mode 100644 nym-validator-rewarder/.sqlx/query-397bde15134e32921ad87037e9436dcb76982d7859e406daa12c97f671e6fd3b.json create mode 100644 nym-validator-rewarder/.sqlx/query-3b75821c30e4e2a87fea04c92a91cb75bd6df809fb1f17620ab888d184291f0b.json create mode 100644 nym-validator-rewarder/.sqlx/query-3bdf81a9db6075f6f77224c30553f419a849d4ec45af40b052a4cbf09b44f3ec.json create mode 100644 nym-validator-rewarder/.sqlx/query-422a516baacf8ba26ea2dca46fa57ed06dbebb3615b912fa59d9e22a097ded57.json create mode 100644 nym-validator-rewarder/.sqlx/query-6be3f8abfa7a2e05721e533e4128b10dd0f01a04f77634d09af260b97a155264.json create mode 100644 nym-validator-rewarder/.sqlx/query-7c2aea05703247a865d5639bd84efa10eee3e1488f7bb990847374c09e8a5944.json create mode 100644 nym-validator-rewarder/.sqlx/query-84e200c64ff49be7241d43841d0e35e94e172738678c7299334c47a54caf5c50.json create mode 100644 nym-validator-rewarder/.sqlx/query-98b2ac25c05850c31990ce0b48fecb9fbe7b3636feb0d36cbad0610a0685cccc.json create mode 100644 nym-validator-rewarder/.sqlx/query-a3db765a00f07d80656e58a543500a9e2b6064f2252c66882fd4a7dd17e187cc.json create mode 100644 nym-validator-rewarder/.sqlx/query-b865ffb57fa5f31de74e0dce28a8d33ad532e06c270adc6f62c4fd6c40ecabcb.json create mode 100644 nym-validator-rewarder/.sqlx/query-b9e16b5c6e11cfa2d3dfee8c0bf18384da48966d5a2b2de842e747ee1d7a5769.json create mode 100644 nym-validator-rewarder/.sqlx/query-be654926e94fb6a07ebb94dd526b310d02d77083207b6a42eb1f8e4dd80b00a8.json create mode 100644 nym-validator-rewarder/.sqlx/query-c88d07fecc3f33deaa6e93db1469ce71582635df47f52dcf3fd1df4e7be6b96d.json create mode 100644 nym-validator-rewarder/.sqlx/query-ceb15dea9ac66e69cfc2fa8fbd57472d7a3c6080766ab0f02aba4c776545adad.json create mode 100644 nym-validator-rewarder/.sqlx/query-d67b6b3fc1099b3ca48eed945d9873717ba4b9d8f83bcb05f8a39094f0ff7c32.json create mode 100644 nym-validator-rewarder/.sqlx/query-dcb00d96a003c9ad0b6213ac6974f40adb4d74539bfe36432ae62a2b5268f5fd.json create mode 100644 nym-validator-rewarder/.sqlx/query-e08a6456f6bd3cc5e8201d18dc3a989aecff01e835cb8fc04acee1b83480a970.json create mode 100644 nym-validator-rewarder/.sqlx/query-eba74b6531013fe5a83287bd50dab220797a39071754ad20bc14819fcced6c56.json create mode 100644 nym-validator-rewarder/.sqlx/query-fa2ea62ed8ccb08d0ef70bc212cbb5ca4bbbb50e7a7fcaacc5361dde3157247a.json diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000000..24e0b39b6a5 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +nym-validator-rewarder/.sqlx/** diff=nodiff diff --git a/.gitignore b/.gitignore index f931d9b0bb2..5646f38f538 100644 --- a/.gitignore +++ b/.gitignore @@ -54,7 +54,8 @@ nym-network-monitor/__pycache__ nym-network-monitor/*.key nym-network-monitor/.envrc nym-network-monitor/.envrc +nym-api/redocly/formatted-openapi.json *.sqlite -.build \ No newline at end of file +.build diff --git a/Cargo.lock b/Cargo.lock index df18e606368..30a01aa784a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3836,6 +3836,12 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "lockfree-object-pool" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" + [[package]] name = "log" version = "0.4.22" @@ -4355,27 +4361,6 @@ dependencies = [ "libc", ] -[[package]] -name = "num_enum" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" -dependencies = [ - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.90", -] - [[package]] name = "num_threads" version = "0.1.7" @@ -5001,6 +4986,7 @@ dependencies = [ "serde", "serde_json", "thiserror", + "utoipa", "vergen", ] @@ -5192,6 +5178,7 @@ dependencies = [ "strum 0.26.3", "thiserror", "time", + "utoipa", ] [[package]] @@ -6530,6 +6517,7 @@ dependencies = [ "serde_json", "sha2 0.10.8", "time", + "utoipa", ] [[package]] @@ -6593,6 +6581,7 @@ dependencies = [ "thiserror", "ts-rs", "url", + "utoipa", "x25519-dalek", ] @@ -7485,39 +7474,6 @@ dependencies = [ "log", ] -[[package]] -name = "proc-macro-crate" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" -dependencies = [ - "toml_edit 0.21.1", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro-error-attr2" version = "2.0.0" @@ -7949,7 +7905,6 @@ checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" dependencies = [ "base64 0.22.1", "bytes", - "futures-channel", "futures-core", "futures-util", "http 1.1.0", @@ -8875,6 +8830,12 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "siphasher" version = "0.3.11" @@ -9932,7 +9893,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.14", + "toml_edit", ] [[package]] @@ -9944,17 +9905,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_edit" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" -dependencies = [ - "indexmap 2.2.6", - "toml_datetime", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.22.14" @@ -9965,7 +9915,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.13", + "winnow", ] [[package]] @@ -10612,9 +10562,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "utoipa" -version = "4.2.3" +version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5afb1a60e207dca502682537fefcfd9921e71d0b83e9576060f09abc6efab23" +checksum = "514a48569e4e21c86d0b84b5612b5e73c0b2cf09db63260134ba426d4e8ea714" dependencies = [ "indexmap 2.2.6", "serde", @@ -10624,11 +10574,10 @@ dependencies = [ [[package]] name = "utoipa-gen" -version = "4.3.0" +version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bf0e16c02bc4bf5322ab65f10ab1149bdbcaa782cba66dc7057370a3f8190be" +checksum = "5629efe65599d0ccd5d493688cbf6e03aa7c1da07fe59ff97cf5977ed0637f66" dependencies = [ - "proc-macro-error", "proc-macro2", "quote", "regex", @@ -10638,14 +10587,13 @@ dependencies = [ [[package]] name = "utoipa-swagger-ui" -version = "7.1.0" +version = "8.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943e0ff606c6d57d410fd5663a4d7c074ab2c5f14ab903b9514565e59fa1189e" +checksum = "a5c80b4dd79ea382e8374d67dcce22b5c6663fa13a82ad3886441d1bbede5e35" dependencies = [ "axum 0.7.7", "mime_guess", "regex", - "reqwest 0.12.4", "rust-embed", "serde", "serde_json", @@ -10656,18 +10604,18 @@ dependencies = [ [[package]] name = "utoipauto" -version = "0.1.14" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608b8f2279483be386261655b562e40877ea434eb92093c894a644fda2021860" +checksum = "cba36db2c397c614110554a60fbb4bb97d5f8c6823775c766e6f455e37377047" dependencies = [ "utoipauto-macro", ] [[package]] name = "utoipauto-core" -version = "0.1.12" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17e82ab96c5a55263b5bed151b8426410d93aa909a453acdbd4b6792b5af7d64" +checksum = "268d76aaebb80eba79240b805972e52d7d410d4bcc52321b951318b0f440cd60" dependencies = [ "proc-macro2", "quote", @@ -10676,9 +10624,9 @@ dependencies = [ [[package]] name = "utoipauto-macro" -version = "0.1.12" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8338dc3c9526011ffaa2aa6bd60ddfda9d49d2123108690755c6e34844212" +checksum = "382673bda1d05c85b4550d32fd4192ccd4cffe9a908543a0795d1e7682b36246" dependencies = [ "proc-macro2", "quote", @@ -11269,15 +11217,6 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "0.6.13" @@ -11390,9 +11329,9 @@ dependencies = [ [[package]] name = "zip" -version = "1.1.4" +version = "2.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cc23c04387f4da0374be4533ad1208cbb091d5c11d070dfef13676ad6497164" +checksum = "40dd8c92efc296286ce1fbd16657c5dbefff44f1b4ca01cc5f517d8b7b3d3e2e" dependencies = [ "arbitrary", "crc32fast", @@ -11400,8 +11339,9 @@ dependencies = [ "displaydoc", "flate2", "indexmap 2.2.6", - "num_enum", + "memchr", "thiserror", + "zopfli", ] [[package]] @@ -11431,3 +11371,17 @@ dependencies = [ "wasmtimer", "zeroize", ] + +[[package]] +name = "zopfli" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946" +dependencies = [ + "bumpalo", + "crc32fast", + "lockfree-object-pool", + "log", + "once_cell", + "simd-adler32", +] diff --git a/Cargo.toml b/Cargo.toml index cd44c15136d..122784eb5a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -347,9 +347,9 @@ tracing-log = "0.2" ts-rs = "10.0.0" tungstenite = { version = "0.20.1", default-features = false } url = "2.5" -utoipa = "4.2" -utoipa-swagger-ui = "7.1" -utoipauto = "0.1" +utoipa = "5.2" +utoipa-swagger-ui = "8.0" +utoipauto = "0.2" uuid = "*" vergen = { version = "=8.3.1", default-features = false } walkdir = "2" diff --git a/LICENSES/BSL-1.0 b/LICENSES/BSL-1.0 new file mode 100644 index 00000000000..36b7cd93cdf --- /dev/null +++ b/LICENSES/BSL-1.0 @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/common/cosmwasm-smart-contracts/contracts-common/Cargo.toml b/common/cosmwasm-smart-contracts/contracts-common/Cargo.toml index fa8a511222f..4a80db6afad 100644 --- a/common/cosmwasm-smart-contracts/contracts-common/Cargo.toml +++ b/common/cosmwasm-smart-contracts/contracts-common/Cargo.toml @@ -13,6 +13,7 @@ cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } schemars = { workspace = true } +utoipa = { workspace = true, optional = true } serde = { workspace = true, features = ["derive"] } thiserror = { workspace = true } @@ -23,4 +24,5 @@ serde_json = { workspace = true } vergen = { workspace = true, features = ["build", "git", "gitcl", "rustc", "cargo"] } [features] -naive_float = [] \ No newline at end of file +naive_float = [] +utoipa = ["dep:utoipa"] diff --git a/common/cosmwasm-smart-contracts/contracts-common/src/types.rs b/common/cosmwasm-smart-contracts/contracts-common/src/types.rs index 320658662e5..456fd45a767 100644 --- a/common/cosmwasm-smart-contracts/contracts-common/src/types.rs +++ b/common/cosmwasm-smart-contracts/contracts-common/src/types.rs @@ -221,6 +221,7 @@ fn default_unknown() -> String { // TODO: there's no reason this couldn't be used for proper binaries, but in that case // perhaps the struct should get renamed and moved to a "more" common crate #[cw_serde] +#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] pub struct ContractBuildInformation { /// Provides the name of the binary, i.e. the content of `CARGO_PKG_NAME` environmental variable. #[serde(default = "default_unknown")] diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/gateway.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/gateway.rs index ed0ee864e80..e21ad52d696 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/gateway.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/gateway.rs @@ -42,9 +42,11 @@ pub struct Gateway { #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] pub struct GatewayBond { /// Original amount pledged by the operator of this node. + #[cfg_attr(feature = "utoipa", schema(value_type = crate::CoinSchema))] pub pledge_amount: Coin, /// Address of the owner of this gateway. + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub owner: Addr, /// Block height at which this gateway has been bonded. @@ -55,6 +57,7 @@ pub struct GatewayBond { /// Entity who bonded this gateway on behalf of the owner. /// If exists, it's most likely the address of the vesting contract. + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub proxy: Option, } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs index bbae58a9358..763082a1f17 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs @@ -82,20 +82,25 @@ impl MixNodeDetails { // currently this struct is shared between mixnodes and nymnodes #[cw_serde] +#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] pub struct NodeRewarding { /// Information provided by the operator that influence the cost function. pub cost_params: NodeCostParams, /// Total pledge and compounded reward earned by the node operator. + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub operator: Decimal, /// Total delegation and compounded reward earned by all node delegators. + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub delegates: Decimal, /// Cumulative reward earned by the "unit delegation" since the block 0. + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub total_unit_reward: Decimal, /// Value of the theoretical "unit delegation" that has delegated to this node at block 0. + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub unit_delegation: Decimal, /// Marks the epoch when this node was last rewarded so that we wouldn't accidentally attempt @@ -492,14 +497,17 @@ impl NodeRewarding { ::cosmwasm_schema::schemars::JsonSchema, )] #[schemars(crate = "::cosmwasm_schema::schemars")] +#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] pub struct MixNodeBond { /// Unique id assigned to the bonded mixnode. pub mix_id: NodeId, /// Address of the owner of this mixnode. + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub owner: Addr, /// Original amount pledged by the operator of this node. + #[cfg_attr(feature = "utoipa", schema(value_type = crate::CoinSchema))] pub original_pledge: Coin, // REMOVED (but might be needed due to legacy things, idk yet) @@ -510,6 +518,7 @@ pub struct MixNodeBond { /// Entity who bonded this mixnode on behalf of the owner. /// If exists, it's most likely the address of the vesting contract. + #[cfg_attr(feature = "utoipa", schema(value_type = Option))] pub proxy: Option, /// Block height at which this mixnode has been bonded. @@ -545,6 +554,7 @@ impl MixNodeBond { feature = "generate-ts", ts(export, export_to = "ts-packages/types/src/types/rust/Mixnode.ts") )] +#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] pub struct MixNode { /// Network address of this mixnode, for example 1.1.1.1 or foo.mixnode.com pub host: String, @@ -571,11 +581,14 @@ pub struct MixNode { /// The cost parameters, or the cost function, defined for the particular mixnode that influences /// how the rewards should be split between the node operator and its delegators. #[cw_serde] +#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] pub struct NodeCostParams { /// The profit margin of the associated node, i.e. the desired percent of the reward to be distributed to the operator. + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub profit_margin_percent: Percent, /// Operating cost of the associated node per the entire interval. + #[cfg_attr(feature = "utoipa", schema(value_type = crate::CoinSchema))] pub interval_operating_cost: Coin, } @@ -680,7 +693,9 @@ pub struct PendingMixNodeChanges { } #[derive(Default, Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)] +#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] pub struct LegacyPendingMixNodeChanges { + #[cfg_attr(feature = "utoipa", schema(value_type = Option))] pub pledge_change: Option, } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/nym_node.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/nym_node.rs index 375fd34374e..4087489cc36 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/nym_node.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/nym_node.rs @@ -231,6 +231,7 @@ pub struct RoleMetadata { /// Full details associated with given node. #[cw_serde] +#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] pub struct NymNodeDetails { /// Basic bond information of this node, such as owner address, original pledge, etc. pub bond_information: NymNodeBond, @@ -288,14 +289,19 @@ impl NymNodeDetails { } #[cw_serde] +#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] pub struct NymNodeBond { /// Unique id assigned to the bonded node. + #[cfg_attr(feature = "utoipa", schema(value_type = u32))] pub node_id: NodeId, /// Address of the owner of this nym-node. + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub owner: Addr, /// Original amount pledged by the operator of this node. + + #[cfg_attr(feature = "utoipa", schema(value_type = crate::CoinSchema))] pub original_pledge: Coin, /// Block height at which this nym-node has been bonded. @@ -348,6 +354,7 @@ impl NymNodeBond { feature = "generate-ts", ts(export, export_to = "ts-packages/types/src/types/rust/NymNode.ts") )] +#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] pub struct NymNode { /// Network address of this nym-node, for example 1.1.1.1 or foo.mixnode.com /// that is used to discover other capabilities of this node. @@ -358,6 +365,7 @@ pub struct NymNode { pub custom_http_port: Option, /// Base58-encoded ed25519 EdDSA public key. + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub identity_key: IdentityKey, // TODO: I don't think we want to include sphinx keys here, // given we want to rotate them and keeping that in sync with contract will be a PITA @@ -435,8 +443,11 @@ pub struct NodeConfigUpdate { export_to = "ts-packages/types/src/types/rust/PendingNodeChanges.ts" ) )] +#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] pub struct PendingNodeChanges { + #[cfg_attr(feature = "utoipa", schema(value_type = Option))] pub pledge_change: Option, + #[cfg_attr(feature = "utoipa", schema(value_type = Option))] pub cost_params_change: Option, } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/reward_params.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/reward_params.rs index 40e34b28889..55bba8f9a60 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/reward_params.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/reward_params.rs @@ -21,31 +21,37 @@ pub type WorkFactor = Decimal; )] #[cw_serde] #[derive(Copy)] +#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] pub struct IntervalRewardParams { /// Current value of the rewarding pool. /// It is expected to be constant throughout the interval. #[cfg_attr(feature = "generate-ts", ts(type = "string"))] + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub reward_pool: Decimal, /// Current value of the staking supply. /// It is expected to be constant throughout the interval. #[cfg_attr(feature = "generate-ts", ts(type = "string"))] + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub staking_supply: Decimal, /// Defines the percentage of stake needed to reach saturation for all of the nodes in the rewarded set. /// Also known as `beta`. #[cfg_attr(feature = "generate-ts", ts(type = "string"))] + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub staking_supply_scale_factor: Percent, // computed values /// Current value of the computed reward budget per epoch, per node. /// It is expected to be constant throughout the interval. #[cfg_attr(feature = "generate-ts", ts(type = "string"))] + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub epoch_reward_budget: Decimal, /// Current value of the stake saturation point. /// It is expected to be constant throughout the interval. #[cfg_attr(feature = "generate-ts", ts(type = "string"))] + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub stake_saturation_point: Decimal, // constants(-ish) @@ -54,6 +60,7 @@ pub struct IntervalRewardParams { /// It is not really expected to be changing very often. /// As a matter of fact, unless there's a very specific reason, it should remain constant. #[cfg_attr(feature = "generate-ts", ts(type = "string"))] + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub sybil_resistance: Percent, // default: 10 @@ -61,6 +68,7 @@ pub struct IntervalRewardParams { /// It is not really expected to be changing very often. /// As a matter of fact, unless there's a very specific reason, it should remain constant. #[cfg_attr(feature = "generate-ts", ts(type = "string"))] + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub active_set_work_factor: Decimal, // default: 2% @@ -70,6 +78,7 @@ pub struct IntervalRewardParams { /// It is not really expected to be changing very often. /// As a matter of fact, unless there's a very specific reason, it should remain constant. #[cfg_attr(feature = "generate-ts", ts(type = "string"))] + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub interval_pool_emission: Percent, } @@ -90,6 +99,7 @@ impl IntervalRewardParams { )] #[cw_serde] #[derive(Copy)] +#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] pub struct RewardingParams { /// Parameters that should remain unchanged throughout an interval. pub interval: IntervalRewardParams, @@ -254,6 +264,7 @@ impl RewardingParams { )] #[cw_serde] #[derive(Copy)] +#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] pub struct RewardedSetParams { /// The expected number of nodes assigned entry gateway role (i.e. [`Role::EntryGateway`]) pub entry_gateways: u32, diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/mod.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/mod.rs index e1c320f806e..ce54caab33f 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/mod.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/mod.rs @@ -17,10 +17,12 @@ pub mod simulator; )] #[cw_serde] #[derive(Copy, Default)] +#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] pub struct RewardEstimate { /// The amount of **decimal** coins that are going to get distributed to the node, /// i.e. the operator and all its delegators. #[cfg_attr(feature = "generate-ts", ts(type = "string"))] + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub total_node_reward: Decimal, // note that operator reward includes the operating_cost, @@ -28,14 +30,17 @@ pub struct RewardEstimate { // in that case the operator reward would still be `1nym` as opposed to 0 /// The share of the reward that is going to get distributed to the node operator. #[cfg_attr(feature = "generate-ts", ts(type = "string"))] + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub operator: Decimal, /// The share of the reward that is going to get distributed among the node delegators. #[cfg_attr(feature = "generate-ts", ts(type = "string"))] + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub delegates: Decimal, /// The operating cost of this node. Note: it's already included in the operator reward. #[cfg_attr(feature = "generate-ts", ts(type = "string"))] + #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub operating_cost: Decimal, } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs index d722f5af938..b3c4e5b2beb 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs @@ -175,6 +175,14 @@ where } } +#[cfg(feature = "utoipa")] +#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] +#[cfg_attr(feature = "utoipa", schema(title = "Coin"))] +pub struct CoinSchema { + pub denom: String, + pub amount: String, +} + /// The current state of the mixnet contract. #[cw_serde] pub struct ContractState { diff --git a/common/credentials-interface/Cargo.toml b/common/credentials-interface/Cargo.toml index 2142acf14a9..f7f957d68bc 100644 --- a/common/credentials-interface/Cargo.toml +++ b/common/credentials-interface/Cargo.toml @@ -16,6 +16,7 @@ serde = { workspace = true, features = ["derive"] } thiserror = { workspace = true } strum = { workspace = true, features = ["derive"] } time = { workspace = true, features = ["serde"] } +utoipa = { workspace = true } rand = { workspace = true } nym-compact-ecash = { path = "../nym_offline_compact_ecash" } diff --git a/common/exit-policy/src/policy/address_policy.rs b/common/exit-policy/src/policy/address_policy.rs index 621fd291e9b..07a1595d934 100644 --- a/common/exit-policy/src/policy/address_policy.rs +++ b/common/exit-policy/src/policy/address_policy.rs @@ -86,7 +86,6 @@ impl Display for AddressPolicyAction { /// ``` #[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq)] #[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] -#[cfg_attr(feature = "openapi", aliases(ExitPolicy))] pub struct AddressPolicy { /// A list of rules to apply to find out whether an address is /// contained by this policy. @@ -727,10 +726,10 @@ mod test { let policy = AddressPolicy::parse_from_torrc( r#" ExitPolicy reject 1.2.3.4/32:* -ExitPolicy reject 1.2.3.5:* +ExitPolicy reject 1.2.3.5:* ExitPolicy reject 1.2.3.6/16:* -ExitPolicy reject 1.2.3.6/16:123-456 -ExitPolicy accept *:53 +ExitPolicy reject 1.2.3.6/16:123-456 +ExitPolicy accept *:53 ExitPolicy accept6 *6:119 ExitPolicy accept *4:120 ExitPolicy reject6 [FC00::]/7:* diff --git a/common/http-api-common/src/lib.rs b/common/http-api-common/src/lib.rs index dbc3bc0125e..ffd258de950 100644 --- a/common/http-api-common/src/lib.rs +++ b/common/http-api-common/src/lib.rs @@ -10,7 +10,6 @@ use serde::{Deserialize, Serialize}; pub mod middleware; #[derive(Debug, Clone)] -#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] pub enum FormattedResponse { Json(Json), Yaml(Yaml), diff --git a/common/nym_offline_compact_ecash/Cargo.toml b/common/nym_offline_compact_ecash/Cargo.toml index 2497edabd9a..5b6e17f2621 100644 --- a/common/nym_offline_compact_ecash/Cargo.toml +++ b/common/nym_offline_compact_ecash/Cargo.toml @@ -63,4 +63,4 @@ par_signing = ["rayon"] # but given it's not done very frequently, it shouldn't be too much of a problem # furthermore, we can't and shouldn't dedicate the entire nym-api CPU just for verification, # but this feature might potentially be desirable for clients. -par_verify = ["rayon"] \ No newline at end of file +par_verify = ["rayon"] diff --git a/common/nym_offline_compact_ecash/src/common_types.rs b/common/nym_offline_compact_ecash/src/common_types.rs index 14f9b1cb663..bc450f97a4e 100644 --- a/common/nym_offline_compact_ecash/src/common_types.rs +++ b/common/nym_offline_compact_ecash/src/common_types.rs @@ -4,10 +4,10 @@ use crate::ecash_group_parameters; use crate::error::Result; use crate::helpers::{g1_tuple_to_bytes, recover_g1_tuple}; -use bls12_381::{G1Projective, Scalar}; use serde::{Deserialize, Serialize}; use subtle::Choice; +pub use bls12_381::{G1Projective, G2Projective, Scalar}; pub type SignerIndex = u64; #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] diff --git a/common/nym_offline_compact_ecash/src/lib.rs b/common/nym_offline_compact_ecash/src/lib.rs index c6346a159f9..77e1ce5199b 100644 --- a/common/nym_offline_compact_ecash/src/lib.rs +++ b/common/nym_offline_compact_ecash/src/lib.rs @@ -36,7 +36,7 @@ pub mod common_types; pub mod constants; pub mod error; mod helpers; -mod proofs; +pub mod proofs; pub mod scheme; pub mod tests; mod traits; diff --git a/common/ticketbooks-merkle/Cargo.toml b/common/ticketbooks-merkle/Cargo.toml index 5b6576da784..3c3f278c6bf 100644 --- a/common/ticketbooks-merkle/Cargo.toml +++ b/common/ticketbooks-merkle/Cargo.toml @@ -14,6 +14,7 @@ readme.workspace = true sha2 = { workspace = true } rs_merkle = { workspace = true } schemars = { workspace = true } +utoipa = { workspace = true } serde = { workspace = true, features = ["derive"] } time = { workspace = true } @@ -23,4 +24,4 @@ nym-serde-helpers = { path = "../serde-helpers", features = ["date", "base64", " [dev-dependencies] rand_chacha = { workspace = true } rand = { workspace = true } -serde_json = { workspace = true } \ No newline at end of file +serde_json = { workspace = true } diff --git a/common/ticketbooks-merkle/src/lib.rs b/common/ticketbooks-merkle/src/lib.rs index f031a3dfc49..acaf0889497 100644 --- a/common/ticketbooks-merkle/src/lib.rs +++ b/common/ticketbooks-merkle/src/lib.rs @@ -14,15 +14,18 @@ use serde::{Deserialize, Serialize}; use sha2::Digest; use std::fmt::{Debug, Formatter}; use time::Date; +use utoipa::ToSchema; // no point in importing the entire contract commons just for this one type pub type DepositId = u32; pub type DKGEpochId = u64; -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, JsonSchema)] +#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, JsonSchema, ToSchema)] #[serde(rename_all = "camelCase")] pub struct IssuedTicketbook { + #[schema(value_type = u32)] pub deposit_id: DepositId, + #[schema(value_type = u32)] pub epoch_id: DKGEpochId, // 96 bytes serialised 'BlindedSignature' @@ -37,9 +40,11 @@ pub struct IssuedTicketbook { #[schemars(with = "String")] #[serde(with = "nym_serde_helpers::date")] + #[schema(value_type = String)] pub expiration_date: Date, #[schemars(with = "String")] + #[schema(value_type = String)] pub ticketbook_type: TicketType, } @@ -80,7 +85,7 @@ pub struct InsertedMerkleLeaf { pub leaf: MerkleLeaf, } -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialOrd, PartialEq, Eq)] +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialOrd, PartialEq, Eq, ToSchema)] pub struct MerkleLeaf { #[schemars(with = "String")] #[serde(with = "nym_serde_helpers::hex")] @@ -162,16 +167,14 @@ impl IssuedTicketbooksMerkleTree { } } -#[derive(Serialize, Deserialize, JsonSchema)] +#[derive(Serialize, Deserialize, JsonSchema, ToSchema)] pub struct IssuedTicketbooksFullMerkleProof { #[schemars(with = "String")] #[serde(with = "inner_proof_base64_serde")] + #[schema(value_type = String)] inner_proof: MerkleProof, - included_leaves: Vec, - total_leaves: usize, - #[schemars(with = "String")] #[serde(with = "nym_serde_helpers::hex")] root: Vec, diff --git a/common/types/Cargo.toml b/common/types/Cargo.toml index 77f30ad7e2e..6ca8a3d9e4c 100644 --- a/common/types/Cargo.toml +++ b/common/types/Cargo.toml @@ -22,6 +22,7 @@ strum = { workspace = true, features = ["derive"] } thiserror = { workspace = true } ts-rs = { workspace = true } url = { workspace = true } +utoipa = { workspace = true } x25519-dalek = { workspace = true, features = ["static_secrets"] } cosmwasm-std = { workspace = true } diff --git a/common/types/src/monitoring.rs b/common/types/src/monitoring.rs index 4768964fc13..09024caaa86 100644 --- a/common/types/src/monitoring.rs +++ b/common/types/src/monitoring.rs @@ -3,6 +3,7 @@ use nym_mixnet_contract_common::NodeId; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::{collections::HashSet, sync::LazyLock, time::SystemTime}; +use utoipa::ToSchema; static NETWORK_MONITORS: LazyLock> = LazyLock::new(|| { let mut nm = HashSet::new(); @@ -10,8 +11,9 @@ static NETWORK_MONITORS: LazyLock> = LazyLock::new(|| { nm }); -#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)] +#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone, ToSchema)] pub struct NodeResult { + #[schema(value_type = u32)] pub node_id: NodeId, pub identity: String, pub reliability: u8, @@ -34,7 +36,7 @@ pub enum MonitorResults { Gateway(Vec), } -#[derive(Serialize, Deserialize, JsonSchema)] +#[derive(Serialize, Deserialize, JsonSchema, ToSchema)] pub struct MonitorMessage { results: Vec, signature: String, diff --git a/deny.toml b/deny.toml index 83982be9527..4da5bf5c592 100644 --- a/deny.toml +++ b/deny.toml @@ -95,6 +95,7 @@ allow = [ "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause", + "BSL-1.0", "ISC", "0BSD", "MPL-2.0", diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 27814af1dba..e931625fdfa 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -105,7 +105,7 @@ nym-gateway-client = { path = "../common/client-libs/gateway-client" } nym-inclusion-probability = { path = "../common/inclusion-probability" } nym-mixnet-contract-common = { path = "../common/cosmwasm-smart-contracts/mixnet-contract", features = ["utoipa"] } nym-vesting-contract-common = { path = "../common/cosmwasm-smart-contracts/vesting-contract" } -nym-contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-common", features = ["naive_float"] } +nym-contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-common", features = ["naive_float", "utoipa"] } nym-multisig-contract-common = { path = "../common/cosmwasm-smart-contracts/multisig-contract" } nym-coconut = { path = "../common/nymcoconut", features = ["key-zeroize"] } nym-sphinx = { path = "../common/nymsphinx" } diff --git a/nym-api/nym-api-requests/Cargo.toml b/nym-api/nym-api-requests/Cargo.toml index 27e70e93619..a67960e1e33 100644 --- a/nym-api/nym-api-requests/Cargo.toml +++ b/nym-api/nym-api-requests/Cargo.toml @@ -31,7 +31,7 @@ nym-crypto = { path = "../../common/crypto", features = ["serde", "asymmetric"] nym-ecash-time = { path = "../../common/ecash-time" } nym-compact-ecash = { path = "../../common/nym_offline_compact_ecash" } nym-contracts-common = { path = "../../common/cosmwasm-smart-contracts/contracts-common", features = ["naive_float"] } -nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" } +nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract", features = ["utoipa"] } nym-node-requests = { path = "../../nym-node/nym-node-requests", default-features = false, features = ["openapi"] } nym-network-defaults = { path = "../../common/network-defaults" } nym-ticketbooks-merkle = { path = "../../common/ticketbooks-merkle" } diff --git a/nym-api/nym-api-requests/src/ecash/models.rs b/nym-api/nym-api-requests/src/ecash/models.rs index ca18f8c15b1..71488b98a56 100644 --- a/nym-api/nym-api-requests/src/ecash/models.rs +++ b/nym-api/nym-api-requests/src/ecash/models.rs @@ -1,7 +1,6 @@ // Copyright 2023-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::helpers::PlaceholderJsonSchemaImpl; use cosmrs::AccountId; use nym_compact_ecash::scheme::coin_indices_signatures::AnnotatedCoinIndexSignature; use nym_compact_ecash::scheme::expiration_date_signatures::AnnotatedExpirationDateSignature; @@ -14,7 +13,6 @@ use nym_credentials_interface::{ }; use nym_crypto::asymmetric::{ed25519, identity}; use nym_ticketbooks_merkle::{IssuedTicketbook, IssuedTicketbooksFullMerkleProof}; -use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use sha2::Digest; use std::collections::BTreeMap; @@ -23,25 +21,25 @@ use thiserror::Error; use time::Date; use utoipa::ToSchema; -#[derive(Serialize, Deserialize, Clone, JsonSchema, ToSchema)] +#[derive(Serialize, Deserialize, Clone, ToSchema)] pub struct VerifyEcashTicketBody { /// The cryptographic material required for spending the underlying credential. - #[schemars(with = "PlaceholderJsonSchemaImpl")] + #[schema(value_type = String)] pub credential: CredentialSpendingData, /// Cosmos address of the sender of the credential - #[schemars(with = "String")] + #[schema(value_type = String)] pub gateway_cosmos_addr: AccountId, } -#[derive(Serialize, Deserialize, Clone, JsonSchema, ToSchema)] +#[derive(Serialize, Deserialize, Clone, ToSchema)] pub struct VerifyEcashCredentialBody { /// The cryptographic material required for spending the underlying credential. - #[schemars(with = "PlaceholderJsonSchemaImpl")] + #[schema(value_type = openapi_schema::CredentialSpendingData)] pub credential: CredentialSpendingData, /// Cosmos address of the sender of the credential - #[schemars(with = "String")] + #[schema(value_type = String)] pub gateway_cosmos_addr: AccountId, /// Multisig proposal for releasing funds for the provided bandwidth credential @@ -62,8 +60,16 @@ impl VerifyEcashCredentialBody { } } -#[derive(Debug, Serialize, Deserialize, JsonSchema, ToSchema)] +/// Used exclusively as part of OpenAPI docs +#[derive(ToSchema)] +pub enum EcashTicketVerificationResult { + Ok(()), + EcashTicketVerificationRejection, +} + +#[derive(Debug, Serialize, Deserialize, ToSchema)] pub struct EcashTicketVerificationResponse { + #[schema(value_type = EcashTicketVerificationResult)] pub verified: Result<(), EcashTicketVerificationRejection>, } @@ -75,18 +81,18 @@ impl EcashTicketVerificationResponse { } } -#[derive(Debug, Error, Serialize, Deserialize, JsonSchema, ToSchema)] +#[derive(Debug, Error, Serialize, Deserialize, ToSchema)] pub enum EcashTicketVerificationRejection { #[error("invalid ticket spent date. expected either today's ({today}) or yesterday's* ({yesterday}) date but got {received} instead\n*assuming it's before 1AM UTC")] InvalidSpentDate { - #[schemars(with = "String")] #[serde(with = "crate::helpers::date_serde")] + #[schema(value_type = String, example = "1970-01-01")] today: Date, - #[schemars(with = "String")] #[serde(with = "crate::helpers::date_serde")] + #[schema(value_type = String, example = "1970-01-01")] yesterday: Date, - #[schemars(with = "String")] #[serde(with = "crate::helpers::date_serde")] + #[schema(value_type = String, example = "1970-01-01")] received: Date, }, @@ -106,26 +112,26 @@ pub enum EcashTicketVerificationRejection { } // All strings are base58 encoded representations of structs -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, JsonSchema, ToSchema)] +#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, ToSchema)] pub struct BlindSignRequestBody { - #[schemars(with = "PlaceholderJsonSchemaImpl")] + #[schema(value_type = openapi_schema::WithdrawalRequest)] pub inner_sign_request: WithdrawalRequest, /// the id of the associated deposit pub deposit_id: u32, /// Signature on the inner sign request and the tx hash - #[schemars(with = "PlaceholderJsonSchemaImpl")] + #[schema(value_type = String)] pub signature: identity::Signature, - #[schemars(with = "PlaceholderJsonSchemaImpl")] + #[schema(value_type = openapi_schema::PublicKeyUser)] pub ecash_pubkey: PublicKeyUser, - #[schemars(with = "String")] #[serde(with = "crate::helpers::date_serde")] + #[schema(value_type = String, example = "1970-01-01")] pub expiration_date: Date, - #[schemars(with = "String")] + #[schema(value_type = String)] pub ticketbook_type: TicketType, } @@ -180,9 +186,9 @@ impl BlindSignRequestBody { } } -#[derive(Debug, Serialize, Deserialize, JsonSchema, ToSchema)] +#[derive(Debug, Serialize, Deserialize, ToSchema)] pub struct BlindedSignatureResponse { - #[schemars(with = "PlaceholderJsonSchemaImpl")] + #[schema(value_type = openapi_schema::BlindedSignature)] pub blinded_signature: BlindedSignature, } @@ -211,9 +217,9 @@ impl BlindedSignatureResponse { } } -#[derive(Serialize, Deserialize, JsonSchema, ToSchema)] +#[derive(Serialize, Deserialize, ToSchema)] pub struct MasterVerificationKeyResponse { - #[schemars(with = "PlaceholderJsonSchemaImpl")] + #[schema(value_type = openapi_schema::VerificationKeyAuth)] pub key: VerificationKeyAuth, } @@ -223,9 +229,9 @@ impl MasterVerificationKeyResponse { } } -#[derive(Serialize, Deserialize, JsonSchema, ToSchema)] +#[derive(Serialize, Deserialize, ToSchema)] pub struct VerificationKeyResponse { - #[schemars(with = "PlaceholderJsonSchemaImpl")] + #[schema(value_type = openapi_schema::VerificationKeyAuth)] pub key: VerificationKeyAuth, } @@ -235,9 +241,8 @@ impl VerificationKeyResponse { } } -#[derive(Serialize, Deserialize, JsonSchema)] +#[derive(Serialize, Deserialize)] pub struct CosmosAddressResponse { - #[schemars(with = "String")] pub addr: AccountId, } @@ -247,45 +252,189 @@ impl CosmosAddressResponse { } } -#[derive(Serialize, Deserialize, JsonSchema, ToSchema)] +#[derive(Serialize, Deserialize, ToSchema)] pub struct PartialExpirationDateSignatureResponse { pub epoch_id: u64, - #[schemars(with = "String")] #[serde(with = "crate::helpers::date_serde")] - #[schema(value_type = String)] + #[schema(value_type = String, example = "1970-01-01")] pub expiration_date: Date, - #[schemars(with = "PlaceholderJsonSchemaImpl")] + #[schema(value_type = openapi_schema::AnnotatedExpirationDateSignature)] pub signatures: Vec, } -#[derive(Serialize, Deserialize, JsonSchema, ToSchema)] +#[derive(Serialize, Deserialize, ToSchema)] pub struct PartialCoinIndicesSignatureResponse { pub epoch_id: u64, - #[schemars(with = "PlaceholderJsonSchemaImpl")] + #[schema(value_type = openapi_schema::AnnotatedCoinIndexSignature)] pub signatures: Vec, } -#[derive(Serialize, Deserialize, JsonSchema, ToSchema)] +#[derive(Serialize, Deserialize, ToSchema)] pub struct AggregatedExpirationDateSignatureResponse { pub epoch_id: u64, - #[schemars(with = "String")] #[serde(with = "crate::helpers::date_serde")] + #[schema(value_type = String, example = "1970-01-01")] pub expiration_date: Date, - #[schemars(with = "PlaceholderJsonSchemaImpl")] + #[schema(value_type = Vec)] pub signatures: Vec, } -#[derive(Serialize, Deserialize, JsonSchema, ToSchema)] +#[derive(Serialize, Deserialize, ToSchema)] pub struct AggregatedCoinIndicesSignatureResponse { pub epoch_id: u64, - #[schemars(with = "PlaceholderJsonSchemaImpl")] + #[schema(value_type = openapi_schema::Signature)] pub signatures: Vec, } -#[derive(Clone, Serialize, Deserialize, Debug, JsonSchema)] +/// duplicate types from `nym-compact-ecash`, but these do derive `ToSchema``` +pub mod openapi_schema { + #![allow(dead_code)] + use nym_compact_ecash::common_types::{G2Projective, Scalar}; + + use super::*; + + #[derive(ToSchema)] + pub struct AnnotatedExpirationDateSignature { + pub signature: Signature, + pub expiration_timestamp: u32, + pub spending_timestamp: u32, + } + + #[derive(ToSchema)] + pub struct AnnotatedCoinIndexSignature { + pub signature: Signature, + pub index: u64, + } + + #[derive(ToSchema)] + pub struct Signature { + #[schema(value_type = String)] + pub(crate) h: G1Projective, + #[schema(value_type = String)] + pub(crate) s: G1Projective, + } + + #[derive(ToSchema)] + pub struct PublicKeyUser { + #[schema(value_type = String)] + pub(crate) pk: G1Projective, + } + + #[derive(ToSchema)] + pub struct BlindedSignature { + #[schema(value_type = String)] + pub h: G1Projective, + #[schema(value_type = String)] + pub c: G1Projective, + } + + #[derive(ToSchema)] + pub struct VerificationKeyAuth { + #[schema(value_type = String)] + pub(crate) alpha: G2Projective, + #[schema(value_type = Vec)] + pub(crate) beta_g1: Vec, + #[schema(value_type = Vec)] + pub(crate) beta_g2: Vec, + } + + #[derive(ToSchema)] + pub struct WithdrawalRequest { + #[schema(value_type = String)] + joined_commitment_hash: G1Projective, + #[schema(value_type = String)] + joined_commitment: G1Projective, + #[schema(value_type = Vec)] + private_attributes_commitments: Vec, + zk_proof: WithdrawalReqProof, + } + + #[derive(ToSchema)] + pub struct WithdrawalReqProof { + #[schema(value_type = String)] + challenge: Scalar, + #[schema(value_type = String)] + response_opening: Scalar, + #[schema(value_type = Vec)] + response_openings: Vec, + #[schema(value_type = Vec)] + response_attributes: Vec, + } + + #[derive(ToSchema)] + pub struct CredentialSpendingData { + pub payment: Payment, + + #[schema(value_type = [u8; 72], format = Binary)] + pub pay_info: PayInfo, + + pub spend_date: Date, + + // pub value: u64, + /// The (DKG) epoch id under which the credential has been issued so that the verifier could use correct verification key for validation. + pub epoch_id: u64, + } + + #[derive(ToSchema)] + pub struct Payment { + #[schema(value_type = String)] + pub kappa: G2Projective, + #[schema(value_type = String)] + pub kappa_e: G2Projective, + pub sig: Signature, + + pub sig_exp: Signature, + #[schema(value_type = Vec)] + pub kappa_k: Vec, + pub omega: Vec, + #[schema(value_type = Vec)] + pub ss: Vec, + #[schema(value_type = Vec)] + pub tt: Vec, + #[schema(value_type = Vec)] + pub aa: Vec, + pub spend_value: u64, + #[schema(value_type = String)] + pub cc: G1Projective, + pub t_type: u8, + pub zk_proof: SpendProof, + } + + #[derive(PartialEq, Eq, Debug, Clone, Copy, ToSchema)] + pub struct PayInfo { + #[schema(content_encoding = "base16")] + pub pay_info_bytes: [u8; 72], + } + + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ToSchema)] + pub struct SpendProof { + #[schema(value_type = String)] + challenge: Scalar, + #[schema(value_type = String)] + response_r: Scalar, + #[schema(value_type = String)] + response_r_e: Scalar, + #[schema(value_type = Vec)] + responses_r_k: Vec, + #[schema(value_type = Vec)] + responses_l: Vec, + #[schema(value_type = Vec)] + responses_o_a: Vec, + #[schema(value_type = String)] + response_o_c: Scalar, + #[schema(value_type = Vec)] + responses_mu: Vec, + #[schema(value_type = Vec)] + responses_o_mu: Vec, + #[schema(value_type = Vec)] + responses_attributes: Vec, + } +} + +#[derive(Clone, Serialize, Deserialize, Debug)] pub struct Pagination { /// last_key is the last value returned in the previous query. /// it's used to indicate the start of the next (this) page. @@ -297,12 +446,8 @@ pub struct Pagination { pub limit: Option, } -#[derive(Clone, Serialize, Deserialize, Debug, JsonSchema, PartialEq)] -pub struct SerialNumberWrapper( - #[serde(with = "nym_serde_helpers::bs58")] - #[schemars(with = "String")] - Vec, -); +#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, ToSchema)] +pub struct SerialNumberWrapper(#[serde(with = "nym_serde_helpers::bs58")] Vec); impl Deref for SerialNumberWrapper { type Target = Vec; @@ -323,14 +468,13 @@ impl From> for SerialNumberWrapper { } } -#[derive(Clone, Serialize, Deserialize, Debug, JsonSchema, PartialEq)] +#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, ToSchema)] pub struct BatchRedeemTicketsBody { #[serde(with = "nym_serde_helpers::bs58")] - #[schemars(with = "String")] pub digest: Vec, pub included_serial_numbers: Vec, pub proposal_id: u64, - #[schemars(with = "String")] + #[schema(value_type = String)] pub gateway_cosmos_addr: AccountId, } @@ -366,16 +510,15 @@ impl BatchRedeemTicketsBody { } } -#[derive(Debug, Serialize, Deserialize, JsonSchema, ToSchema)] +#[derive(Debug, Serialize, Deserialize, ToSchema)] pub struct EcashBatchTicketRedemptionResponse { pub proposal_accepted: bool, } -#[derive(Clone, Serialize, Deserialize, Debug, JsonSchema, ToSchema)] +#[derive(Clone, Serialize, Deserialize, Debug, ToSchema)] #[serde(rename_all = "camelCase")] pub struct SpentCredentialsResponse { #[serde(with = "nym_serde_helpers::base64")] - #[schemars(with = "String")] #[schema(value_type = String)] pub bitmap: Vec, } @@ -388,18 +531,19 @@ impl SpentCredentialsResponse { pub type DepositId = u32; -#[derive(Clone, Serialize, Deserialize, Debug, JsonSchema, ToSchema, PartialEq, Eq)] +#[derive(Clone, Serialize, Deserialize, Debug, ToSchema, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct CommitedDeposit { + #[schema(value_type = u32)] pub deposit_id: DepositId, pub merkle_index: usize, } -#[derive(Clone, Serialize, Deserialize, Debug, JsonSchema, ToSchema)] +#[derive(Clone, Serialize, Deserialize, Debug, ToSchema)] #[serde(rename_all = "camelCase")] pub struct IssuedTicketbooksForResponseBody { - #[schemars(with = "String")] #[serde(with = "crate::helpers::date_serde")] + #[schema(value_type = String, example = "1970-01-01")] pub expiration_date: Date, pub deposits: Vec, pub merkle_root: Option<[u8; 32]>, @@ -419,13 +563,13 @@ impl IssuedTicketbooksForResponseBody { } } -#[derive(Clone, Serialize, Deserialize, Debug, JsonSchema, ToSchema)] +#[derive(Clone, Serialize, Deserialize, Debug, ToSchema)] #[serde(rename_all = "camelCase")] pub struct IssuedTicketbooksForResponse { pub body: IssuedTicketbooksForResponseBody, - /// Signature on the body - #[schemars(with = "PlaceholderJsonSchemaImpl")] + /// Signature on the body + #[schema(value_type = String)] pub signature: identity::Signature, } @@ -437,22 +581,24 @@ impl IssuedTicketbooksForResponse { } } -#[derive(Serialize, Deserialize, JsonSchema, ToSchema, Debug)] +#[derive(Serialize, Deserialize, ToSchema, Debug)] #[serde(rename_all = "camelCase")] pub struct IssuedTicketbooksChallengeRequest { - #[schemars(with = "String")] #[serde(with = "crate::helpers::date_serde")] + #[schema(value_type = String, example = "1970-01-01")] pub expiration_date: Date, + #[schema(value_type = Vec)] pub deposits: Vec, } -#[derive(Serialize, Deserialize, JsonSchema, ToSchema, Clone, Debug)] +#[derive(Serialize, Deserialize, ToSchema, Clone, Debug)] #[serde(rename_all = "camelCase")] pub struct IssuedTicketbooksChallengeResponseBody { - #[schemars(with = "String")] #[serde(with = "crate::helpers::date_serde")] + #[schema(value_type = String, example = "1970-01-01")] pub expiration_date: Date, + #[schema(value_type = BTreeMap)] pub partial_ticketbooks: BTreeMap, pub merkle_proof: IssuedTicketbooksFullMerkleProof, } @@ -486,12 +632,12 @@ impl IssuedTicketbooksChallengeResponseBody { } } -#[derive(Serialize, Deserialize, JsonSchema, ToSchema, Clone, Debug)] +#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct IssuedTicketbooksChallengeResponse { pub body: IssuedTicketbooksChallengeResponseBody, - #[schemars(with = "PlaceholderJsonSchemaImpl")] + #[schema(value_type = String)] pub signature: identity::Signature, } diff --git a/nym-api/nym-api-requests/src/legacy.rs b/nym-api/nym-api-requests/src/legacy.rs index f0810ffa8ee..cf1250653f8 100644 --- a/nym-api/nym-api-requests/src/legacy.rs +++ b/nym-api/nym-api-requests/src/legacy.rs @@ -52,7 +52,7 @@ impl From for MixNodeBond { } } -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, ToSchema)] pub struct LegacyMixNodeDetailsWithLayer { /// Basic bond information of this mixnode, such as owner address, original pledge, etc. pub bond_information: LegacyMixNodeBondWithLayer, diff --git a/nym-api/nym-api-requests/src/models.rs b/nym-api/nym-api-requests/src/models.rs index 720553ccf3e..ba5d6a94b25 100644 --- a/nym-api/nym-api-requests/src/models.rs +++ b/nym-api/nym-api-requests/src/models.rs @@ -72,7 +72,7 @@ impl Display for RequestError { } } -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] +#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, ToSchema)] #[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] #[cfg_attr( feature = "generate-ts", @@ -145,7 +145,7 @@ pub struct NodePerformance { pub last_24h: Performance, } -#[derive(Serialize, Deserialize, Debug, Clone, Copy, Hash, JsonSchema)] +#[derive(Serialize, Deserialize, Debug, Clone, Copy, Hash, JsonSchema, ToSchema)] #[serde(rename_all = "camelCase")] #[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] #[cfg_attr( @@ -190,7 +190,7 @@ impl From for Role { // imo for now there's no point in exposing more than that, // nym-api shouldn't be calculating apy or stake saturation for you. // it should just return its own metrics (performance) and then you can do with it as you wish -#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema)] +#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema, ToSchema)] #[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] #[cfg_attr( feature = "generate-ts", @@ -202,13 +202,14 @@ impl From for Role { pub struct NodeAnnotation { #[cfg_attr(feature = "generate-ts", ts(type = "string"))] // legacy + #[schema(value_type = String)] pub last_24h_performance: Performance, pub current_role: Option, pub detailed_performance: DetailedNodePerformance, } -#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema)] +#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema, ToSchema)] #[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] #[cfg_attr( feature = "generate-ts", @@ -244,7 +245,7 @@ impl DetailedNodePerformance { } } -#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema)] +#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema, ToSchema)] #[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] #[cfg_attr( feature = "generate-ts", @@ -266,7 +267,7 @@ impl RoutingScore { } } -#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema)] +#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema, ToSchema)] #[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] #[cfg_attr( feature = "generate-ts", @@ -397,12 +398,15 @@ pub struct MixNodeBondAnnotated { #[schema(value_type = String)] pub performance: Performance, pub node_performance: NodePerformance, + #[schema(value_type = String)] pub estimated_operator_apy: Decimal, + #[schema(value_type = String)] pub estimated_delegators_apy: Decimal, pub blacklisted: bool, // a rather temporary thing until we query self-described endpoints of mixnodes #[serde(default)] + #[schema(value_type = Vec)] pub ip_addresses: Vec, } @@ -471,11 +475,13 @@ pub struct GatewayBondAnnotated { pub self_described: Option, // NOTE: the performance field is deprecated in favour of node_performance + #[schema(value_type = String)] pub performance: Performance, pub node_performance: NodePerformance, pub blacklisted: bool, #[serde(default)] + #[schema(value_type = Vec)] pub ip_addresses: Vec, } @@ -526,21 +532,24 @@ impl GatewayBondAnnotated { } } -#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] +#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, ToSchema)] pub struct GatewayDescription { // for now only expose what we need. this struct will evolve in the future (or be incorporated into nym-node properly) } #[derive(Debug, Serialize, Deserialize, JsonSchema, ToSchema, IntoParams)] pub struct ComputeRewardEstParam { - #[schema(value_type = String)] + #[schema(value_type = Option)] + #[param(value_type = Option)] pub performance: Option, pub active_in_rewarded_set: Option, pub pledge_amount: Option, pub total_delegation: Option, - #[schema(value_type = CoinSchema)] + #[schema(value_type = Option)] + #[param(value_type = Option)] pub interval_operating_cost: Option, - #[schema(value_type = String)] + #[schema(value_type = Option)] + #[param(value_type = Option)] pub profit_margin_percent: Option, } @@ -698,8 +707,11 @@ pub struct MixnodeStatusReportResponse { pub mix_id: NodeId, pub identity: IdentityKey, pub owner: String, + #[schema(value_type = u8)] pub most_recent: Uptime, + #[schema(value_type = u8)] pub last_hour: Uptime, + #[schema(value_type = u8)] pub last_day: Uptime, } @@ -825,6 +837,7 @@ pub struct CirculatingSupplyResponse { #[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, ToSchema)] pub struct HostInformation { + #[schema(value_type = Vec)] pub ip_address: Vec, pub hostname: Option, pub keys: HostKeys, @@ -844,15 +857,18 @@ impl From for HostInf pub struct HostKeys { #[serde(with = "bs58_ed25519_pubkey")] #[schemars(with = "String")] + #[schema(value_type = String)] pub ed25519: ed25519::PublicKey, #[serde(with = "bs58_x25519_pubkey")] #[schemars(with = "String")] + #[schema(value_type = String)] pub x25519: x25519::PublicKey, #[serde(default)] #[serde(with = "option_bs58_x25519_pubkey")] #[schemars(with = "Option")] + #[schema(value_type = String)] pub x25519_noise: Option, } @@ -896,6 +912,7 @@ pub struct OffsetDateTimeJsonSchemaWrapper( default = "unix_epoch", with = "crate::helpers::overengineered_offset_date_time_serde" )] + #[schema(inline)] pub OffsetDateTime, ); @@ -1233,13 +1250,13 @@ pub struct SignerInformationResponse { pub verification_key: Option, } -#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, Default)] +#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, Default, ToSchema)] pub struct TestNode { pub node_id: Option, pub identity_key: Option, } -#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema)] +#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, ToSchema)] pub struct TestRoute { pub gateway: TestNode, pub layer1: TestNode, @@ -1274,10 +1291,12 @@ pub struct NetworkMonitorRunDetailsResponse { pub struct NoiseDetails { #[schemars(with = "String")] #[serde(with = "bs58_x25519_pubkey")] + #[schema(value_type = String)] pub x25119_pubkey: x25519::PublicKey, pub mixnet_port: u16, + #[schema(value_type = Vec)] pub ip_addresses: Vec, } @@ -1285,12 +1304,14 @@ pub struct NoiseDetails { pub struct NodeRefreshBody { #[serde(with = "bs58_ed25519_pubkey")] #[schemars(with = "String")] + #[schema(value_type = String)] pub node_identity: ed25519::PublicKey, // a poor man's nonce pub request_timestamp: i64, #[schemars(with = "PlaceholderJsonSchemaImpl")] + #[schema(value_type = String)] pub signature: ed25519::Signature, } diff --git a/nym-api/nym-api-requests/src/nym_nodes.rs b/nym-api/nym-api-requests/src/nym_nodes.rs index d8574e36d5f..2d91940fe49 100644 --- a/nym-api/nym-api-requests/src/nym_nodes.rs +++ b/nym-api/nym-api-requests/src/nym_nodes.rs @@ -14,19 +14,19 @@ use std::net::IpAddr; use time::OffsetDateTime; use utoipa::ToSchema; -#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema)] -pub struct CachedNodesResponse { +#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, ToSchema)] +pub struct CachedNodesResponse { pub refreshed_at: OffsetDateTimeJsonSchemaWrapper, pub nodes: Vec, } -impl From> for CachedNodesResponse { +impl From> for CachedNodesResponse { fn from(nodes: Vec) -> Self { CachedNodesResponse::new(nodes) } } -impl CachedNodesResponse { +impl CachedNodesResponse { pub fn new(nodes: Vec) -> Self { CachedNodesResponse { refreshed_at: OffsetDateTime::now_utc().into(), @@ -130,6 +130,7 @@ pub struct SkimmedNode { #[serde(with = "bs58_ed25519_pubkey")] #[schemars(with = "String")] + #[schema(value_type = String)] pub ed25519_identity_pubkey: ed25519::PublicKey, #[schema(value_type = Vec)] @@ -139,6 +140,7 @@ pub struct SkimmedNode { #[serde(with = "bs58_x25519_pubkey")] #[schemars(with = "String")] + #[schema(value_type = String)] pub x25519_sphinx_pubkey: x25519::PublicKey, #[serde(alias = "epoch_role")] diff --git a/nym-api/redocly/.redocly.lint-ignore.yaml b/nym-api/redocly/.redocly.lint-ignore.yaml new file mode 100644 index 00000000000..4cd758f99fd --- /dev/null +++ b/nym-api/redocly/.redocly.lint-ignore.yaml @@ -0,0 +1,47 @@ +# This file instructs Redocly's linter to ignore the rules contained for specific parts of your API. +# See https://redocly.com/docs/cli/ for more information. +formatted-openapi.json: + path-parameters-defined: + - >- + #/paths/~1v1~1status~1mixnode~1{mix_id}~1compute-reward-estimation/post/parameters/0/name + - >- + #/paths/~1v1~1status~1mixnode~1{mix_id}~1compute-reward-estimation/post/parameters/1/name + - >- + #/paths/~1v1~1status~1mixnode~1{mix_id}~1compute-reward-estimation/post/parameters/2/name + - >- + #/paths/~1v1~1status~1mixnode~1{mix_id}~1compute-reward-estimation/post/parameters/3/name + - >- + #/paths/~1v1~1status~1mixnode~1{mix_id}~1compute-reward-estimation/post/parameters/4/name + - >- + #/paths/~1v1~1status~1mixnode~1{mix_id}~1compute-reward-estimation/post/parameters/5/name + operation-operationId-unique: + - >- + #/paths/~1v1~1status~1mixnodes~1active~1detailed/get/get_active_set_detailed + - '#/paths/~1v1~1status~1mixnodes~1detailed/get/get_mixnodes_detailed' + - >- + #/paths/~1v1~1status~1mixnodes~1rewarded~1detailed/get/get_rewarded_set_detailed + no-unused-components: + - '#/components/schemas/AxumErrorResponse' + - '#/components/schemas/DateQuery' + - '#/components/schemas/EcashTicketVerificationRejection' + - '#/components/schemas/ExpirationDatePathParam' + - '#/components/schemas/FullFatNode' + - '#/components/schemas/G2ProjectiveSchema' + - '#/components/schemas/HistoricalPerformanceResponse' + - '#/components/schemas/HistoricalUptimeResponse' + - '#/components/schemas/MasterVerificationKeyResponse' + - '#/components/schemas/MixnodeStatusReport' + - '#/components/schemas/NodeId' + - '#/components/schemas/NodeRoleQueryParam' + - '#/components/schemas/NoiseDetails' + - '#/components/schemas/NymNodeDescription' + - '#/components/schemas/NymNodeDetails' + - '#/components/schemas/PaginationRequest' + - '#/components/schemas/PartialCoinIndicesSignatureResponse' + - '#/components/schemas/PayInfo' + - '#/components/schemas/SpentCredentialsResponse' + - '#/components/schemas/UptimeHistoryResponse' + - '#/components/schemas/VerifyEcashCredentialBody' + - '#/components/responses/AxumErrorResponse' + - '#/components/responses/CirculatingSupplyResponse' + - '#/components/responses/RequestError' diff --git a/nym-api/redocly/.redocly.yaml b/nym-api/redocly/.redocly.yaml new file mode 100644 index 00000000000..99a71053f0e --- /dev/null +++ b/nym-api/redocly/.redocly.yaml @@ -0,0 +1,12 @@ +extends: + - minimal +apis: + nym-api: + root: ./formatted-openapi.json +rules: + # https://redocly.com/docs/cli/rules/oas/operation-summary + operation-summary: off + # https://redocly.com/docs/cli/rules/oas/security-defined + security-defined: off + # https://redocly.com/docs/cli/rules/oas/operation-2xx-response + operation-2xx-response: off diff --git a/nym-api/redocly/readme.MD b/nym-api/redocly/readme.MD new file mode 100644 index 00000000000..79ac2fbb9fa --- /dev/null +++ b/nym-api/redocly/readme.MD @@ -0,0 +1,27 @@ +# Test / validate OpenAPI spec + +`redocly` CLI is an [OpenAPI linter][docs] that enforces good practices by +checking whether a series of lints are applied to your OpenAPI spec. + +## Install + +You need `npm` and `npx` ([official instructions][instructions]) + +## Run + +``` +./redocly.sh +``` + +## Configuration + +- redocly.yaml is the main [config file](https://redocly.com/docs/redoc/config) + +## Ignore file + +- specifies lints to ignore (some lints may be false alarms/not applicable) +- if you want to add current CLI warnings to an ignore file, run redocly CLI + with `--generate-ignore-file` + +[docs]: https://redocly.com/docs/redoc +[instructions]: https://redocly.com/docs/cli/installation diff --git a/nym-api/redocly/redocly.sh b/nym-api/redocly/redocly.sh new file mode 100755 index 00000000000..4e7d67693d0 --- /dev/null +++ b/nym-api/redocly/redocly.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +curl -s http://localhost:8000/api-docs/openapi.json | jq . > formatted-openapi.json +npx @redocly/cli@latest lint --config .redocly.yaml \ + # --generate-ignore-file diff --git a/nym-api/src/ecash/api_routes/issued.rs b/nym-api/src/ecash/api_routes/issued.rs index 376b5324753..8c2fe10053a 100644 --- a/nym-api/src/ecash/api_routes/issued.rs +++ b/nym-api/src/ecash/api_routes/issued.rs @@ -48,7 +48,7 @@ pub(crate) struct ExpirationDatePathParam { context_path = "/v1/ecash", responses( (status = 200, body = IssuedTicketbooksForResponse), - (status = 400, body = ErrorResponse, description = "this nym-api is not an ecash signer in the current epoch"), + (status = 400, body = String, description = "this nym-api is not an ecash signer in the current epoch"), ) )] async fn issued_ticketbooks_for( @@ -73,7 +73,7 @@ async fn issued_ticketbooks_for( context_path = "/v1/ecash", responses( (status = 200, body = IssuedTicketbooksChallengeResponse), - (status = 400, body = ErrorResponse, description = "this nym-api is not an ecash signer in the current epoch"), + (status = 400, body = String, description = "this nym-api is not an ecash signer in the current epoch"), ) )] async fn issued_ticketbooks_challenge( diff --git a/nym-api/src/ecash/api_routes/partial_signing.rs b/nym-api/src/ecash/api_routes/partial_signing.rs index afe522cbee1..b5d53a5ed0f 100644 --- a/nym-api/src/ecash/api_routes/partial_signing.rs +++ b/nym-api/src/ecash/api_routes/partial_signing.rs @@ -42,7 +42,7 @@ pub(crate) fn partial_signing_routes() -> Router { path = "/v1/ecash/blind-sign", responses( (status = 200, body = BlindedSignatureResponse), - (status = 400, body = ErrorResponse, description = "this nym-api is not an ecash signer in the current epoch"), + (status = 400, body = String, description = "this nym-api is not an ecash signer in the current epoch"), ) )] @@ -118,7 +118,7 @@ struct ExpirationDateParam { path = "/v1/ecash/partial-expiration-date-signatures", responses( (status = 200, body = PartialExpirationDateSignatureResponse), - (status = 400, body = ErrorResponse, description = "this nym-api is not an ecash signer in the current epoch"), + (status = 400, body = String, description = "this nym-api is not an ecash signer in the current epoch"), ) )] async fn partial_expiration_date_signatures( @@ -156,7 +156,7 @@ async fn partial_expiration_date_signatures( path = "/v1/ecash/partial-coin-indices-signatures", responses( (status = 200, body = PartialExpirationDateSignatureResponse), - (status = 400, body = ErrorResponse, description = "this nym-api is not an ecash signer in the current epoch"), + (status = 400, body = String, description = "this nym-api is not an ecash signer in the current epoch"), ) )] async fn partial_coin_indices_signatures( diff --git a/nym-api/src/ecash/api_routes/spending.rs b/nym-api/src/ecash/api_routes/spending.rs index f52aeda2eb0..873d9044d05 100644 --- a/nym-api/src/ecash/api_routes/spending.rs +++ b/nym-api/src/ecash/api_routes/spending.rs @@ -52,7 +52,7 @@ fn reject_ticket( path = "/v1/ecash/verify-ecash-ticket", responses( (status = 200, body = EcashTicketVerificationResponse), - (status = 400, body = ErrorResponse, description = "this nym-api is not an ecash signer in the current epoch"), + (status = 400, body = String, description = "this nym-api is not an ecash signer in the current epoch"), ) )] async fn verify_ticket( @@ -155,7 +155,7 @@ async fn verify_ticket( path = "/v1/ecash/batch-redeem-ecash-tickets", responses( (status = 200, body = EcashBatchTicketRedemptionResponse), - (status = 400, body = ErrorResponse, description = "this nym-api is not an ecash signer in the current epoch"), + (status = 400, body = String, description = "this nym-api is not an ecash signer in the current epoch"), ) )] async fn batch_redeem_tickets( @@ -235,7 +235,7 @@ async fn batch_redeem_tickets( get, path = "/v1/ecash/double-spending-filter-v1", responses( - (status = 500, body = ErrorResponse, description = "bloomfilters got disabled"), + (status = 500, body = String, description = "bloomfilters got disabled"), ) )] #[deprecated] diff --git a/nym-api/src/network/handlers.rs b/nym-api/src/network/handlers.rs index 7bb77bc3fcc..ff398a16cbf 100644 --- a/nym-api/src/network/handlers.rs +++ b/nym-api/src/network/handlers.rs @@ -47,12 +47,19 @@ pub(crate) struct ContractVersionSchemaResponse { pub version: String, } +#[allow(dead_code)] // not dead, used in OpenAPI docs +#[derive(ToSchema)] +pub struct ContractInformationContractVersion { + pub(crate) address: Option, + pub(crate) details: Option, +} + #[utoipa::path( tag = "network", get, path = "/v1/network/nym-contracts", responses( - (status = 200, body = HashMap>) + (status = 200, body = HashMap) ) )] async fn nym_contracts( @@ -73,12 +80,19 @@ async fn nym_contracts( .into() } +#[allow(dead_code)] // not dead, used in OpenAPI docs +#[derive(ToSchema)] +pub struct ContractInformationBuildInformation { + pub(crate) address: Option, + pub(crate) details: Option, +} + #[utoipa::path( tag = "network", get, path = "/v1/network/nym-contracts-detailed", responses( - (status = 200, body = HashMap>) + (status = 200, body = HashMap) ) )] async fn nym_contracts_detailed( diff --git a/nym-api/src/network/models.rs b/nym-api/src/network/models.rs index 66d0324c26b..1819ce024d8 100644 --- a/nym-api/src/network/models.rs +++ b/nym-api/src/network/models.rs @@ -4,8 +4,9 @@ use nym_config::defaults::NymNetworkDetails; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +use utoipa::ToSchema; -#[derive(Clone, Serialize, Deserialize, JsonSchema, utoipa::ToSchema)] +#[derive(Clone, Serialize, Deserialize, JsonSchema, ToSchema)] pub struct NetworkDetails { pub(crate) connected_nyxd: String, pub(crate) network: NymNetworkDetails, @@ -20,7 +21,7 @@ impl NetworkDetails { } } -#[derive(Clone, Serialize, Deserialize, JsonSchema, utoipa::ToSchema)] +#[derive(Clone, Serialize, Deserialize, JsonSchema, ToSchema)] #[serde(rename_all = "snake_case")] pub struct ContractInformation { pub(crate) address: Option, diff --git a/nym-api/src/node_status_api/handlers/without_monitor.rs b/nym-api/src/node_status_api/handlers/without_monitor.rs index 4aaa6f8253e..e364e1ee312 100644 --- a/nym-api/src/node_status_api/handlers/without_monitor.rs +++ b/nym-api/src/node_status_api/handlers/without_monitor.rs @@ -1,6 +1,8 @@ // Copyright 2021-2024 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only +// we want to mark the routes as deprecated in swagger, but still expose them +#![allow(deprecated)] use crate::node_status_api::handlers::MixIdParam; use crate::node_status_api::helpers::{ _get_active_set_legacy_mixnodes_detailed, _get_legacy_mixnodes_detailed, @@ -20,8 +22,6 @@ use nym_mixnet_contract_common::NodeId; use nym_types::monitoring::MonitorMessage; use tracing::error; -// we want to mark the routes as deprecated in swagger, but still expose them -#[allow(deprecated)] pub(super) fn mandatory_routes() -> Router { Router::new() .route( @@ -63,9 +63,9 @@ pub(super) fn mandatory_routes() -> Router { path = "/v1/status/submit-gateway-monitoring-results", responses( (status = 200), - (status = 400, body = ErrorResponse, description = "TBD"), - (status = 403, body = ErrorResponse, description = "TBD"), - (status = 500, body = ErrorResponse, description = "TBD"), + (status = 400, body = String, description = "TBD"), + (status = 403, body = String, description = "TBD"), + (status = 500, body = String, description = "TBD"), ), )] pub(crate) async fn submit_gateway_monitoring_results( @@ -107,9 +107,9 @@ pub(crate) async fn submit_gateway_monitoring_results( path = "/v1/status/submit-node-monitoring-results", responses( (status = 200), - (status = 400, body = ErrorResponse, description = "TBD"), - (status = 403, body = ErrorResponse, description = "TBD"), - (status = 500, body = ErrorResponse, description = "TBD"), + (status = 400, body = String, description = "TBD"), + (status = 403, body = String, description = "TBD"), + (status = 500, body = String, description = "TBD"), ), )] pub(crate) async fn submit_node_monitoring_results( @@ -198,7 +198,7 @@ async fn get_mixnode_stake_saturation( ), path = "/v1/status/mixnode/{mix_id}/inclusion-probability", responses( - (status = 200, body = InclusionProbabilityResponse) + (status = 200, body = nym_api_requests::models::InclusionProbabilityResponse) ) )] #[deprecated] @@ -217,7 +217,7 @@ async fn get_mixnode_inclusion_probability( get, path = "/v1/status/mixnodes/inclusion-probability", responses( - (status = 200, body = AllInclusionProbabilitiesResponse) + (status = 200, body = nym_api_requests::models::AllInclusionProbabilitiesResponse) ) )] #[deprecated] diff --git a/nym-api/src/node_status_api/models.rs b/nym-api/src/node_status_api/models.rs index 958188db9d9..2e33fd80253 100644 --- a/nym-api/src/node_status_api/models.rs +++ b/nym-api/src/node_status_api/models.rs @@ -22,6 +22,7 @@ use std::fmt::Display; use thiserror::Error; use time::{Date, OffsetDateTime}; use tracing::error; +use utoipa::ToSchema; #[derive(Error, Debug)] #[error("Received uptime value was within 0-100 range (got {received})")] @@ -128,14 +129,17 @@ impl From for Performance { } } -#[derive(Clone, Serialize, Deserialize, Debug, JsonSchema)] +#[derive(Clone, Serialize, Deserialize, Debug, JsonSchema, ToSchema)] pub struct MixnodeStatusReport { + #[schema(value_type = u32)] pub(crate) mix_id: NodeId, + #[schema(value_type = String)] pub(crate) identity: IdentityKey, - + #[schema(value_type = u8)] pub(crate) most_recent: Uptime, - + #[schema(value_type = u8)] pub(crate) last_hour: Uptime, + #[schema(value_type = u8)] pub(crate) last_day: Uptime, } @@ -315,8 +319,12 @@ impl From for OldHistoricalUptimeResponse { // TODO rocket remove smurf name after eliminating `rocket` pub(crate) type AxumResult = Result; + +// #[derive(ToSchema, ToResponse)] +// #[schema(title = "ErrorResponse")] pub(crate) struct AxumErrorResponse { message: RequestError, + // #[schema(value_type = u16)] status: StatusCode, } diff --git a/nym-api/src/nym_nodes/handlers/legacy.rs b/nym-api/src/nym_nodes/handlers/legacy.rs index 3dd6a51f741..3262f997c1e 100644 --- a/nym-api/src/nym_nodes/handlers/legacy.rs +++ b/nym-api/src/nym_nodes/handlers/legacy.rs @@ -27,7 +27,7 @@ pub(crate) fn legacy_nym_node_routes() -> Router { get, path = "/v1/gateways/described", responses( - (status = 200, body = Vec) + (status = 200, body = Vec) ) )] #[deprecated] @@ -81,7 +81,7 @@ async fn get_gateways_described( get, path = "/v1/mixnodes/described", responses( - (status = 200, body = Vec) + (status = 200, body = Vec) ) )] #[deprecated] diff --git a/nym-api/src/nym_nodes/handlers/unstable/full_fat.rs b/nym-api/src/nym_nodes/handlers/unstable/full_fat.rs index d16d68e240b..debc2842081 100644 --- a/nym-api/src/nym_nodes/handlers/unstable/full_fat.rs +++ b/nym-api/src/nym_nodes/handlers/unstable/full_fat.rs @@ -12,7 +12,7 @@ use nym_api_requests::nym_nodes::{CachedNodesResponse, FullFatNode}; tag = "Unstable Nym Nodes", get, params(NodesParamsWithRole), - path = "/", + path = "", context_path = "/v1/unstable/nym-nodes/full-fat", responses( // (status = 200, body = CachedNodesResponse) diff --git a/nym-api/src/nym_nodes/handlers/unstable/mod.rs b/nym-api/src/nym_nodes/handlers/unstable/mod.rs index 88d0338e6f4..c629834919d 100644 --- a/nym-api/src/nym_nodes/handlers/unstable/mod.rs +++ b/nym-api/src/nym_nodes/handlers/unstable/mod.rs @@ -88,6 +88,7 @@ struct NodesParamsWithRole { } #[derive(Debug, Deserialize, utoipa::IntoParams)] +#[into_params(parameter_in = Query)] struct NodesParams { #[allow(dead_code)] semver_compatibility: Option, diff --git a/nym-api/src/nym_nodes/handlers/unstable/semi_skimmed.rs b/nym-api/src/nym_nodes/handlers/unstable/semi_skimmed.rs index 294ec222e53..e8b9ffb2bcd 100644 --- a/nym-api/src/nym_nodes/handlers/unstable/semi_skimmed.rs +++ b/nym-api/src/nym_nodes/handlers/unstable/semi_skimmed.rs @@ -12,7 +12,7 @@ use nym_api_requests::nym_nodes::{CachedNodesResponse, SemiSkimmedNode}; tag = "Unstable Nym Nodes", get, params(NodesParamsWithRole), - path = "/", + path = "", context_path = "/v1/unstable/nym-nodes/semi-skimmed", responses( // (status = 200, body = CachedNodesResponse) diff --git a/nym-api/src/nym_nodes/handlers/unstable/skimmed.rs b/nym-api/src/nym_nodes/handlers/unstable/skimmed.rs index b46234082eb..9d712d04628 100644 --- a/nym-api/src/nym_nodes/handlers/unstable/skimmed.rs +++ b/nym-api/src/nym_nodes/handlers/unstable/skimmed.rs @@ -9,16 +9,20 @@ use crate::support::caching::Cache; use crate::support::http::state::AppState; use axum::extract::{Query, State}; use axum::Json; -use nym_api_requests::models::{NodeAnnotation, NymNodeDescription}; +use nym_api_requests::models::{ + NodeAnnotation, NymNodeDescription, OffsetDateTimeJsonSchemaWrapper, +}; use nym_api_requests::nym_nodes::{ CachedNodesResponse, NodeRole, NodeRoleQueryParam, PaginatedCachedNodesResponse, SkimmedNode, }; +use nym_api_requests::pagination::PaginatedResponse; use nym_mixnet_contract_common::NodeId; use nym_topology::CachedEpochRewardedSet; use std::collections::HashMap; use std::future::Future; use tokio::sync::RwLockReadGuard; use tracing::trace; +use utoipa::ToSchema; pub type PaginatedSkimmedNodes = AxumResult>>; @@ -270,16 +274,25 @@ async fn nodes_basic( ))) } +#[allow(dead_code)] // not dead, used in OpenAPI docs +#[derive(ToSchema)] +#[schema(title = "PaginatedCachedNodesResponse")] +pub struct PaginatedCachedNodesResponseSchema { + pub refreshed_at: OffsetDateTimeJsonSchemaWrapper, + #[schema(value_type = SkimmedNode)] + pub nodes: PaginatedResponse, +} + /// Return all Nym Nodes and optionally legacy mixnodes/gateways (if `no-legacy` flag is not used) /// that are currently bonded. #[utoipa::path( tag = "Unstable Nym Nodes", get, params(NodesParamsWithRole), - path = "/", + path = "", context_path = "/v1/unstable/nym-nodes/skimmed", responses( - (status = 200, body = PaginatedCachedNodesResponse) + (status = 200, body = PaginatedCachedNodesResponseSchema) ) )] pub(super) async fn nodes_basic_all( @@ -312,7 +325,7 @@ pub(super) async fn nodes_basic_all( path = "/active", context_path = "/v1/unstable/nym-nodes/skimmed", responses( - (status = 200, body = PaginatedCachedNodesResponse) + (status = 200, body = PaginatedCachedNodesResponseSchema) ) )] pub(super) async fn nodes_basic_active( @@ -364,7 +377,7 @@ async fn mixnodes_basic( path = "/mixnodes/all", context_path = "/v1/unstable/nym-nodes/skimmed", responses( - (status = 200, body = PaginatedCachedNodesResponse) + (status = 200, body = PaginatedCachedNodesResponseSchema) ) )] pub(super) async fn mixnodes_basic_all( @@ -383,7 +396,7 @@ pub(super) async fn mixnodes_basic_all( path = "/mixnodes/active", context_path = "/v1/unstable/nym-nodes/skimmed", responses( - (status = 200, body = PaginatedCachedNodesResponse) + (status = 200, body = PaginatedCachedNodesResponseSchema) ) )] pub(super) async fn mixnodes_basic_active( @@ -421,7 +434,7 @@ async fn entry_gateways_basic( path = "/entry-gateways/active", context_path = "/v1/unstable/nym-nodes/skimmed", responses( - (status = 200, body = PaginatedCachedNodesResponse) + (status = 200, body = PaginatedCachedNodesResponseSchema) ) )] pub(super) async fn entry_gateways_basic_active( @@ -440,7 +453,7 @@ pub(super) async fn entry_gateways_basic_active( path = "/entry-gateways/all", context_path = "/v1/unstable/nym-nodes/skimmed", responses( - (status = 200, body = PaginatedCachedNodesResponse) + (status = 200, body = PaginatedCachedNodesResponseSchema) ) )] pub(super) async fn entry_gateways_basic_all( @@ -478,7 +491,7 @@ async fn exit_gateways_basic( path = "/exit-gateways/active", context_path = "/v1/unstable/nym-nodes/skimmed", responses( - (status = 200, body = PaginatedCachedNodesResponse) + (status = 200, body = PaginatedCachedNodesResponseSchema) ) )] pub(super) async fn exit_gateways_basic_active( @@ -497,7 +510,7 @@ pub(super) async fn exit_gateways_basic_active( path = "/exit-gateways/all", context_path = "/v1/unstable/nym-nodes/skimmed", responses( - (status = 200, body = PaginatedCachedNodesResponse) + (status = 200, body = PaginatedCachedNodesResponseSchema) ) )] pub(super) async fn exit_gateways_basic_all( diff --git a/nym-api/src/support/http/helpers.rs b/nym-api/src/support/http/helpers.rs index 4ea95d4cd27..92f6d5585a3 100644 --- a/nym-api/src/support/http/helpers.rs +++ b/nym-api/src/support/http/helpers.rs @@ -14,6 +14,8 @@ pub struct PaginationRequest { } #[derive(Deserialize, IntoParams, ToSchema)] +#[schema(title = "NodeId")] +#[schema(as = NodeId)] #[into_params(parameter_in = Path)] pub(crate) struct NodeIdParam { #[schema(value_type = u32)] diff --git a/nym-api/src/support/http/openapi.rs b/nym-api/src/support/http/openapi.rs index 99713e16507..9d2f49af932 100644 --- a/nym-api/src/support/http/openapi.rs +++ b/nym-api/src/support/http/openapi.rs @@ -2,9 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only #![allow(deprecated)] - use crate::network::handlers::ContractVersionSchemaResponse; -use nym_api_requests::models; use utoipa::OpenApi; use utoipauto::utoipauto; @@ -13,7 +11,15 @@ use utoipauto::utoipauto; // for automatic model discovery based on ToSchema / IntoParams implementation. // Then you can remove `components(schemas)` manual imports below -#[utoipauto(paths = "./nym-api/src")] +// dependencies which have derive(ToSchema) behind a feature flag with cfg_attr +// cannot be autodiscovered because proc macros run before feature flags. +// Tracking issue: https://github.com/ProbablyClem/utoipauto/issues/13 + +#[utoipauto(paths = "./nym-api/src, + ./nym-api/nym-api-requests/src from nym-api-requests, + ./common/config/src from nym-config, + ./common/ticketbooks-merkle/src from nym-ticketbooks-merkle, + ./common/nym_offline_compact_ecash/src from nym_compact_ecash")] #[derive(OpenApi)] #[openapi( info(title = "Nym API"), @@ -24,79 +30,19 @@ use utoipauto::utoipauto; ), tags(), components(schemas( - models::CirculatingSupplyResponse, - models::CoinSchema, nym_mixnet_contract_common::Interval, - nym_api_requests::models::NodeRefreshBody, - nym_api_requests::models::GatewayStatusReportResponse, - nym_api_requests::models::GatewayUptimeHistoryResponse, - nym_api_requests::models::GatewayCoreStatusResponse, - nym_api_requests::models::GatewayUptimeResponse, - nym_api_requests::models::RewardEstimationResponse, - nym_api_requests::models::UptimeResponse, - nym_api_requests::models::ComputeRewardEstParam, - nym_api_requests::models::MixNodeBondAnnotated, - nym_api_requests::models::GatewayBondAnnotated, - nym_api_requests::models::MixnodeTestResultResponse, - nym_api_requests::models::StakeSaturationResponse, - nym_api_requests::models::InclusionProbabilityResponse, - nym_api_requests::models::AllInclusionProbabilitiesResponse, - nym_api_requests::models::InclusionProbability, - nym_api_requests::models::SelectionChance, - crate::network::models::NetworkDetails, + nym_mixnet_contract_common::IntervalRewardParams, + nym_mixnet_contract_common::RewardingParams, + nym_mixnet_contract_common::reward_params::RewardedSetParams, nym_config::defaults::NymNetworkDetails, nym_config::defaults::ChainDetails, nym_config::defaults::DenomDetailsOwned, nym_config::defaults::ValidatorDetails, nym_config::defaults::NymContracts, ContractVersionSchemaResponse, - crate::network::models::ContractInformation, - nym_api_requests::models::ApiHealthResponse, - nym_api_requests::models::ApiStatus, nym_bin_common::build_information::BinaryBuildInformationOwned, - nym_api_requests::models::SignerInformationResponse, - nym_api_requests::models::LegacyDescribedGateway, - nym_mixnet_contract_common::Gateway, - nym_mixnet_contract_common::GatewayBond, - nym_api_requests::models::NymNodeDescription, - nym_api_requests::models::HostInformation, - nym_api_requests::models::HostKeys, nym_node_requests::api::v1::node::models::AuxiliaryDetails, - nym_api_requests::models::NetworkRequesterDetails, - nym_api_requests::models::IpPacketRouterDetails, - nym_api_requests::models::AuthenticatorDetails, - nym_api_requests::models::WebSockets, - nym_api_requests::nym_nodes::NodeRole, - nym_api_requests::models::LegacyDescribedMixNode, - nym_api_requests::ecash::VerificationKeyResponse, - nym_api_requests::ecash::models::AggregatedExpirationDateSignatureResponse, - nym_api_requests::ecash::models::AggregatedCoinIndicesSignatureResponse, - nym_api_requests::ecash::models::MasterVerificationKeyResponse, - nym_api_requests::ecash::models::BlindedSignatureResponse, - nym_api_requests::ecash::models::BlindSignRequestBody, - nym_api_requests::ecash::models::PartialExpirationDateSignatureResponse, - nym_api_requests::ecash::models::PartialCoinIndicesSignatureResponse, - nym_api_requests::ecash::models::EcashTicketVerificationResponse, - nym_api_requests::ecash::models::EcashTicketVerificationRejection, - nym_api_requests::ecash::models::EcashBatchTicketRedemptionResponse, - nym_api_requests::ecash::models::VerifyEcashTicketBody, - nym_api_requests::ecash::models::VerifyEcashCredentialBody, - nym_api_requests::ecash::models::CommitedDeposit, - nym_api_requests::ecash::models::IssuedTicketbooksForResponseBody, - nym_api_requests::ecash::models::IssuedTicketbooksForResponse, - nym_api_requests::ecash::models::IssuedTicketbooksChallengeRequest, - nym_api_requests::ecash::models::IssuedTicketbooksChallengeResponseBody, - nym_api_requests::ecash::models::IssuedTicketbooksChallengeResponse, - nym_api_requests::nym_nodes::SkimmedNode, - nym_api_requests::nym_nodes::SemiSkimmedNode, - nym_api_requests::nym_nodes::FullFatNode, - nym_api_requests::nym_nodes::BasicEntryInformation, - nym_api_requests::nym_nodes::NodeRoleQueryParam, - nym_api_requests::models::AnnotationResponse, - nym_api_requests::models::NodePerformanceResponse, - nym_api_requests::models::NodeDatePerformanceResponse, - nym_api_requests::models::PerformanceHistoryResponse, - nym_api_requests::models::UptimeHistoryResponse, + nym_contracts_common::ContractBuildInformation )) )] pub(crate) struct ApiDoc; diff --git a/nym-credential-proxy/nym-credential-proxy-requests/src/api/v1/mod.rs b/nym-credential-proxy/nym-credential-proxy-requests/src/api/v1/mod.rs index 2e131231cd4..d2c5dc46e34 100644 --- a/nym-credential-proxy/nym-credential-proxy-requests/src/api/v1/mod.rs +++ b/nym-credential-proxy/nym-credential-proxy-requests/src/api/v1/mod.rs @@ -10,9 +10,7 @@ use uuid::Uuid; pub mod ticketbook; #[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)] -#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] pub struct ErrorResponse { - #[cfg_attr(feature = "openapi",schema(value_type = Option, example = "c48f9ce3-a1e9-4886-8000-13f290f34501"))] pub uuid: Option, pub message: String, } diff --git a/nym-credential-proxy/nym-credential-proxy-requests/src/api/v1/ticketbook/models.rs b/nym-credential-proxy/nym-credential-proxy-requests/src/api/v1/ticketbook/models.rs index 81082ea154d..22f04a7483a 100644 --- a/nym-credential-proxy/nym-credential-proxy-requests/src/api/v1/ticketbook/models.rs +++ b/nym-credential-proxy/nym-credential-proxy-requests/src/api/v1/ticketbook/models.rs @@ -46,6 +46,7 @@ pub struct TicketbookRequest { // needs to be explicit in case user creates request at 23:59:59.999, but it reaches vpn-api at 00:00:00.001 #[schemars(with = "String")] #[serde(with = "crate::helpers::date_serde")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] pub expiration_date: Date, #[schemars(with = "String")] @@ -246,10 +247,12 @@ pub struct WebhookTicketbookWalletShares { #[schemars(with = "String")] #[serde(with = "time::serde::rfc3339")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] pub created: OffsetDateTime, #[schemars(with = "String")] #[serde(with = "time::serde::rfc3339")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] pub updated: OffsetDateTime, } diff --git a/nym-credential-proxy/nym-credential-proxy/src/http/router/api/v1/openapi.rs b/nym-credential-proxy/nym-credential-proxy/src/http/router/api/v1/openapi.rs index 2315a658a16..812392056a9 100644 --- a/nym-credential-proxy/nym-credential-proxy/src/http/router/api/v1/openapi.rs +++ b/nym-credential-proxy/nym-credential-proxy/src/http/router/api/v1/openapi.rs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::http::router::api; -use crate::http::types::RequestError; use axum::Router; use nym_credential_proxy_requests::api as api_requests; use nym_credential_proxy_requests::routes::api::{v1, v1_absolute}; @@ -69,7 +68,6 @@ pub(crate) struct ApiDoc; schemas( api::Output, api::OutputParams, - api_requests::v1::ErrorResponse, api_requests::v1::ticketbook::models::DepositResponse, api_requests::v1::ticketbook::models::PartialVerificationKeysResponse, api_requests::v1::ticketbook::models::CurrentEpochResponse, @@ -90,7 +88,6 @@ pub(crate) struct ApiDoc; api_requests::v1::ticketbook::models::SharesQueryParams, api_requests::v1::ticketbook::models::PlaceholderJsonSchemaImpl, ), - responses(RequestError), ), modifiers(&SecurityAddon), )] diff --git a/nym-credential-proxy/nym-credential-proxy/src/http/router/api/v1/ticketbook/mod.rs b/nym-credential-proxy/nym-credential-proxy/src/http/router/api/v1/ticketbook/mod.rs index 335107f3dba..530d2bdad1d 100644 --- a/nym-credential-proxy/nym-credential-proxy/src/http/router/api/v1/ticketbook/mod.rs +++ b/nym-credential-proxy/nym-credential-proxy/src/http/router/api/v1/ticketbook/mod.rs @@ -48,14 +48,14 @@ pub type FormattedTicketbookWalletSharesAsyncResponse = ), responses( (status = 200, content( - ("application/json" = TicketbookWalletSharesResponse), - ("application/yaml" = TicketbookWalletSharesResponse), + (TicketbookWalletSharesResponse = "application/json"), + (TicketbookWalletSharesResponse = "application/yaml"), )), (status = 400, description = "the provided request hasn't been created against correct attributes"), (status = 401, description = "authentication token is missing or is invalid"), (status = 422, description = "provided request was malformed"), - (status = 500, body = ErrorResponse, description = "failed to obtain a ticketbook"), - (status = 503, body = ErrorResponse, description = "ticketbooks can't be issued at this moment: the epoch transition is probably taking place"), + (status = 500, body = String, description = "failed to obtain a ticketbook"), + (status = 503, body = String, description = "ticketbooks can't be issued at this moment: the epoch transition is probably taking place"), ), params(TicketbookObtainQueryParams), security( @@ -138,15 +138,15 @@ pub(crate) async fn obtain_ticketbook_shares( ), responses( (status = 200, content( - ("application/json" = TicketbookWalletSharesAsyncResponse), - ("application/yaml" = TicketbookWalletSharesAsyncResponse), + (TicketbookWalletSharesAsyncResponse = "application/json"), + (TicketbookWalletSharesAsyncResponse = "application/yaml"), )), (status = 400, description = "the provided request hasn't been created against correct attributes"), (status = 401, description = "authentication token is missing or is invalid"), (status = 409, description = "shares were already requested"), (status = 422, description = "provided request was malformed"), - (status = 500, body = ErrorResponse, description = "failed to obtain a ticketbook"), - (status = 503, body = ErrorResponse, description = "ticketbooks can't be issued at this moment: the epoch transition is probably taking place"), + (status = 500, body = String, description = "failed to obtain a ticketbook"), + (status = 503, body = String, description = "ticketbooks can't be issued at this moment: the epoch transition is probably taking place"), ), params(TicketbookObtainQueryParams), security( @@ -235,11 +235,11 @@ pub(crate) async fn obtain_ticketbook_shares_async( tag = "Ticketbook", responses( (status = 200, content( - ("application/json" = DepositResponse), - ("application/yaml" = DepositResponse), + (DepositResponse = "application/json"), + (DepositResponse = "application/yaml"), )), (status = 401, description = "authentication token is missing or is invalid"), - (status = 500, body = ErrorResponse, description = "failed to obtain current deposit information"), + (status = 500, body = String, description = "failed to obtain current deposit information"), ), params(OutputParams), security( @@ -270,12 +270,12 @@ pub(crate) async fn current_deposit( tag = "Ticketbook", responses( (status = 200, content( - ("application/json" = PartialVerificationKeysResponse), - ("application/yaml" = PartialVerificationKeysResponse), + (PartialVerificationKeysResponse = "application/json"), + (PartialVerificationKeysResponse = "application/yaml"), )), (status = 401, description = "authentication token is missing or is invalid"), - (status = 500, body = ErrorResponse, description = "failed to obtain current epoch information"), - (status = 503, body = ErrorResponse, description = "credentials can't be issued at this moment: the epoch transition is probably taking place"), + (status = 500, body = String, description = "failed to obtain current epoch information"), + (status = 503, body = String, description = "credentials can't be issued at this moment: the epoch transition is probably taking place"), ), params(OutputParams), security( @@ -320,12 +320,12 @@ pub(crate) async fn partial_verification_keys( tag = "Ticketbook", responses( (status = 200, content( - ("application/json" = MasterVerificationKeyResponse), - ("application/yaml" = MasterVerificationKeyResponse), + (MasterVerificationKeyResponse = "application/json"), + (MasterVerificationKeyResponse = "application/yaml"), )), (status = 401, description = "authentication token is missing or is invalid"), - (status = 500, body = ErrorResponse, description = "failed to obtain current epoch information"), - (status = 503, body = ErrorResponse, description = "credentials can't be issued at this moment: the epoch transition is probably taking place"), + (status = 500, body = String, description = "failed to obtain current epoch information"), + (status = 503, body = String, description = "credentials can't be issued at this moment: the epoch transition is probably taking place"), ), params(OutputParams), security( @@ -365,12 +365,12 @@ pub(crate) async fn master_verification_key( tag = "Ticketbook", responses( (status = 200, content( - ("application/json" = CurrentEpochResponse), - ("application/yaml" = CurrentEpochResponse), + (CurrentEpochResponse = "application/json"), + (CurrentEpochResponse = "application/yaml"), )), (status = 401, description = "authentication token is missing or is invalid"), - (status = 500, body = ErrorResponse, description = "failed to obtain current epoch information"), - (status = 503, body = ErrorResponse, description = "credentials can't be issued at this moment: the epoch transition is probably taking place"), + (status = 500, body = String, description = "failed to obtain current epoch information"), + (status = 503, body = String, description = "credentials can't be issued at this moment: the epoch transition is probably taking place"), ), params(OutputParams), security( diff --git a/nym-credential-proxy/nym-credential-proxy/src/http/router/api/v1/ticketbook/shares.rs b/nym-credential-proxy/nym-credential-proxy/src/http/router/api/v1/ticketbook/shares.rs index cfe4893a69b..8b3dacb82d4 100644 --- a/nym-credential-proxy/nym-credential-proxy/src/http/router/api/v1/ticketbook/shares.rs +++ b/nym-credential-proxy/nym-credential-proxy/src/http/router/api/v1/ticketbook/shares.rs @@ -80,12 +80,12 @@ async fn shares_to_response( tag = "Ticketbook Wallet Shares", responses( (status = 200, content( - ("application/json" = TicketbookWalletSharesResponse), - ("application/yaml" = TicketbookWalletSharesResponse), + (TicketbookWalletSharesResponse = "application/json"), + (TicketbookWalletSharesResponse = "application/yaml"), )), (status = 404, description = "share_id not found"), (status = 401, description = "authentication token is missing or is invalid"), - (status = 500, body = ErrorResponse, description = "failed to query for bandwidth blinded shares"), + (status = 500, body = String, description = "failed to query for bandwidth blinded shares"), ), params(OutputParams), security( @@ -155,12 +155,12 @@ pub(crate) async fn query_for_shares_by_id( tag = "Ticketbook Wallet Shares", responses( (status = 200, content( - ("application/json" = TicketbookWalletSharesResponse), - ("application/yaml" = TicketbookWalletSharesResponse), + (TicketbookWalletSharesResponse = "application/json"), + (TicketbookWalletSharesResponse = "application/yaml"), )), (status = 404, description = "share_id not found"), (status = 401, description = "authentication token is missing or is invalid"), - (status = 500, body = ErrorResponse, description = "failed to query for bandwidth blinded shares"), + (status = 500, body = String, description = "failed to query for bandwidth blinded shares"), ), params(SharesQueryParams), security( diff --git a/nym-credential-proxy/nym-credential-proxy/src/http/types.rs b/nym-credential-proxy/nym-credential-proxy/src/http/types.rs index 86021034569..6538c5a9a73 100644 --- a/nym-credential-proxy/nym-credential-proxy/src/http/types.rs +++ b/nym-credential-proxy/nym-credential-proxy/src/http/types.rs @@ -6,14 +6,11 @@ use axum::http::StatusCode; use axum::response::{IntoResponse, Response}; use axum::Json; use nym_credential_proxy_requests::api::v1::ErrorResponse; -use utoipa::ToResponse; use uuid::Uuid; -#[derive(Debug, Clone, ToResponse)] -#[response(description = "Error response with additional message")] +#[derive(Debug, Clone)] pub struct RequestError { pub inner: ErrorResponse, - pub status: StatusCode, } diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/gateways.rs b/nym-node-status-api/nym-node-status-api/src/http/api/gateways.rs index c1f40737671..80e870f1983 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/gateways.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/gateways.rs @@ -27,7 +27,7 @@ pub(crate) fn routes() -> Router { ), path = "/v2/gateways", responses( - (status = 200, body = PagedGateway) + (status = 200, body = PagedResult) ) )] async fn gateways( @@ -48,7 +48,7 @@ async fn gateways( ), path = "/v2/gateways/skinny", responses( - (status = 200, body = PagedGatewaySkinny) + (status = 200, body = PagedResult) ) )] async fn gateways_skinny( diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/metrics/sessions.rs b/nym-node-status-api/nym-node-status-api/src/http/api/metrics/sessions.rs index e2e4cd9cedc..409c0427538 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/metrics/sessions.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/metrics/sessions.rs @@ -35,7 +35,7 @@ pub(crate) struct SessionQueryParams { ), path = "/v2/metrics/sessions", responses( - (status = 200, body = PagedSessionStats) + (status = 200, body = PagedResult) ) )] #[instrument(level = tracing::Level::DEBUG, skip(state))] diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/mixnodes.rs b/nym-node-status-api/nym-node-status-api/src/http/api/mixnodes.rs index f42d0bf91c8..ae9842e1dfe 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/mixnodes.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/mixnodes.rs @@ -28,7 +28,7 @@ pub(crate) fn routes() -> Router { ), path = "/v2/mixnodes", responses( - (status = 200, body = PagedMixnode) + (status = 200, body = PagedResult) ) )] #[instrument(level = tracing::Level::DEBUG, skip_all, fields(page=pagination.page, size=pagination.size))] diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/services/mod.rs b/nym-node-status-api/nym-node-status-api/src/http/api/services/mod.rs index 5650684c43e..4a817ab759f 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/services/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/services/mod.rs @@ -35,7 +35,7 @@ pub(crate) struct ServicesQueryParams { ), path = "/v2/services", responses( - (status = 200, body = PagedService) + (status = 200, body = PagedResult) ) )] #[instrument(level = tracing::Level::DEBUG, skip(state))] diff --git a/nym-node-status-api/nym-node-status-api/src/http/api_docs.rs b/nym-node-status-api/nym-node-status-api/src/http/api_docs.rs index fec4d25cd5d..124c7ebee0a 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api_docs.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api_docs.rs @@ -1,4 +1,3 @@ -use crate::http::{Gateway, GatewaySkinny, Mixnode, Service, SessionStats}; use utoipa::OpenApi; use utoipauto::utoipauto; diff --git a/nym-node-status-api/nym-node-status-api/src/http/mod.rs b/nym-node-status-api/nym-node-status-api/src/http/mod.rs index b1a7bf742d6..2fa83733180 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/mod.rs @@ -1,4 +1,4 @@ -use models::{Gateway, GatewaySkinny, Mixnode, Service, SessionStats}; +use utoipa::ToSchema; pub(crate) mod api; pub(crate) mod api_docs; @@ -8,28 +8,14 @@ pub(crate) mod server; pub(crate) mod state; #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, utoipa::ToSchema)] -// exclude generic from auto-discovery -#[utoipauto::utoipa_ignore] -// https://docs.rs/utoipa/latest/utoipa/derive.ToSchema.html#generic-schemas-with-aliases -// Generic structs can only be included via aliases, not directly, because they -// it would cause an error in generated Swagger docs. -// Instead, you have to manually monomorphize each generic struct that -// you wish to document -#[aliases( - PagedGateway = PagedResult, - PagedGatewaySkinny = PagedResult, - PagedMixnode = PagedResult, - PagedService = PagedResult, - PagedSessionStats = PagedResult -)] -pub struct PagedResult { +pub struct PagedResult { pub page: usize, pub size: usize, pub total: usize, pub items: Vec, } -impl PagedResult { +impl PagedResult { pub fn paginate(pagination: Pagination, res: Vec) -> Self { let total = res.len(); let (size, mut page) = pagination.intoto_inner_values(); diff --git a/nym-node/nym-node-requests/Cargo.toml b/nym-node/nym-node-requests/Cargo.toml index fc1d0853c3a..8b8849c480f 100644 --- a/nym-node/nym-node-requests/Cargo.toml +++ b/nym-node/nym-node-requests/Cargo.toml @@ -35,7 +35,7 @@ async-trait = { workspace = true, optional = true } nym-http-api-client = { path = "../../common/http-api-client", optional = true } ## openapi: -utoipa = { workspace = true, optional = true } +utoipa = { workspace = true, features = ["time"], optional = true } nym-bin-common = { path = "../../common/bin-common", features = [ "bin_info_schema", ] } diff --git a/nym-node/nym-node-requests/src/api/mod.rs b/nym-node/nym-node-requests/src/api/mod.rs index 6bf586f71b0..5e09d150b7b 100644 --- a/nym-node/nym-node-requests/src/api/mod.rs +++ b/nym-node/nym-node-requests/src/api/mod.rs @@ -1,15 +1,14 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::api::v1::node::models::{ - HostInformation, LegacyHostInformation, LegacyHostInformationV2, -}; +use crate::api::v1::node::models::{LegacyHostInformation, LegacyHostInformationV2}; use crate::error::Error; use nym_crypto::asymmetric::identity; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter}; use std::ops::Deref; +use utoipa::ToSchema; #[cfg(feature = "client")] pub mod client; @@ -19,12 +18,16 @@ pub mod v1; pub use client::Client; // create the type alias manually if openapi is not enabled -#[cfg(not(feature = "openapi"))] -pub type SignedHostInformation = SignedData; +pub type SignedHostInformation = SignedData; + +#[derive(ToSchema)] +pub struct SignedDataHostInfo { + // #[serde(flatten)] + pub data: crate::api::v1::node::models::HostInformation, + pub signature: String, +} #[derive(Debug, Clone, Serialize, Deserialize)] -#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] -#[cfg_attr(feature = "openapi", aliases(SignedHostInformation = SignedData))] pub struct SignedData { // #[serde(flatten)] pub data: T, @@ -90,7 +93,6 @@ impl Deref for SignedData { } #[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)] -#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] pub struct ErrorResponse { pub message: String, } diff --git a/nym-node/nym-node-requests/src/api/v1/metrics/models.rs b/nym-node/nym-node-requests/src/api/v1/metrics/models.rs index 0ee4170dfec..555982bb2aa 100644 --- a/nym-node/nym-node-requests/src/api/v1/metrics/models.rs +++ b/nym-node/nym-node-requests/src/api/v1/metrics/models.rs @@ -97,6 +97,13 @@ pub mod verloc { use serde::{Deserialize, Serialize}; use std::time::Duration; use time::OffsetDateTime; + #[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, PartialEq)] + #[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] + pub struct VerlocNodeResult { + #[serde(with = "bs58_ed25519_pubkey")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub node_identity: ed25519::PublicKey, + } #[derive(Serialize, Deserialize, Default, Debug, Clone)] #[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] @@ -129,15 +136,6 @@ pub mod verloc { pub results: Vec, } - #[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, PartialEq)] - #[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] - pub struct VerlocNodeResult { - #[serde(with = "bs58_ed25519_pubkey")] - pub node_identity: ed25519::PublicKey, - - pub latest_measurement: Option, - } - #[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] pub struct VerlocMeasurement { @@ -174,6 +172,7 @@ pub mod session { #[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] pub struct SessionStats { #[serde(with = "time::serde::rfc3339")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] pub update_time: OffsetDateTime, pub unique_active_users: u32, diff --git a/nym-node/nym-node-requests/src/api/v1/node/models.rs b/nym-node/nym-node-requests/src/api/v1/node/models.rs index d0f1e3df037..5f047912faa 100644 --- a/nym-node/nym-node-requests/src/api/v1/node/models.rs +++ b/nym-node/nym-node-requests/src/api/v1/node/models.rs @@ -111,6 +111,7 @@ pub struct HostKeys { #[serde(alias = "ed25519")] #[serde(with = "bs58_ed25519_pubkey")] #[schemars(with = "String")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] pub ed25519_identity: ed25519::PublicKey, /// Base58-encoded x25519 public key of this node used for sphinx/outfox packet creation. @@ -118,12 +119,14 @@ pub struct HostKeys { #[serde(alias = "x25519")] #[serde(with = "bs58_x25519_pubkey")] #[schemars(with = "String")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] pub x25519_sphinx: x25519::PublicKey, /// Base58-encoded x25519 public key of this node used for the noise protocol. #[serde(default)] #[serde(with = "option_bs58_x25519_pubkey")] #[schemars(with = "Option")] + #[cfg_attr(feature = "openapi", schema(value_type = Option))] pub x25519_noise: Option, } diff --git a/nym-node/src/node/http/router/api/v1/authenticator/root.rs b/nym-node/src/node/http/router/api/v1/authenticator/root.rs index 054d224779d..6c6ed9c8355 100644 --- a/nym-node/src/node/http/router/api/v1/authenticator/root.rs +++ b/nym-node/src/node/http/router/api/v1/authenticator/root.rs @@ -15,8 +15,8 @@ use nym_node_requests::api::v1::authenticator::models::Authenticator; responses( (status = 501, description = "the endpoint hasn't been implemented yet"), (status = 200, content( - ("application/json" = Authenticator), - ("application/yaml" = Authenticator) + (Authenticator = "application/json"), + (Authenticator = "application/yaml") )) ), params(OutputParams) diff --git a/nym-node/src/node/http/router/api/v1/gateway/client_interfaces/mod.rs b/nym-node/src/node/http/router/api/v1/gateway/client_interfaces/mod.rs index 96215f71920..6e2b5c57d26 100644 --- a/nym-node/src/node/http/router/api/v1/gateway/client_interfaces/mod.rs +++ b/nym-node/src/node/http/router/api/v1/gateway/client_interfaces/mod.rs @@ -45,8 +45,8 @@ pub(crate) fn routes( responses( (status = 501, description = "the endpoint hasn't been implemented yet"), (status = 200, content( - ("application/json" = ClientInterfaces), - ("application/yaml" = ClientInterfaces) + (ClientInterfaces = "application/json"), + (ClientInterfaces = "application/yaml") )) ), params(OutputParams) @@ -71,8 +71,8 @@ pub type ClientInterfacesResponse = FormattedResponse; responses( (status = 501, description = "the endpoint hasn't been implemented yet"), (status = 200, content( - ("application/json" = WebSockets), - ("application/yaml" = WebSockets) + (WebSockets = "application/json"), + (WebSockets = "application/yaml") )) ), params(OutputParams) @@ -97,8 +97,8 @@ pub type MixnetWebSocketsResponse = FormattedResponse; responses( (status = 501, description = "the endpoint hasn't been implemented yet"), (status = 200, content( - ("application/json" = Wireguard), - ("application/yaml" = Wireguard) + (Wireguard = "application/json"), + (Wireguard = "application/yaml") )) ), params(OutputParams) diff --git a/nym-node/src/node/http/router/api/v1/gateway/root.rs b/nym-node/src/node/http/router/api/v1/gateway/root.rs index 4738acb30ec..2d96374b2ed 100644 --- a/nym-node/src/node/http/router/api/v1/gateway/root.rs +++ b/nym-node/src/node/http/router/api/v1/gateway/root.rs @@ -15,8 +15,8 @@ use nym_node_requests::api::v1::gateway::models::Gateway; responses( (status = 501, description = "the endpoint hasn't been implemented yet"), (status = 200, content( - ("application/json" = Gateway), - ("application/yaml" = Gateway) + (Gateway = "application/json"), + (Gateway = "application/yaml") )) ), params(OutputParams) diff --git a/nym-node/src/node/http/router/api/v1/health.rs b/nym-node/src/node/http/router/api/v1/health.rs index 0972ea6339e..510107039f8 100644 --- a/nym-node/src/node/http/router/api/v1/health.rs +++ b/nym-node/src/node/http/router/api/v1/health.rs @@ -14,8 +14,8 @@ use nym_node_requests::api::v1::health::models::NodeHealth; tag = "Health", responses( (status = 200, content( - ("application/json" = Vec), - ("application/yaml" = Vec) + (Vec = "application/json"), + (Vec = "application/yaml") ), description = "the api is available and healthy") ), params(OutputParams) diff --git a/nym-node/src/node/http/router/api/v1/ip_packet_router/root.rs b/nym-node/src/node/http/router/api/v1/ip_packet_router/root.rs index 18c503bd5ce..e85cee897ec 100644 --- a/nym-node/src/node/http/router/api/v1/ip_packet_router/root.rs +++ b/nym-node/src/node/http/router/api/v1/ip_packet_router/root.rs @@ -15,8 +15,8 @@ use nym_node_requests::api::v1::ip_packet_router::models::IpPacketRouter; responses( (status = 501, description = "the endpoint hasn't been implemented yet"), (status = 200, content( - ("application/json" = IpPacketRouter), - ("application/yaml" = IpPacketRouter) + (IpPacketRouter = "application/json"), + (IpPacketRouter = "application/yaml") )) ), params(OutputParams) diff --git a/nym-node/src/node/http/router/api/v1/metrics/legacy_mixing.rs b/nym-node/src/node/http/router/api/v1/metrics/legacy_mixing.rs index 23cfd0607d7..de9126aead8 100644 --- a/nym-node/src/node/http/router/api/v1/metrics/legacy_mixing.rs +++ b/nym-node/src/node/http/router/api/v1/metrics/legacy_mixing.rs @@ -16,8 +16,8 @@ use nym_node_requests::api::v1::metrics::models::LegacyMixingStats; tag = "Metrics", responses( (status = 200, content( - ("application/json" = LegacyMixingStats), - ("application/yaml" = LegacyMixingStats) + (LegacyMixingStats = "application/json"), + (LegacyMixingStats = "application/yaml") )) ), params(OutputParams), diff --git a/nym-node/src/node/http/router/api/v1/metrics/packets_stats.rs b/nym-node/src/node/http/router/api/v1/metrics/packets_stats.rs index 490bcffb57e..3faf5be346f 100644 --- a/nym-node/src/node/http/router/api/v1/metrics/packets_stats.rs +++ b/nym-node/src/node/http/router/api/v1/metrics/packets_stats.rs @@ -18,8 +18,8 @@ use nym_node_requests::api::v1::metrics::models::packets::{ tag = "Metrics", responses( (status = 200, content( - ("application/json" = PacketsStats), - ("application/yaml" = PacketsStats) + (PacketsStats = "application/json"), + (PacketsStats = "application/yaml") )) ), params(OutputParams), diff --git a/nym-node/src/node/http/router/api/v1/metrics/sessions.rs b/nym-node/src/node/http/router/api/v1/metrics/sessions.rs index 0b76e832051..e2fd969e178 100644 --- a/nym-node/src/node/http/router/api/v1/metrics/sessions.rs +++ b/nym-node/src/node/http/router/api/v1/metrics/sessions.rs @@ -17,8 +17,8 @@ use time::macros::time; tag = "Metrics", responses( (status = 200, content( - ("application/json" = SessionStats), - ("application/yaml" = SessionStats) + (SessionStats = "application/json"), + (SessionStats = "application/yaml") )) ), params(OutputParams), diff --git a/nym-node/src/node/http/router/api/v1/metrics/verloc.rs b/nym-node/src/node/http/router/api/v1/metrics/verloc.rs index 1a15986373c..8a2a046637d 100644 --- a/nym-node/src/node/http/router/api/v1/metrics/verloc.rs +++ b/nym-node/src/node/http/router/api/v1/metrics/verloc.rs @@ -1,14 +1,15 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use crate::node::http::state::metrics::MetricsAppState; use axum::extract::{Query, State}; use nym_http_api_common::{FormattedResponse, OutputParams}; use nym_node_requests::api::v1::metrics::models::{ - VerlocMeasurement, VerlocNodeResult, VerlocResult, VerlocResultData, VerlocStats, + VerlocNodeResult, VerlocResult, VerlocResultData, VerlocStats, }; use nym_verloc::measurements::SharedVerlocStats; +use crate::node::http::state::metrics::MetricsAppState; + /// If applicable, returns verloc statistics information of this node. #[utoipa::path( get, @@ -17,8 +18,8 @@ use nym_verloc::measurements::SharedVerlocStats; tag = "Metrics", responses( (status = 200, content( - ("application/json" = VerlocStats), - ("application/yaml" = VerlocStats) + (VerlocStats = "application/json"), + (VerlocStats = "application/yaml") )) ), params(OutputParams), @@ -42,12 +43,6 @@ async fn build_response(verloc_stats: &SharedVerlocStats) -> VerlocStats { .iter() .map(|r| VerlocNodeResult { node_identity: r.node_identity, - latest_measurement: r.latest_measurement.map(|l| VerlocMeasurement { - minimum: l.minimum, - mean: l.mean, - maximum: l.maximum, - standard_deviation: l.standard_deviation, - }), }) .collect(), } diff --git a/nym-node/src/node/http/router/api/v1/metrics/wireguard.rs b/nym-node/src/node/http/router/api/v1/metrics/wireguard.rs index 3519ff30dde..1e4668a8057 100644 --- a/nym-node/src/node/http/router/api/v1/metrics/wireguard.rs +++ b/nym-node/src/node/http/router/api/v1/metrics/wireguard.rs @@ -16,8 +16,8 @@ use nym_node_requests::api::v1::metrics::models::WireguardStats; tag = "Metrics", responses( (status = 200, content( - ("application/json" = WireguardStats), - ("application/yaml" = WireguardStats) + (WireguardStats = "application/json"), + (WireguardStats = "application/yaml") )) ), params(OutputParams), diff --git a/nym-node/src/node/http/router/api/v1/mixnode/root.rs b/nym-node/src/node/http/router/api/v1/mixnode/root.rs index 4f1133ebc3c..dff028e6c29 100644 --- a/nym-node/src/node/http/router/api/v1/mixnode/root.rs +++ b/nym-node/src/node/http/router/api/v1/mixnode/root.rs @@ -15,8 +15,8 @@ use nym_node_requests::api::v1::mixnode::models::Mixnode; responses( (status = 501, description = "the endpoint hasn't been implemented yet"), (status = 200, content( - ("application/json" = Mixnode), - ("application/yaml" = Mixnode) + (Mixnode = "application/json"), + (Mixnode = "application/yaml") )) ), params(OutputParams) diff --git a/nym-node/src/node/http/router/api/v1/network_requester/exit_policy.rs b/nym-node/src/node/http/router/api/v1/network_requester/exit_policy.rs index a58cd8862c2..1640fb0d665 100644 --- a/nym-node/src/node/http/router/api/v1/network_requester/exit_policy.rs +++ b/nym-node/src/node/http/router/api/v1/network_requester/exit_policy.rs @@ -13,8 +13,8 @@ use nym_node_requests::api::v1::network_requester::exit_policy::models::UsedExit tag = "Network Requester", responses( (status = 200, content( - ("application/json" = UsedExitPolicy), - ("application/yaml" = UsedExitPolicy) + (UsedExitPolicy = "application/json"), + (UsedExitPolicy = "application/yaml") )) ), params(OutputParams) diff --git a/nym-node/src/node/http/router/api/v1/network_requester/root.rs b/nym-node/src/node/http/router/api/v1/network_requester/root.rs index 426614b07f7..fe9f2c07a21 100644 --- a/nym-node/src/node/http/router/api/v1/network_requester/root.rs +++ b/nym-node/src/node/http/router/api/v1/network_requester/root.rs @@ -15,8 +15,8 @@ use nym_node_requests::api::v1::network_requester::models::NetworkRequester; responses( (status = 501, description = "the endpoint hasn't been implemented yet"), (status = 200, content( - ("application/json" = NetworkRequester), - ("application/yaml" = NetworkRequester) + (NetworkRequester = "application/json"), + (NetworkRequester = "application/yaml") )) ), params(OutputParams) diff --git a/nym-node/src/node/http/router/api/v1/node/auxiliary.rs b/nym-node/src/node/http/router/api/v1/node/auxiliary.rs index 9db2b5f6dd8..b163371ef27 100644 --- a/nym-node/src/node/http/router/api/v1/node/auxiliary.rs +++ b/nym-node/src/node/http/router/api/v1/node/auxiliary.rs @@ -14,8 +14,8 @@ use nym_node_requests::api::v1::node::models::AuxiliaryDetails; tag = "Node", responses( (status = 200, content( - ("application/json" = AuxiliaryDetails), - ("application/yaml" = AuxiliaryDetails) + (AuxiliaryDetails = "application/json"), + (AuxiliaryDetails = "application/yaml") )), ), params(OutputParams) diff --git a/nym-node/src/node/http/router/api/v1/node/build_information.rs b/nym-node/src/node/http/router/api/v1/node/build_information.rs index 6073482c3e6..7761a99f4de 100644 --- a/nym-node/src/node/http/router/api/v1/node/build_information.rs +++ b/nym-node/src/node/http/router/api/v1/node/build_information.rs @@ -13,8 +13,8 @@ use nym_node_requests::api::v1::node::models::BinaryBuildInformationOwned; tag = "Node", responses( (status = 200, content( - ("application/json" = BinaryBuildInformationOwned), - ("application/yaml" = BinaryBuildInformationOwned) + (BinaryBuildInformationOwned = "application/json"), + (BinaryBuildInformationOwned = "application/yaml") )) ), params(OutputParams) diff --git a/nym-node/src/node/http/router/api/v1/node/description.rs b/nym-node/src/node/http/router/api/v1/node/description.rs index ff569c78fbe..bd6e4ee8b5d 100644 --- a/nym-node/src/node/http/router/api/v1/node/description.rs +++ b/nym-node/src/node/http/router/api/v1/node/description.rs @@ -14,8 +14,8 @@ use nym_node_requests::api::v1::node::models::NodeDescription; tag = "Node", responses( (status = 200, content( - ("application/json" = NodeDescription), - ("application/yaml" = NodeDescription) + (NodeDescription = "application/json"), + (NodeDescription = "application/yaml") )), ), params(OutputParams) diff --git a/nym-node/src/node/http/router/api/v1/node/hardware.rs b/nym-node/src/node/http/router/api/v1/node/hardware.rs index 969e93458f0..b0f5e124d3d 100644 --- a/nym-node/src/node/http/router/api/v1/node/hardware.rs +++ b/nym-node/src/node/http/router/api/v1/node/hardware.rs @@ -15,10 +15,10 @@ use nym_node_requests::api::v1::node::models::HostSystem; tag = "Node", responses( (status = 200, content( - ("application/json" = HostSystem), - ("application/yaml" = HostSystem) + (HostSystem = "application/json"), + (HostSystem = "application/yaml") )), - (status = 403, body = ErrorResponse, description = "the node does not wish to expose the system information") + (status = 403, body = String, description = "the node does not wish to expose the system information") ), params(OutputParams) )] diff --git a/nym-node/src/node/http/router/api/v1/node/host_information.rs b/nym-node/src/node/http/router/api/v1/node/host_information.rs index d6cea0acde6..76eb5ddfa02 100644 --- a/nym-node/src/node/http/router/api/v1/node/host_information.rs +++ b/nym-node/src/node/http/router/api/v1/node/host_information.rs @@ -3,7 +3,7 @@ use axum::extract::Query; use nym_http_api_common::{FormattedResponse, OutputParams}; -use nym_node_requests::api::v1::node::models::SignedHostInformation; +use nym_node_requests::api::{v1::node::models::SignedHostInformation, SignedDataHostInfo}; /// Returns host information of this node. #[utoipa::path( @@ -13,8 +13,8 @@ use nym_node_requests::api::v1::node::models::SignedHostInformation; tag = "Node", responses( (status = 200, content( - ("application/json" = SignedHostInformation), - ("application/yaml" = SignedHostInformation) + (SignedDataHostInfo = "application/json"), + (SignedDataHostInfo = "application/yaml") )) ), params(OutputParams) diff --git a/nym-node/src/node/http/router/api/v1/node/roles.rs b/nym-node/src/node/http/router/api/v1/node/roles.rs index 40b98d868af..c1228a5188c 100644 --- a/nym-node/src/node/http/router/api/v1/node/roles.rs +++ b/nym-node/src/node/http/router/api/v1/node/roles.rs @@ -13,8 +13,8 @@ use nym_node_requests::api::v1::node::models::NodeRoles; tag = "Node", responses( (status = 200, content( - ("application/json" = NodeRoles), - ("application/yaml" = NodeRoles) + (NodeRoles = "application/json"), + (NodeRoles = "application/yaml") )) ), params(OutputParams) diff --git a/nym-node/src/node/http/router/api/v1/openapi.rs b/nym-node/src/node/http/router/api/v1/openapi.rs index a46812464f3..6b209c450f0 100644 --- a/nym-node/src/node/http/router/api/v1/openapi.rs +++ b/nym-node/src/node/http/router/api/v1/openapi.rs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::node::http::router::api; -use crate::node::http::router::types::{ErrorResponse, RequestError}; use axum::Router; use nym_node_requests::api as api_requests; use nym_node_requests::routes::api::{v1, v1_absolute}; @@ -35,13 +34,11 @@ use utoipa_swagger_ui::SwaggerUi; ), components( schemas( - ErrorResponse, nym_http_api_common::Output, nym_http_api_common::OutputParams, api_requests::v1::health::models::NodeHealth, api_requests::v1::health::models::NodeStatus, api_requests::v1::node::models::BinaryBuildInformationOwned, - api_requests::v1::node::models::SignedHostInformation, api_requests::v1::node::models::HostInformation, api_requests::v1::node::models::HostKeys, api_requests::v1::node::models::NodeRoles, @@ -71,7 +68,6 @@ use utoipa_swagger_ui::SwaggerUi; api_requests::v1::network_requester::exit_policy::models::UsedExitPolicy, api_requests::v1::ip_packet_router::models::IpPacketRouter, ), - responses(RequestError), ), modifiers(&SecurityAddon), )] diff --git a/nym-node/src/node/http/router/types.rs b/nym-node/src/node/http/router/types.rs index 7a20492fc62..c8b692bda99 100644 --- a/nym-node/src/node/http/router/types.rs +++ b/nym-node/src/node/http/router/types.rs @@ -5,10 +5,8 @@ use axum::http::StatusCode; use axum::response::{IntoResponse, Response}; use axum::Json; pub use nym_node_requests::api::ErrorResponse; -use utoipa::ToResponse; -#[derive(Debug, Clone, ToResponse)] -#[response(description = "Error response with additional message")] +#[derive(Debug, Clone)] pub(crate) struct RequestError { pub(crate) inner: ErrorResponse, diff --git a/nym-validator-rewarder/.sqlx/query-0a802236d0b9cc7679971f884a89146f8b40d46d14aa0ecb7237d5d78a9f463f.json b/nym-validator-rewarder/.sqlx/query-0a802236d0b9cc7679971f884a89146f8b40d46d14aa0ecb7237d5d78a9f463f.json new file mode 100644 index 00000000000..e130a550d31 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-0a802236d0b9cc7679971f884a89146f8b40d46d14aa0ecb7237d5d78a9f463f.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n INSERT INTO block_signing_rewarding_details(\n rewarding_epoch_id,\n total_voting_power_at_epoch_start,\n num_blocks,\n spent,\n rewarding_tx,\n rewarding_error,\n monitor_only\n ) VALUES (?, ?, ?, ?, ?, ?, ?)\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 7 + }, + "nullable": [] + }, + "hash": "0a802236d0b9cc7679971f884a89146f8b40d46d14aa0ecb7237d5d78a9f463f" +} diff --git a/nym-validator-rewarder/.sqlx/query-0e03fcbde46a0296e029624ae083381fe8e839998717e6d1a0502f54438fc9b0.json b/nym-validator-rewarder/.sqlx/query-0e03fcbde46a0296e029624ae083381fe8e839998717e6d1a0502f54438fc9b0.json new file mode 100644 index 00000000000..53b4bf47308 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-0e03fcbde46a0296e029624ae083381fe8e839998717e6d1a0502f54438fc9b0.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "UPDATE pruning SET last_pruned_height = ?", + "describe": { + "columns": [], + "parameters": { + "Right": 1 + }, + "nullable": [] + }, + "hash": "0e03fcbde46a0296e029624ae083381fe8e839998717e6d1a0502f54438fc9b0" +} diff --git a/nym-validator-rewarder/.sqlx/query-1d3938bc8d8d6829289ef7ff78ee836c7cff2646b6b76559543b4e4056094d58.json b/nym-validator-rewarder/.sqlx/query-1d3938bc8d8d6829289ef7ff78ee836c7cff2646b6b76559543b4e4056094d58.json new file mode 100644 index 00000000000..1d6a5bdaf62 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-1d3938bc8d8d6829289ef7ff78ee836c7cff2646b6b76559543b4e4056094d58.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n INSERT INTO ticketbook_issuance_reward(\n ticketbook_expiration_date,\n api_endpoint,\n operator_account,\n whitelisted,\n banned,\n amount,\n issued_partial_ticketbooks,\n share_of_issued_ticketbooks,\n skipped_verification,\n subsample_size\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 10 + }, + "nullable": [] + }, + "hash": "1d3938bc8d8d6829289ef7ff78ee836c7cff2646b6b76559543b4e4056094d58" +} diff --git a/nym-validator-rewarder/.sqlx/query-1ebd5510a96bc84a88cc91316f891d372e750a74e2eb5a252a787cf571c326e4.json b/nym-validator-rewarder/.sqlx/query-1ebd5510a96bc84a88cc91316f891d372e750a74e2eb5a252a787cf571c326e4.json new file mode 100644 index 00000000000..f189ef3675c --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-1ebd5510a96bc84a88cc91316f891d372e750a74e2eb5a252a787cf571c326e4.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "DELETE FROM \"transaction\" WHERE height < ?", + "describe": { + "columns": [], + "parameters": { + "Right": 1 + }, + "nullable": [] + }, + "hash": "1ebd5510a96bc84a88cc91316f891d372e750a74e2eb5a252a787cf571c326e4" +} diff --git a/nym-validator-rewarder/.sqlx/query-227e0cd05334ac228ca55f309f3738f6bda8532a5bd2d944884cd87784eefe43.json b/nym-validator-rewarder/.sqlx/query-227e0cd05334ac228ca55f309f3738f6bda8532a5bd2d944884cd87784eefe43.json new file mode 100644 index 00000000000..c21d9bd39ef --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-227e0cd05334ac228ca55f309f3738f6bda8532a5bd2d944884cd87784eefe43.json @@ -0,0 +1,26 @@ +{ + "db_name": "SQLite", + "query": "\n SELECT * FROM validator \n WHERE EXISTS (\n SELECT 1 FROM pre_commit\n WHERE height == ?\n AND pre_commit.validator_address = validator.consensus_address\n )\n ", + "describe": { + "columns": [ + { + "name": "consensus_address", + "ordinal": 0, + "type_info": "Text" + }, + { + "name": "consensus_pubkey", + "ordinal": 1, + "type_info": "Text" + } + ], + "parameters": { + "Right": 1 + }, + "nullable": [ + false, + false + ] + }, + "hash": "227e0cd05334ac228ca55f309f3738f6bda8532a5bd2d944884cd87784eefe43" +} diff --git a/nym-validator-rewarder/.sqlx/query-2561fb016951ea4cd29e43fb9a4a93e944b0d44ed1f7c1036f306e34372da11c.json b/nym-validator-rewarder/.sqlx/query-2561fb016951ea4cd29e43fb9a4a93e944b0d44ed1f7c1036f306e34372da11c.json new file mode 100644 index 00000000000..c4d9958ff84 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-2561fb016951ea4cd29e43fb9a4a93e944b0d44ed1f7c1036f306e34372da11c.json @@ -0,0 +1,20 @@ +{ + "db_name": "SQLite", + "query": "\n SELECT height\n FROM block\n ORDER BY height ASC\n LIMIT 1\n ", + "describe": { + "columns": [ + { + "name": "height", + "ordinal": 0, + "type_info": "Int64" + } + ], + "parameters": { + "Right": 0 + }, + "nullable": [ + true + ] + }, + "hash": "2561fb016951ea4cd29e43fb9a4a93e944b0d44ed1f7c1036f306e34372da11c" +} diff --git a/nym-validator-rewarder/.sqlx/query-2db92c21c933bc1eadc486867f7c8643ae77e22ad908147b910d9406234911f0.json b/nym-validator-rewarder/.sqlx/query-2db92c21c933bc1eadc486867f7c8643ae77e22ad908147b910d9406234911f0.json new file mode 100644 index 00000000000..13c8d883b84 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-2db92c21c933bc1eadc486867f7c8643ae77e22ad908147b910d9406234911f0.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n INSERT INTO ticketbook_issuance_rewarding_details(\n ticketbook_expiration_date,\n approximate_deposits,\n spent,\n rewarding_tx,\n rewarding_error,\n monitor_only\n ) VALUES (?, ?, ?, ?, ?, ?)\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 6 + }, + "nullable": [] + }, + "hash": "2db92c21c933bc1eadc486867f7c8643ae77e22ad908147b910d9406234911f0" +} diff --git a/nym-validator-rewarder/.sqlx/query-3227631b516dd16b8474e050393b9036df67d74966a35d9af74d43e93d3524eb.json b/nym-validator-rewarder/.sqlx/query-3227631b516dd16b8474e050393b9036df67d74966a35d9af74d43e93d3524eb.json new file mode 100644 index 00000000000..dd4aa3560e2 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-3227631b516dd16b8474e050393b9036df67d74966a35d9af74d43e93d3524eb.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "DELETE FROM block WHERE height < ?", + "describe": { + "columns": [], + "parameters": { + "Right": 1 + }, + "nullable": [] + }, + "hash": "3227631b516dd16b8474e050393b9036df67d74966a35d9af74d43e93d3524eb" +} diff --git a/nym-validator-rewarder/.sqlx/query-397bde15134e32921ad87037e9436dcb76982d7859e406daa12c97f671e6fd3b.json b/nym-validator-rewarder/.sqlx/query-397bde15134e32921ad87037e9436dcb76982d7859e406daa12c97f671e6fd3b.json new file mode 100644 index 00000000000..a1147e12e01 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-397bde15134e32921ad87037e9436dcb76982d7859e406daa12c97f671e6fd3b.json @@ -0,0 +1,20 @@ +{ + "db_name": "SQLite", + "query": "\n SELECT height\n FROM block\n WHERE timestamp < ?\n ORDER BY timestamp DESC\n LIMIT 1\n ", + "describe": { + "columns": [ + { + "name": "height", + "ordinal": 0, + "type_info": "Int64" + } + ], + "parameters": { + "Right": 1 + }, + "nullable": [ + true + ] + }, + "hash": "397bde15134e32921ad87037e9436dcb76982d7859e406daa12c97f671e6fd3b" +} diff --git a/nym-validator-rewarder/.sqlx/query-3b75821c30e4e2a87fea04c92a91cb75bd6df809fb1f17620ab888d184291f0b.json b/nym-validator-rewarder/.sqlx/query-3b75821c30e4e2a87fea04c92a91cb75bd6df809fb1f17620ab888d184291f0b.json new file mode 100644 index 00000000000..b979eb62c47 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-3b75821c30e4e2a87fea04c92a91cb75bd6df809fb1f17620ab888d184291f0b.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n INSERT INTO block_signing_rewarding_epoch (id, start_time, end_time, budget, disabled)\n VALUES (?, ?, ?, ?, ?)\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 5 + }, + "nullable": [] + }, + "hash": "3b75821c30e4e2a87fea04c92a91cb75bd6df809fb1f17620ab888d184291f0b" +} diff --git a/nym-validator-rewarder/.sqlx/query-3bdf81a9db6075f6f77224c30553f419a849d4ec45af40b052a4cbf09b44f3ec.json b/nym-validator-rewarder/.sqlx/query-3bdf81a9db6075f6f77224c30553f419a849d4ec45af40b052a4cbf09b44f3ec.json new file mode 100644 index 00000000000..0f91e82479e --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-3bdf81a9db6075f6f77224c30553f419a849d4ec45af40b052a4cbf09b44f3ec.json @@ -0,0 +1,20 @@ +{ + "db_name": "SQLite", + "query": "\n SELECT last_pruned_height FROM pruning\n ", + "describe": { + "columns": [ + { + "name": "last_pruned_height", + "ordinal": 0, + "type_info": "Int64" + } + ], + "parameters": { + "Right": 0 + }, + "nullable": [ + false + ] + }, + "hash": "3bdf81a9db6075f6f77224c30553f419a849d4ec45af40b052a4cbf09b44f3ec" +} diff --git a/nym-validator-rewarder/.sqlx/query-422a516baacf8ba26ea2dca46fa57ed06dbebb3615b912fa59d9e22a097ded57.json b/nym-validator-rewarder/.sqlx/query-422a516baacf8ba26ea2dca46fa57ed06dbebb3615b912fa59d9e22a097ded57.json new file mode 100644 index 00000000000..fe59f444cf1 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-422a516baacf8ba26ea2dca46fa57ed06dbebb3615b912fa59d9e22a097ded57.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n INSERT INTO \"transaction\" (hash, height, \"index\", success, num_messages, memo, gas_wanted, gas_used, raw_log)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (hash) DO UPDATE\n SET height = excluded.height,\n \"index\" = excluded.\"index\",\n success = excluded.success,\n num_messages = excluded.num_messages,\n memo = excluded.memo,\n gas_wanted = excluded.gas_wanted,\n gas_used = excluded.gas_used,\n raw_log = excluded.raw_log\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 9 + }, + "nullable": [] + }, + "hash": "422a516baacf8ba26ea2dca46fa57ed06dbebb3615b912fa59d9e22a097ded57" +} diff --git a/nym-validator-rewarder/.sqlx/query-6be3f8abfa7a2e05721e533e4128b10dd0f01a04f77634d09af260b97a155264.json b/nym-validator-rewarder/.sqlx/query-6be3f8abfa7a2e05721e533e4128b10dd0f01a04f77634d09af260b97a155264.json new file mode 100644 index 00000000000..edf75914cf0 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-6be3f8abfa7a2e05721e533e4128b10dd0f01a04f77634d09af260b97a155264.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n INSERT INTO block_signing_reward (\n rewarding_epoch_id,\n validator_consensus_address,\n operator_account,\n whitelisted,\n amount,\n voting_power,\n voting_power_share,\n signed_blocks,\n signed_blocks_percent\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 9 + }, + "nullable": [] + }, + "hash": "6be3f8abfa7a2e05721e533e4128b10dd0f01a04f77634d09af260b97a155264" +} diff --git a/nym-validator-rewarder/.sqlx/query-7c2aea05703247a865d5639bd84efa10eee3e1488f7bb990847374c09e8a5944.json b/nym-validator-rewarder/.sqlx/query-7c2aea05703247a865d5639bd84efa10eee3e1488f7bb990847374c09e8a5944.json new file mode 100644 index 00000000000..929cec20806 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-7c2aea05703247a865d5639bd84efa10eee3e1488f7bb990847374c09e8a5944.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "DELETE FROM pre_commit WHERE height < ?", + "describe": { + "columns": [], + "parameters": { + "Right": 1 + }, + "nullable": [] + }, + "hash": "7c2aea05703247a865d5639bd84efa10eee3e1488f7bb990847374c09e8a5944" +} diff --git a/nym-validator-rewarder/.sqlx/query-84e200c64ff49be7241d43841d0e35e94e172738678c7299334c47a54caf5c50.json b/nym-validator-rewarder/.sqlx/query-84e200c64ff49be7241d43841d0e35e94e172738678c7299334c47a54caf5c50.json new file mode 100644 index 00000000000..efc1aefbbdf --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-84e200c64ff49be7241d43841d0e35e94e172738678c7299334c47a54caf5c50.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n INSERT INTO block (height, hash, num_txs, total_gas, proposer_address, timestamp)\n VALUES (?, ?, ?, ?, ?, ?)\n ON CONFLICT DO NOTHING\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 6 + }, + "nullable": [] + }, + "hash": "84e200c64ff49be7241d43841d0e35e94e172738678c7299334c47a54caf5c50" +} diff --git a/nym-validator-rewarder/.sqlx/query-98b2ac25c05850c31990ce0b48fecb9fbe7b3636feb0d36cbad0610a0685cccc.json b/nym-validator-rewarder/.sqlx/query-98b2ac25c05850c31990ce0b48fecb9fbe7b3636feb0d36cbad0610a0685cccc.json new file mode 100644 index 00000000000..c994b238941 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-98b2ac25c05850c31990ce0b48fecb9fbe7b3636feb0d36cbad0610a0685cccc.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n INSERT INTO message (transaction_hash, \"index\", type, height)\n VALUES (?, ?, ?, ?)\n ON CONFLICT (transaction_hash, \"index\") DO UPDATE\n SET height = excluded.height,\n type = excluded.type\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 4 + }, + "nullable": [] + }, + "hash": "98b2ac25c05850c31990ce0b48fecb9fbe7b3636feb0d36cbad0610a0685cccc" +} diff --git a/nym-validator-rewarder/.sqlx/query-a3db765a00f07d80656e58a543500a9e2b6064f2252c66882fd4a7dd17e187cc.json b/nym-validator-rewarder/.sqlx/query-a3db765a00f07d80656e58a543500a9e2b6064f2252c66882fd4a7dd17e187cc.json new file mode 100644 index 00000000000..af56095d43a --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-a3db765a00f07d80656e58a543500a9e2b6064f2252c66882fd4a7dd17e187cc.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "DELETE FROM message WHERE height < ?", + "describe": { + "columns": [], + "parameters": { + "Right": 1 + }, + "nullable": [] + }, + "hash": "a3db765a00f07d80656e58a543500a9e2b6064f2252c66882fd4a7dd17e187cc" +} diff --git a/nym-validator-rewarder/.sqlx/query-b865ffb57fa5f31de74e0dce28a8d33ad532e06c270adc6f62c4fd6c40ecabcb.json b/nym-validator-rewarder/.sqlx/query-b865ffb57fa5f31de74e0dce28a8d33ad532e06c270adc6f62c4fd6c40ecabcb.json new file mode 100644 index 00000000000..69132402bef --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-b865ffb57fa5f31de74e0dce28a8d33ad532e06c270adc6f62c4fd6c40ecabcb.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n INSERT INTO ticketbook_issuance_epoch(\n expiration_date,\n total_budget,\n whitelist_size,\n budget_per_operator,\n disabled\n ) VALUES (?, ?, ?, ?, ?)\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 5 + }, + "nullable": [] + }, + "hash": "b865ffb57fa5f31de74e0dce28a8d33ad532e06c270adc6f62c4fd6c40ecabcb" +} diff --git a/nym-validator-rewarder/.sqlx/query-b9e16b5c6e11cfa2d3dfee8c0bf18384da48966d5a2b2de842e747ee1d7a5769.json b/nym-validator-rewarder/.sqlx/query-b9e16b5c6e11cfa2d3dfee8c0bf18384da48966d5a2b2de842e747ee1d7a5769.json new file mode 100644 index 00000000000..d17600cd486 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-b9e16b5c6e11cfa2d3dfee8c0bf18384da48966d5a2b2de842e747ee1d7a5769.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n INSERT INTO banned_ticketbook_issuer(\n operator_account,\n api_endpoint,\n banned_on,\n associated_ticketbook_expiration_date,\n reason,\n evidence\n ) VALUES (?, ?, ?, ?, ?, ?)\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 6 + }, + "nullable": [] + }, + "hash": "b9e16b5c6e11cfa2d3dfee8c0bf18384da48966d5a2b2de842e747ee1d7a5769" +} diff --git a/nym-validator-rewarder/.sqlx/query-be654926e94fb6a07ebb94dd526b310d02d77083207b6a42eb1f8e4dd80b00a8.json b/nym-validator-rewarder/.sqlx/query-be654926e94fb6a07ebb94dd526b310d02d77083207b6a42eb1f8e4dd80b00a8.json new file mode 100644 index 00000000000..ca3f00b385b --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-be654926e94fb6a07ebb94dd526b310d02d77083207b6a42eb1f8e4dd80b00a8.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "UPDATE metadata SET last_processed_height = MAX(last_processed_height, ?)", + "describe": { + "columns": [], + "parameters": { + "Right": 1 + }, + "nullable": [] + }, + "hash": "be654926e94fb6a07ebb94dd526b310d02d77083207b6a42eb1f8e4dd80b00a8" +} diff --git a/nym-validator-rewarder/.sqlx/query-c88d07fecc3f33deaa6e93db1469ce71582635df47f52dcf3fd1df4e7be6b96d.json b/nym-validator-rewarder/.sqlx/query-c88d07fecc3f33deaa6e93db1469ce71582635df47f52dcf3fd1df4e7be6b96d.json new file mode 100644 index 00000000000..e588b0a25ab --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-c88d07fecc3f33deaa6e93db1469ce71582635df47f52dcf3fd1df4e7be6b96d.json @@ -0,0 +1,20 @@ +{ + "db_name": "SQLite", + "query": "\n SELECT last_processed_height FROM metadata\n ", + "describe": { + "columns": [ + { + "name": "last_processed_height", + "ordinal": 0, + "type_info": "Int64" + } + ], + "parameters": { + "Right": 0 + }, + "nullable": [ + false + ] + }, + "hash": "c88d07fecc3f33deaa6e93db1469ce71582635df47f52dcf3fd1df4e7be6b96d" +} diff --git a/nym-validator-rewarder/.sqlx/query-ceb15dea9ac66e69cfc2fa8fbd57472d7a3c6080766ab0f02aba4c776545adad.json b/nym-validator-rewarder/.sqlx/query-ceb15dea9ac66e69cfc2fa8fbd57472d7a3c6080766ab0f02aba4c776545adad.json new file mode 100644 index 00000000000..38d47056a82 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-ceb15dea9ac66e69cfc2fa8fbd57472d7a3c6080766ab0f02aba4c776545adad.json @@ -0,0 +1,20 @@ +{ + "db_name": "SQLite", + "query": "\n SELECT operator_account\n FROM banned_ticketbook_issuer\n ", + "describe": { + "columns": [ + { + "name": "operator_account", + "ordinal": 0, + "type_info": "Text" + } + ], + "parameters": { + "Right": 0 + }, + "nullable": [ + false + ] + }, + "hash": "ceb15dea9ac66e69cfc2fa8fbd57472d7a3c6080766ab0f02aba4c776545adad" +} diff --git a/nym-validator-rewarder/.sqlx/query-d67b6b3fc1099b3ca48eed945d9873717ba4b9d8f83bcb05f8a39094f0ff7c32.json b/nym-validator-rewarder/.sqlx/query-d67b6b3fc1099b3ca48eed945d9873717ba4b9d8f83bcb05f8a39094f0ff7c32.json new file mode 100644 index 00000000000..0413a18c5b4 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-d67b6b3fc1099b3ca48eed945d9873717ba4b9d8f83bcb05f8a39094f0ff7c32.json @@ -0,0 +1,20 @@ +{ + "db_name": "SQLite", + "query": "\n SELECT COUNT(*) as count FROM pre_commit\n WHERE \n validator_address == ?\n AND height >= ? \n AND height <= ?\n ", + "describe": { + "columns": [ + { + "name": "count", + "ordinal": 0, + "type_info": "Int" + } + ], + "parameters": { + "Right": 3 + }, + "nullable": [ + false + ] + }, + "hash": "d67b6b3fc1099b3ca48eed945d9873717ba4b9d8f83bcb05f8a39094f0ff7c32" +} diff --git a/nym-validator-rewarder/.sqlx/query-dcb00d96a003c9ad0b6213ac6974f40adb4d74539bfe36432ae62a2b5268f5fd.json b/nym-validator-rewarder/.sqlx/query-dcb00d96a003c9ad0b6213ac6974f40adb4d74539bfe36432ae62a2b5268f5fd.json new file mode 100644 index 00000000000..1c629ba0ff0 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-dcb00d96a003c9ad0b6213ac6974f40adb4d74539bfe36432ae62a2b5268f5fd.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n INSERT INTO validator (consensus_address, consensus_pubkey)\n VALUES (?, ?)\n ON CONFLICT DO NOTHING\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 2 + }, + "nullable": [] + }, + "hash": "dcb00d96a003c9ad0b6213ac6974f40adb4d74539bfe36432ae62a2b5268f5fd" +} diff --git a/nym-validator-rewarder/.sqlx/query-e08a6456f6bd3cc5e8201d18dc3a989aecff01e835cb8fc04acee1b83480a970.json b/nym-validator-rewarder/.sqlx/query-e08a6456f6bd3cc5e8201d18dc3a989aecff01e835cb8fc04acee1b83480a970.json new file mode 100644 index 00000000000..a7a5ad47d10 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-e08a6456f6bd3cc5e8201d18dc3a989aecff01e835cb8fc04acee1b83480a970.json @@ -0,0 +1,20 @@ +{ + "db_name": "SQLite", + "query": "\n SELECT height\n FROM block\n WHERE timestamp > ?\n ORDER BY timestamp\n LIMIT 1\n ", + "describe": { + "columns": [ + { + "name": "height", + "ordinal": 0, + "type_info": "Int64" + } + ], + "parameters": { + "Right": 1 + }, + "nullable": [ + true + ] + }, + "hash": "e08a6456f6bd3cc5e8201d18dc3a989aecff01e835cb8fc04acee1b83480a970" +} diff --git a/nym-validator-rewarder/.sqlx/query-eba74b6531013fe5a83287bd50dab220797a39071754ad20bc14819fcced6c56.json b/nym-validator-rewarder/.sqlx/query-eba74b6531013fe5a83287bd50dab220797a39071754ad20bc14819fcced6c56.json new file mode 100644 index 00000000000..c3ce58bb1f9 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-eba74b6531013fe5a83287bd50dab220797a39071754ad20bc14819fcced6c56.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n INSERT INTO pre_commit (validator_address, height, timestamp, voting_power, proposer_priority)\n VALUES (?, ?, ?, ?, ?)\n ON CONFLICT (validator_address, timestamp) DO NOTHING\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 5 + }, + "nullable": [] + }, + "hash": "eba74b6531013fe5a83287bd50dab220797a39071754ad20bc14819fcced6c56" +} diff --git a/nym-validator-rewarder/.sqlx/query-fa2ea62ed8ccb08d0ef70bc212cbb5ca4bbbb50e7a7fcaacc5361dde3157247a.json b/nym-validator-rewarder/.sqlx/query-fa2ea62ed8ccb08d0ef70bc212cbb5ca4bbbb50e7a7fcaacc5361dde3157247a.json new file mode 100644 index 00000000000..4bbca101697 --- /dev/null +++ b/nym-validator-rewarder/.sqlx/query-fa2ea62ed8ccb08d0ef70bc212cbb5ca4bbbb50e7a7fcaacc5361dde3157247a.json @@ -0,0 +1,20 @@ +{ + "db_name": "SQLite", + "query": "\n SELECT expiration_date as \"expiration_date: Date\"\n FROM ticketbook_issuance_epoch\n ORDER BY expiration_date DESC\n LIMIT 1\n ", + "describe": { + "columns": [ + { + "name": "expiration_date: Date", + "ordinal": 0, + "type_info": "Date" + } + ], + "parameters": { + "Right": 0 + }, + "nullable": [ + false + ] + }, + "hash": "fa2ea62ed8ccb08d0ef70bc212cbb5ca4bbbb50e7a7fcaacc5361dde3157247a" +} diff --git a/nyx-chain-watcher/src/db/models.rs b/nyx-chain-watcher/src/db/models.rs index 9a433ee8ec9..ce99cedb892 100644 --- a/nyx-chain-watcher/src/db/models.rs +++ b/nyx-chain-watcher/src/db/models.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use utoipa::ToSchema; -#[derive(Clone, Deserialize, Debug)] +#[derive(Clone, Deserialize, Debug, ToSchema)] pub(crate) struct CurrencyPrices { pub(crate) chf: f32, pub(crate) usd: f32, diff --git a/nyx-chain-watcher/src/models.rs b/nyx-chain-watcher/src/models.rs index 93a9f9e5923..ce1c0886f4a 100644 --- a/nyx-chain-watcher/src/models.rs +++ b/nyx-chain-watcher/src/models.rs @@ -9,7 +9,18 @@ pub struct WebhookPayload { pub message_index: u64, pub sender_address: String, pub receiver_address: String, + #[schema(value_type = openapi_schema::Coin)] pub funds: CosmWasmCoin, pub height: u128, pub memo: Option, } + +pub mod openapi_schema { + use super::*; + + #[derive(ToSchema)] + pub struct Coin { + pub denom: String, + pub amount: String, + } +}