Skip to content

Commit dd3dcfa

Browse files
authored
Treat gateways as Nym Nodes (#5504)
* Generate GW moniker if missing Beside that: - clear up gw nomenclature - adjust counting when legacy nodes are present in nym node APIs - create utils module * Store gatewy descriptions * Clippy & version
1 parent 86ea2d2 commit dd3dcfa

File tree

16 files changed

+359
-181
lines changed

16 files changed

+359
-181
lines changed

Cargo.lock

+5-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nym-node-status-api/nym-node-status-api/Cargo.toml

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
[package]
55
name = "nym-node-status-api"
6-
version = "1.0.0-rc.10"
6+
version = "1.0.0"
77
authors.workspace = true
88
repository.workspace = true
99
homepage.workspace = true
@@ -16,11 +16,13 @@ rust-version.workspace = true
1616
ammonia = { workspace = true }
1717
anyhow = { workspace = true }
1818
axum = { workspace = true, features = ["tokio", "macros"] }
19+
bip39 = { workspace = true }
1920
chrono = { workspace = true }
2021
clap = { workspace = true, features = ["cargo", "derive", "env", "string"] }
2122
cosmwasm-std = { workspace = true }
2223
envy = { workspace = true }
2324
futures-util = { workspace = true }
25+
itertools = { workspace = true }
2426
moka = { workspace = true, features = ["future"] }
2527
nym-contracts-common = { path = "../../common/cosmwasm-smart-contracts/contracts-common" }
2628
nym-bin-common = { path = "../../common/bin-common", features = ["models"] }
@@ -33,6 +35,8 @@ nym-statistics-common = { path = "../../common/statistics" }
3335
nym-validator-client = { path = "../../common/client-libs/validator-client" }
3436
nym-task = { path = "../../common/task" }
3537
nym-node-requests = { path = "../../nym-node/nym-node-requests", features = ["openapi"] }
38+
rand = { workspace = true }
39+
rand_chacha = { workspace = true }
3640
regex = { workspace = true }
3741
reqwest = { workspace = true }
3842
serde = { workspace = true, features = ["derive"] }

nym-node-status-api/nym-node-status-api/src/db/models.rs

+21-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::str::FromStr;
22

33
use crate::{
44
http::{self, models::SummaryHistory},
5-
monitor::NumericalCheckedCast,
5+
utils::NumericalCheckedCast,
66
};
77
use anyhow::Context;
88
use nym_contracts_common::Percent;
@@ -16,7 +16,7 @@ use strum_macros::{EnumString, FromRepr};
1616
use time::{Date, OffsetDateTime};
1717
use utoipa::ToSchema;
1818

19-
pub(crate) struct GatewayRecord {
19+
pub(crate) struct GatewayInsertRecord {
2020
pub(crate) identity_key: String,
2121
pub(crate) bonded: bool,
2222
pub(crate) self_described: String,
@@ -360,14 +360,24 @@ impl TryFrom<GatewaySessionsRecord> for http::models::SessionStats {
360360
}
361361
}
362362

363-
pub(crate) enum MixingNodeKind {
364-
LegacyMixnode,
365-
NymNode,
363+
pub(crate) enum ScrapeNodeKind {
364+
LegacyMixnode { mix_id: i64 },
365+
MixingNymNode { node_id: i64 },
366+
EntryExitNymNode { node_id: i64, identity_key: String },
367+
}
368+
369+
impl ScrapeNodeKind {
370+
pub(crate) fn node_id(&self) -> &i64 {
371+
match self {
372+
ScrapeNodeKind::LegacyMixnode { mix_id } => mix_id,
373+
ScrapeNodeKind::MixingNymNode { node_id } => node_id,
374+
ScrapeNodeKind::EntryExitNymNode { node_id, .. } => node_id,
375+
}
376+
}
366377
}
367378

368379
pub(crate) struct ScraperNodeInfo {
369-
pub node_id: i64,
370-
pub node_kind: MixingNodeKind,
380+
pub node_kind: ScrapeNodeKind,
371381
pub hosts: Vec<String>,
372382
pub http_api_port: i64,
373383
}
@@ -390,6 +400,10 @@ impl ScraperNodeInfo {
390400

391401
urls
392402
}
403+
404+
pub(crate) fn node_id(&self) -> &i64 {
405+
self.node_kind.node_id()
406+
}
393407
}
394408

395409
#[derive(sqlx::Decode, Debug)]

nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs

+22-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
use std::collections::HashSet;
2+
13
use crate::{
24
db::{
3-
models::{GatewayDto, GatewayRecord},
5+
models::{GatewayDto, GatewayInsertRecord},
46
DbPool,
57
},
68
http::models::Gateway,
@@ -30,7 +32,7 @@ pub(crate) async fn select_gateway_identity(
3032

3133
pub(crate) async fn insert_gateways(
3234
pool: &DbPool,
33-
gateways: Vec<GatewayRecord>,
35+
gateways: Vec<GatewayInsertRecord>,
3436
) -> anyhow::Result<()> {
3537
let mut db = pool.acquire().await?;
3638
for record in gateways {
@@ -98,3 +100,21 @@ pub(crate) async fn get_all_gateways(pool: &DbPool) -> anyhow::Result<Vec<Gatewa
98100
tracing::trace!("Fetched {} gateways from DB", items.len());
99101
Ok(items)
100102
}
103+
104+
pub(crate) async fn get_all_gateway_id_keys(pool: &DbPool) -> anyhow::Result<HashSet<String>> {
105+
let mut conn = pool.acquire().await?;
106+
let items = sqlx::query!(
107+
r#"
108+
SELECT gateway_identity_key
109+
FROM gateways
110+
WHERE bonded = true
111+
"#
112+
)
113+
.fetch_all(&mut *conn)
114+
.await?
115+
.into_iter()
116+
.map(|record| record.gateway_identity_key)
117+
.collect::<HashSet<_>>();
118+
119+
Ok(items)
120+
}

nym-node-status-api/nym-node-status-api/src/db/queries/mixnodes.rs

+20
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::collections::HashSet;
2+
13
use futures_util::TryStreamExt;
24
use tracing::error;
35

@@ -124,3 +126,21 @@ pub(crate) async fn get_daily_stats(pool: &DbPool) -> anyhow::Result<Vec<DailySt
124126

125127
Ok(items)
126128
}
129+
130+
pub(crate) async fn get_all_mix_ids(pool: &DbPool) -> anyhow::Result<HashSet<i64>> {
131+
let mut conn = pool.acquire().await?;
132+
let items = sqlx::query!(
133+
r#"
134+
SELECT mix_id
135+
FROM mixnodes
136+
WHERE bonded = true
137+
"#
138+
)
139+
.fetch_all(&mut *conn)
140+
.await?
141+
.into_iter()
142+
.map(|record| record.mix_id)
143+
.collect::<HashSet<_>>();
144+
145+
Ok(items)
146+
}

nym-node-status-api/nym-node-status-api/src/db/queries/mod.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ pub(crate) mod scraper;
88
mod summary;
99
pub(crate) mod testruns;
1010

11-
pub(crate) use gateways::{get_all_gateways, insert_gateways, select_gateway_identity};
11+
pub(crate) use gateways::{
12+
get_all_gateway_id_keys, get_all_gateways, insert_gateways, select_gateway_identity,
13+
};
1214
pub(crate) use gateways_stats::{delete_old_records, get_sessions_stats, insert_session_records};
1315
pub(crate) use misc::insert_summaries;
14-
pub(crate) use mixnodes::{get_all_mixnodes, get_daily_stats, insert_mixnodes};
16+
pub(crate) use mixnodes::{get_all_mix_ids, get_all_mixnodes, get_daily_stats, insert_mixnodes};
1517
pub(crate) use nym_nodes::{get_nym_nodes, insert_nym_nodes};
1618
pub(crate) use packet_stats::{
1719
get_raw_node_stats, insert_daily_node_stats, insert_node_packet_stats,
1820
};
19-
pub(crate) use scraper::{get_mixing_nodes_for_scraping, insert_scraped_node_description};
21+
pub(crate) use scraper::{get_nodes_for_scraping, insert_scraped_node_description};
2022
pub(crate) use summary::{get_summary, get_summary_history};

nym-node-status-api/nym-node-status-api/src/db/queries/nym_nodes.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::collections::HashMap;
22

3+
use anyhow::Context;
34
use futures_util::TryStreamExt;
45
use nym_validator_client::{client::NymNodeDetails, nym_api::SkimmedNode};
56
use tracing::instrument;
@@ -9,7 +10,7 @@ use crate::{
910
models::{NymNodeDto, NymNodeInsertRecord},
1011
DbPool,
1112
},
12-
monitor::decimal_to_i64,
13+
utils::decimal_to_i64,
1314
};
1415

1516
pub(crate) async fn get_nym_nodes(pool: &DbPool) -> anyhow::Result<Vec<SkimmedNode>> {
@@ -100,7 +101,8 @@ pub(crate) async fn insert_nym_nodes(
100101
record.last_updated_utc,
101102
)
102103
.execute(&mut *conn)
103-
.await?;
104+
.await
105+
.with_context(|| format!("node_id={}", record.node_id))?;
104106
}
105107

106108
Ok(())

nym-node-status-api/nym-node-status-api/src/db/queries/packet_stats.rs

+18-16
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
11
use crate::db::{
2-
models::{MixingNodeKind, NodeStats, ScraperNodeInfo},
2+
models::{NodeStats, ScrapeNodeKind, ScraperNodeInfo},
33
DbPool,
44
};
55
use anyhow::Result;
66

77
pub(crate) async fn insert_node_packet_stats(
88
pool: &DbPool,
9-
node_id: i64,
10-
node_kind: &MixingNodeKind,
9+
node_kind: &ScrapeNodeKind,
1110
stats: &NodeStats,
1211
timestamp_utc: i64,
1312
) -> Result<()> {
1413
let mut conn = pool.acquire().await?;
1514

1615
match node_kind {
17-
MixingNodeKind::LegacyMixnode => {
16+
ScrapeNodeKind::LegacyMixnode { mix_id } => {
1817
sqlx::query!(
1918
r#"
2019
INSERT INTO mixnode_packet_stats_raw (
2120
mix_id, timestamp_utc, packets_received, packets_sent, packets_dropped
2221
) VALUES (?, ?, ?, ?, ?)
2322
"#,
24-
node_id,
23+
mix_id,
2524
timestamp_utc,
2625
stats.packets_received,
2726
stats.packets_sent,
@@ -30,7 +29,8 @@ pub(crate) async fn insert_node_packet_stats(
3029
.execute(&mut *conn)
3130
.await?;
3231
}
33-
MixingNodeKind::NymNode => {
32+
ScrapeNodeKind::MixingNymNode { node_id }
33+
| ScrapeNodeKind::EntryExitNymNode { node_id, .. } => {
3434
sqlx::query!(
3535
r#"
3636
INSERT INTO nym_nodes_packet_stats_raw (
@@ -60,7 +60,7 @@ pub(crate) async fn get_raw_node_stats(
6060
let packets = match node.node_kind {
6161
// if no packets are found, it's fine to assume 0 because that's also
6262
// SQL default value if none provided
63-
MixingNodeKind::LegacyMixnode => {
63+
ScrapeNodeKind::LegacyMixnode { mix_id } => {
6464
sqlx::query_as!(
6565
NodeStats,
6666
r#"
@@ -73,12 +73,13 @@ pub(crate) async fn get_raw_node_stats(
7373
ORDER BY timestamp_utc DESC
7474
LIMIT 1 OFFSET 1
7575
"#,
76-
node.node_id
76+
mix_id
7777
)
7878
.fetch_optional(&mut *conn)
7979
.await?
8080
}
81-
MixingNodeKind::NymNode => {
81+
ScrapeNodeKind::MixingNymNode { node_id }
82+
| ScrapeNodeKind::EntryExitNymNode { node_id, .. } => {
8283
sqlx::query_as!(
8384
NodeStats,
8485
r#"
@@ -91,7 +92,7 @@ pub(crate) async fn get_raw_node_stats(
9192
ORDER BY timestamp_utc DESC
9293
LIMIT 1 OFFSET 1
9394
"#,
94-
node.node_id
95+
node_id
9596
)
9697
.fetch_optional(&mut *conn)
9798
.await?
@@ -110,15 +111,15 @@ pub(crate) async fn insert_daily_node_stats(
110111
let mut conn = pool.acquire().await?;
111112

112113
match node.node_kind {
113-
MixingNodeKind::LegacyMixnode => {
114+
ScrapeNodeKind::LegacyMixnode { mix_id } => {
114115
let total_stake = sqlx::query_scalar!(
115116
r#"
116117
SELECT
117118
total_stake
118119
FROM mixnodes
119120
WHERE mix_id = ?
120121
"#,
121-
node.node_id
122+
mix_id
122123
)
123124
.fetch_one(&mut *conn)
124125
.await?;
@@ -136,7 +137,7 @@ pub(crate) async fn insert_daily_node_stats(
136137
packets_sent = mixnode_daily_stats.packets_sent + excluded.packets_sent,
137138
packets_dropped = mixnode_daily_stats.packets_dropped + excluded.packets_dropped
138139
"#,
139-
node.node_id,
140+
mix_id,
140141
date_utc,
141142
total_stake,
142143
packets.packets_received,
@@ -146,15 +147,16 @@ pub(crate) async fn insert_daily_node_stats(
146147
.execute(&mut *conn)
147148
.await?;
148149
}
149-
MixingNodeKind::NymNode => {
150+
ScrapeNodeKind::MixingNymNode { node_id }
151+
| ScrapeNodeKind::EntryExitNymNode { node_id, .. } => {
150152
let total_stake = sqlx::query_scalar!(
151153
r#"
152154
SELECT
153155
total_stake
154156
FROM nym_nodes
155157
WHERE node_id = ?
156158
"#,
157-
node.node_id
159+
node_id
158160
)
159161
.fetch_one(&mut *conn)
160162
.await?;
@@ -172,7 +174,7 @@ pub(crate) async fn insert_daily_node_stats(
172174
packets_sent = nym_node_daily_mixing_stats.packets_sent + excluded.packets_sent,
173175
packets_dropped = nym_node_daily_mixing_stats.packets_dropped + excluded.packets_dropped
174176
"#,
175-
node.node_id,
177+
node_id,
176178
date_utc,
177179
total_stake,
178180
packets.packets_received,

0 commit comments

Comments
 (0)