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
This commit is contained in:
dynco-nym
2024-12-20 12:18:45 +01:00
committed by GitHub
parent 7d5e3ef7d3
commit 41fb17a31b
114 changed files with 1116 additions and 443 deletions
+1
View File
@@ -0,0 +1 @@
nym-validator-rewarder/.sqlx/** diff=nodiff
+2 -1
View File
@@ -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
.build
Generated
+48 -94
View File
@@ -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",
]
+3 -3
View File
@@ -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"
+23
View File
@@ -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.
@@ -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 = []
naive_float = []
utoipa = ["dep:utoipa"]
@@ -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")]
@@ -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<Addr>,
}
@@ -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<String>))]
pub proxy: Option<Addr>,
/// 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<u32>))]
pub pledge_change: Option<EpochEventId>,
}
@@ -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<u16>,
/// 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<u32>))]
pub pledge_change: Option<EpochEventId>,
#[cfg_attr(feature = "utoipa", schema(value_type = Option<u32>))]
pub cost_params_change: Option<IntervalEventId>,
}
@@ -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,
@@ -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,
}
@@ -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 {
+1
View File
@@ -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" }
@@ -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:*
-1
View File
@@ -10,7 +10,6 @@ use serde::{Deserialize, Serialize};
pub mod middleware;
#[derive(Debug, Clone)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub enum FormattedResponse<T> {
Json(Json<T>),
Yaml(Yaml<T>),
+1 -1
View File
@@ -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"]
par_verify = ["rayon"]
@@ -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)]
+1 -1
View File
@@ -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;
+2 -1
View File
@@ -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 }
serde_json = { workspace = true }
+9 -6
View File
@@ -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<Sha256>,
included_leaves: Vec<MerkleLeaf>,
total_leaves: usize,
#[schemars(with = "String")]
#[serde(with = "nym_serde_helpers::hex")]
root: Vec<u8>,
+1
View File
@@ -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 }
+4 -2
View File
@@ -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<HashSet<String>> = LazyLock::new(|| {
let mut nm = HashSet::new();
@@ -10,8 +11,9 @@ static NETWORK_MONITORS: LazyLock<HashSet<String>> = 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<NodeResult>),
}
#[derive(Serialize, Deserialize, JsonSchema)]
#[derive(Serialize, Deserialize, JsonSchema, ToSchema)]
pub struct MonitorMessage {
results: Vec<NodeResult>,
signature: String,
+1
View File
@@ -95,6 +95,7 @@ allow = [
"Apache-2.0",
"BSD-2-Clause",
"BSD-3-Clause",
"BSL-1.0",
"ISC",
"0BSD",
"MPL-2.0",
+1 -1
View File
@@ -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" }
+1 -1
View File
@@ -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" }
+209 -63
View File
@@ -1,7 +1,6 @@
// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net>
// 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<AnnotatedExpirationDateSignature>,
}
#[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<AnnotatedCoinIndexSignature>,
}
#[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<openapi_schema::AnnotatedExpirationDateSignature>)]
pub signatures: Vec<AnnotatedExpirationDateSignature>,
}
#[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<AnnotatedCoinIndexSignature>,
}
#[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<String>)]
pub(crate) beta_g1: Vec<G1Projective>,
#[schema(value_type = Vec<String>)]
pub(crate) beta_g2: Vec<G2Projective>,
}
#[derive(ToSchema)]
pub struct WithdrawalRequest {
#[schema(value_type = String)]
joined_commitment_hash: G1Projective,
#[schema(value_type = String)]
joined_commitment: G1Projective,
#[schema(value_type = Vec<String>)]
private_attributes_commitments: Vec<G1Projective>,
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<String>)]
response_openings: Vec<Scalar>,
#[schema(value_type = Vec<String>)]
response_attributes: Vec<Scalar>,
}
#[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<String>)]
pub kappa_k: Vec<G2Projective>,
pub omega: Vec<Signature>,
#[schema(value_type = Vec<String>)]
pub ss: Vec<G1Projective>,
#[schema(value_type = Vec<String>)]
pub tt: Vec<G1Projective>,
#[schema(value_type = Vec<String>)]
pub aa: Vec<G1Projective>,
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<String>)]
responses_r_k: Vec<Scalar>,
#[schema(value_type = Vec<String>)]
responses_l: Vec<Scalar>,
#[schema(value_type = Vec<String>)]
responses_o_a: Vec<Scalar>,
#[schema(value_type = String)]
response_o_c: Scalar,
#[schema(value_type = Vec<String>)]
responses_mu: Vec<Scalar>,
#[schema(value_type = Vec<String>)]
responses_o_mu: Vec<Scalar>,
#[schema(value_type = Vec<String>)]
responses_attributes: Vec<Scalar>,
}
}
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct Pagination<T> {
/// 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<T> {
pub limit: Option<u32>,
}
#[derive(Clone, Serialize, Deserialize, Debug, JsonSchema, PartialEq)]
pub struct SerialNumberWrapper(
#[serde(with = "nym_serde_helpers::bs58")]
#[schemars(with = "String")]
Vec<u8>,
);
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, ToSchema)]
pub struct SerialNumberWrapper(#[serde(with = "nym_serde_helpers::bs58")] Vec<u8>);
impl Deref for SerialNumberWrapper {
type Target = Vec<u8>;
@@ -323,14 +468,13 @@ impl From<Vec<u8>> 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<u8>,
pub included_serial_numbers: Vec<SerialNumberWrapper>,
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<u8>,
}
@@ -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<CommitedDeposit>,
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<u32>)]
pub deposits: Vec<DepositId>,
}
#[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<u32, IssuedTicketbook>)]
pub partial_ticketbooks: BTreeMap<DepositId, IssuedTicketbook>,
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,
}
+1 -1
View File
@@ -52,7 +52,7 @@ impl From<LegacyMixNodeBondWithLayer> 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,
+33 -12
View File
@@ -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<DisplayRole> 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<DisplayRole> 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<DisplayRole>,
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<String>)]
pub ip_addresses: Vec<IpAddr>,
}
@@ -471,11 +475,13 @@ pub struct GatewayBondAnnotated {
pub self_described: Option<GatewayDescription>,
// 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<String>)]
pub ip_addresses: Vec<IpAddr>,
}
@@ -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<String>)]
#[param(value_type = Option<String>)]
pub performance: Option<Performance>,
pub active_in_rewarded_set: Option<bool>,
pub pledge_amount: Option<u64>,
pub total_delegation: Option<u64>,
#[schema(value_type = CoinSchema)]
#[schema(value_type = Option<CoinSchema>)]
#[param(value_type = Option<CoinSchema>)]
pub interval_operating_cost: Option<Coin>,
#[schema(value_type = String)]
#[schema(value_type = Option<String>)]
#[param(value_type = Option<String>)]
pub profit_margin_percent: Option<Percent>,
}
@@ -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<String>)]
pub ip_address: Vec<IpAddr>,
pub hostname: Option<String>,
pub keys: HostKeys,
@@ -844,15 +857,18 @@ impl From<nym_node_requests::api::v1::node::models::HostInformation> 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<String>")]
#[schema(value_type = String)]
pub x25519_noise: Option<x25519::PublicKey>,
}
@@ -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<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, Default)]
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, Default, ToSchema)]
pub struct TestNode {
pub node_id: Option<u32>,
pub identity_key: Option<String>,
}
#[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<String>)]
pub ip_addresses: Vec<IpAddr>,
}
@@ -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,
}
+6 -4
View File
@@ -14,19 +14,19 @@ use std::net::IpAddr;
use time::OffsetDateTime;
use utoipa::ToSchema;
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema)]
pub struct CachedNodesResponse<T> {
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, ToSchema)]
pub struct CachedNodesResponse<T: ToSchema> {
pub refreshed_at: OffsetDateTimeJsonSchemaWrapper,
pub nodes: Vec<T>,
}
impl<T> From<Vec<T>> for CachedNodesResponse<T> {
impl<T: ToSchema> From<Vec<T>> for CachedNodesResponse<T> {
fn from(nodes: Vec<T>) -> Self {
CachedNodesResponse::new(nodes)
}
}
impl<T> CachedNodesResponse<T> {
impl<T: ToSchema> CachedNodesResponse<T> {
pub fn new(nodes: Vec<T>) -> 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<String>)]
@@ -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")]
+47
View File
@@ -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'
+12
View File
@@ -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
+27
View File
@@ -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
+5
View File
@@ -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
+2 -2
View File
@@ -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(
@@ -42,7 +42,7 @@ pub(crate) fn partial_signing_routes() -> Router<AppState> {
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(
+3 -3
View File
@@ -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]
+16 -2
View File
@@ -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<String>,
pub(crate) details: Option<ContractVersionSchemaResponse>,
}
#[utoipa::path(
tag = "network",
get,
path = "/v1/network/nym-contracts",
responses(
(status = 200, body = HashMap<String, ContractInformation<ContractVersionSchemaResponse>>)
(status = 200, body = HashMap<String, ContractInformationContractVersion>)
)
)]
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<String>,
pub(crate) details: Option<ContractBuildInformation>,
}
#[utoipa::path(
tag = "network",
get,
path = "/v1/network/nym-contracts-detailed",
responses(
(status = 200, body = HashMap<String, ContractInformation<ContractBuildInformation>>)
(status = 200, body = HashMap<String, ContractInformationBuildInformation>)
)
)]
async fn nym_contracts_detailed(
+3 -2
View File
@@ -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<T> {
pub(crate) address: Option<String>,
@@ -1,6 +1,8 @@
// Copyright 2021-2024 - Nym Technologies SA <contact@nymtech.net>
// 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<AppState> {
Router::new()
.route(
@@ -63,9 +63,9 @@ pub(super) fn mandatory_routes() -> Router<AppState> {
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]
+11 -3
View File
@@ -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<Uptime> 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<HistoricalUptime> for OldHistoricalUptimeResponse {
// TODO rocket remove smurf name after eliminating `rocket`
pub(crate) type AxumResult<T> = Result<T, AxumErrorResponse>;
// #[derive(ToSchema, ToResponse)]
// #[schema(title = "ErrorResponse")]
pub(crate) struct AxumErrorResponse {
message: RequestError,
// #[schema(value_type = u16)]
status: StatusCode,
}
+2 -2
View File
@@ -27,7 +27,7 @@ pub(crate) fn legacy_nym_node_routes() -> Router<AppState> {
get,
path = "/v1/gateways/described",
responses(
(status = 200, body = Vec<DescribedGateway>)
(status = 200, body = Vec<LegacyDescribedGateway>)
)
)]
#[deprecated]
@@ -81,7 +81,7 @@ async fn get_gateways_described(
get,
path = "/v1/mixnodes/described",
responses(
(status = 200, body = Vec<DescribedMixNode>)
(status = 200, body = Vec<LegacyDescribedMixNode>)
)
)]
#[deprecated]
@@ -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<FullFatNode>)
@@ -88,6 +88,7 @@ struct NodesParamsWithRole {
}
#[derive(Debug, Deserialize, utoipa::IntoParams)]
#[into_params(parameter_in = Query)]
struct NodesParams {
#[allow(dead_code)]
semver_compatibility: Option<String>,
@@ -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<SemiSkimmedNode>)
@@ -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<Json<PaginatedCachedNodesResponse<SkimmedNode>>>;
@@ -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<SkimmedNode>,
}
/// 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<SkimmedNode>)
(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<SkimmedNode>)
(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<SkimmedNode>)
(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<SkimmedNode>)
(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<SkimmedNode>)
(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<SkimmedNode>)
(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<SkimmedNode>)
(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<SkimmedNode>)
(status = 200, body = PaginatedCachedNodesResponseSchema)
)
)]
pub(super) async fn exit_gateways_basic_all(
+2
View File
@@ -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)]
+13 -67
View File
@@ -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<ContractVersionSchemaResponse>,
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;
@@ -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<String>, example = "c48f9ce3-a1e9-4886-8000-13f290f34501"))]
pub uuid: Option<Uuid>,
pub message: String,
}
@@ -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,
}
@@ -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),
)]
@@ -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(
@@ -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(
@@ -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,
}
@@ -27,7 +27,7 @@ pub(crate) fn routes() -> Router<AppState> {
),
path = "/v2/gateways",
responses(
(status = 200, body = PagedGateway)
(status = 200, body = PagedResult<Gateway>)
)
)]
async fn gateways(
@@ -48,7 +48,7 @@ async fn gateways(
),
path = "/v2/gateways/skinny",
responses(
(status = 200, body = PagedGatewaySkinny)
(status = 200, body = PagedResult<GatewaySkinny>)
)
)]
async fn gateways_skinny(
@@ -35,7 +35,7 @@ pub(crate) struct SessionQueryParams {
),
path = "/v2/metrics/sessions",
responses(
(status = 200, body = PagedSessionStats)
(status = 200, body = PagedResult<SessionStats>)
)
)]
#[instrument(level = tracing::Level::DEBUG, skip(state))]
@@ -28,7 +28,7 @@ pub(crate) fn routes() -> Router<AppState> {
),
path = "/v2/mixnodes",
responses(
(status = 200, body = PagedMixnode)
(status = 200, body = PagedResult<Mixnode>)
)
)]
#[instrument(level = tracing::Level::DEBUG, skip_all, fields(page=pagination.page, size=pagination.size))]
@@ -35,7 +35,7 @@ pub(crate) struct ServicesQueryParams {
),
path = "/v2/services",
responses(
(status = 200, body = PagedService)
(status = 200, body = PagedResult<Service>)
)
)]
#[instrument(level = tracing::Level::DEBUG, skip(state))]
@@ -1,4 +1,3 @@
use crate::http::{Gateway, GatewaySkinny, Mixnode, Service, SessionStats};
use utoipa::OpenApi;
use utoipauto::utoipauto;
@@ -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<Gateway>,
PagedGatewaySkinny = PagedResult<GatewaySkinny>,
PagedMixnode = PagedResult<Mixnode>,
PagedService = PagedResult<Service>,
PagedSessionStats = PagedResult<SessionStats>
)]
pub struct PagedResult<T> {
pub struct PagedResult<T: ToSchema> {
pub page: usize,
pub size: usize,
pub total: usize,
pub items: Vec<T>,
}
impl<T: Clone> PagedResult<T> {
impl<T: Clone + ToSchema> PagedResult<T> {
pub fn paginate(pagination: Pagination, res: Vec<T>) -> Self {
let total = res.len();
let (size, mut page) = pagination.intoto_inner_values();
+1 -1
View File
@@ -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",
] }
+10 -8
View File
@@ -1,15 +1,14 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// 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<HostInformation>;
pub type SignedHostInformation = SignedData<crate::api::v1::node::models::HostInformation>;
#[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<HostInformation>))]
pub struct SignedData<T> {
// #[serde(flatten)]
pub data: T,
@@ -90,7 +93,6 @@ impl<T> Deref for SignedData<T> {
}
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)]
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
pub struct ErrorResponse {
pub message: String,
}
@@ -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<VerlocNodeResult>,
}
#[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<VerlocMeasurement>,
}
#[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,
@@ -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<String>")]
#[cfg_attr(feature = "openapi", schema(value_type = Option<String>))]
pub x25519_noise: Option<x25519::PublicKey>,
}
@@ -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)
@@ -45,8 +45,8 @@ pub(crate) fn routes<S: Send + Sync + 'static + Clone>(
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<ClientInterfaces>;
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<WebSockets>;
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)
@@ -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)
@@ -14,8 +14,8 @@ use nym_node_requests::api::v1::health::models::NodeHealth;
tag = "Health",
responses(
(status = 200, content(
("application/json" = Vec<NodeHealth>),
("application/yaml" = Vec<NodeHealth>)
(Vec<NodeHealth> = "application/json"),
(Vec<NodeHealth> = "application/yaml")
), description = "the api is available and healthy")
),
params(OutputParams)
@@ -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)
@@ -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),
@@ -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),
@@ -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),
@@ -1,14 +1,15 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// 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(),
}
@@ -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),
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
)]
@@ -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)
@@ -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)
@@ -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),
)]
+1 -3
View File
@@ -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,
@@ -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"
}
@@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "UPDATE pruning SET last_pruned_height = ?",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "0e03fcbde46a0296e029624ae083381fe8e839998717e6d1a0502f54438fc9b0"
}
@@ -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"
}
@@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "DELETE FROM \"transaction\" WHERE height < ?",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "1ebd5510a96bc84a88cc91316f891d372e750a74e2eb5a252a787cf571c326e4"
}
@@ -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"
}
@@ -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"
}
@@ -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"
}
@@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "DELETE FROM block WHERE height < ?",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "3227631b516dd16b8474e050393b9036df67d74966a35d9af74d43e93d3524eb"
}
@@ -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"
}
@@ -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"
}
@@ -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"
}
@@ -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"
}
@@ -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"
}
@@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "DELETE FROM pre_commit WHERE height < ?",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "7c2aea05703247a865d5639bd84efa10eee3e1488f7bb990847374c09e8a5944"
}
@@ -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"
}

Some files were not shown because too many files have changed in this diff Show More