nym_mixnet_contract_common/
gateway.rs1use crate::{IdentityKey, NodeId, SphinxKey};
5use cosmwasm_schema::cw_serde;
6use cosmwasm_std::{Addr, Coin, to_json_string};
7use std::cmp::Ordering;
8use std::fmt::Display;
9
10#[cw_serde]
12#[derive(PartialOrd)]
13#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
14pub struct Gateway {
15 pub host: String,
17
18 pub mix_port: u16,
20
21 pub clients_port: u16,
23
24 pub location: String,
27
28 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
30 pub sphinx_key: SphinxKey,
31
32 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
34 pub identity_key: IdentityKey,
35
36 pub version: String,
38}
39
40#[cw_serde]
42#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
43pub struct GatewayBond {
44 #[cfg_attr(feature = "utoipa", schema(value_type = crate::CoinSchema))]
46 pub pledge_amount: Coin,
47
48 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
50 pub owner: Addr,
51
52 pub block_height: u64,
54
55 pub gateway: Gateway,
57
58 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
61 pub proxy: Option<Addr>,
62}
63
64impl GatewayBond {
65 pub fn new(pledge_amount: Coin, owner: Addr, block_height: u64, gateway: Gateway) -> Self {
66 GatewayBond {
67 pledge_amount,
68 owner,
69 block_height,
70 gateway,
71 proxy: None,
72 }
73 }
74
75 pub fn identity(&self) -> &String {
76 &self.gateway.identity_key
77 }
78
79 pub fn pledge_amount(&self) -> Coin {
80 self.pledge_amount.clone()
81 }
82
83 pub fn owner(&self) -> &Addr {
84 &self.owner
85 }
86
87 pub fn gateway(&self) -> &Gateway {
88 &self.gateway
89 }
90}
91
92impl PartialOrd for GatewayBond {
93 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
94 if self.pledge_amount.denom != other.pledge_amount.denom {
96 return None;
97 }
98
99 let pledge_cmp = self
101 .pledge_amount
102 .amount
103 .partial_cmp(&other.pledge_amount.amount)?;
104 if pledge_cmp != Ordering::Equal {
105 return Some(pledge_cmp);
106 }
107
108 let height_cmp = self.block_height.partial_cmp(&other.block_height)?;
110 if height_cmp != Ordering::Equal {
111 return Some(height_cmp);
112 }
113
114 let owner_cmp = self.owner.partial_cmp(&other.owner)?;
117 if owner_cmp != Ordering::Equal {
118 return Some(owner_cmp);
119 }
120
121 self.gateway.partial_cmp(&other.gateway)
122 }
123}
124
125impl Display for GatewayBond {
126 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127 write!(
128 f,
129 "amount: {} {}, owner: {}, identity: {}",
130 self.pledge_amount.amount,
131 self.pledge_amount.denom,
132 self.owner,
133 self.gateway.identity_key
134 )
135 }
136}
137
138#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
139#[cfg_attr(
140 feature = "generate-ts",
141 ts(
142 export,
143 export_to = "ts-packages/types/src/types/rust/GatewayConfigUpdate.ts"
144 )
145)]
146#[cw_serde]
147pub struct GatewayConfigUpdate {
148 pub host: String,
149 pub mix_port: u16,
150 pub clients_port: u16,
151 pub location: String,
152 pub version: String,
153}
154
155impl GatewayConfigUpdate {
156 pub fn to_inline_json(&self) -> String {
157 to_json_string(self).unwrap_or_else(|_| "serialisation failure".into())
158 }
159}
160
161#[cw_serde]
163pub struct PagedGatewayResponse {
164 pub nodes: Vec<GatewayBond>,
166
167 pub per_page: usize,
170
171 pub start_next_after: Option<IdentityKey>,
173}
174
175impl PagedGatewayResponse {
176 pub fn new(
177 nodes: Vec<GatewayBond>,
178 per_page: usize,
179 start_next_after: Option<IdentityKey>,
180 ) -> Self {
181 PagedGatewayResponse {
182 nodes,
183 per_page,
184 start_next_after,
185 }
186 }
187}
188
189#[cw_serde]
191pub struct GatewayOwnershipResponse {
192 pub address: Addr,
194
195 pub gateway: Option<GatewayBond>,
197}
198
199#[cw_serde]
201pub struct GatewayBondResponse {
202 pub identity: IdentityKey,
204
205 pub gateway: Option<GatewayBond>,
207}
208
209#[cw_serde]
210pub struct PreassignedId {
211 pub identity: IdentityKey,
213
214 pub node_id: NodeId,
216}
217
218#[cw_serde]
219pub struct PreassignedGatewayIdsResponse {
220 pub ids: Vec<PreassignedId>,
221
222 pub start_next_after: Option<IdentityKey>,
224}
225
226#[cfg(test)]
227mod tests {
228 use super::*;
229
230 fn gateway_fixture() -> Gateway {
231 Gateway {
232 host: "1.1.1.1".to_string(),
233 mix_port: 123,
234 clients_port: 456,
235 location: "foomplandia".to_string(),
236 sphinx_key: "sphinxkey".to_string(),
237 identity_key: "identitykey".to_string(),
238 version: "0.11.0".to_string(),
239 }
240 }
241
242 #[test]
243 fn gateway_bond_partial_ord() {
244 let _150foos = Coin::new(150u32, "foo");
245 let _140foos = Coin::new(140u32, "foo");
246 let _50foos = Coin::new(50u32, "foo");
247 let _0foos = Coin::new(0u32, "foo");
248
249 let gate1 = GatewayBond {
250 pledge_amount: _150foos.clone(),
251 owner: Addr::unchecked("foo1"),
252 block_height: 100,
253 gateway: gateway_fixture(),
254 proxy: None,
255 };
256
257 let gate2 = GatewayBond {
258 pledge_amount: _150foos,
259 owner: Addr::unchecked("foo2"),
260 block_height: 120,
261 gateway: gateway_fixture(),
262 proxy: None,
263 };
264
265 let gate3 = GatewayBond {
266 pledge_amount: _50foos,
267 owner: Addr::unchecked("foo3"),
268 block_height: 120,
269 gateway: gateway_fixture(),
270 proxy: None,
271 };
272
273 let gate4 = GatewayBond {
274 pledge_amount: _140foos,
275 owner: Addr::unchecked("foo4"),
276 block_height: 120,
277 gateway: gateway_fixture(),
278 proxy: None,
279 };
280
281 let gate5 = GatewayBond {
282 pledge_amount: _0foos,
283 owner: Addr::unchecked("foo5"),
284 block_height: 120,
285 gateway: gateway_fixture(),
286 proxy: None,
287 };
288
289 assert!(gate1 > gate4);
301 assert!(gate1 > gate5);
302
303 assert!(gate1 > gate3);
305 assert!(gate4 > gate5);
307
308 assert!(gate1 < gate2);
310 }
311}