af9f6e5ca0
* feat(db): add SQL query wrapper for PostgreSQL placeholder conversion - Created query_wrapper module with functions to automatically convert SQLite ? placeholders to PostgreSQL $1, $2, ... format - Updated build.rs to handle mutually exclusive feature flags - Modified one query in mixnodes.rs as proof of concept - Added type conversions for PostgreSQL compatibility (u32->i64, u16->i32) This is a checkpoint commit before converting all queries to use the wrapper. * feat(nym-node-status-api): add PostgreSQL database support via feature flags Implement dual database support for SQLite and PostgreSQL through Cargo feature flags. The implementation uses a query wrapper that automatically converts SQLite-style ? placeholders to PostgreSQL-style $1, $2, ... placeholders at runtime. Key changes: - Add query wrapper functions that handle placeholder conversion - Convert all sqlx::query\! macros to use wrapper functions - Handle type conversions between databases (i64 vs i32) - Add feature-gated implementations for database-specific SQL syntax - Update Makefile with clippy targets for both database features - Document database support in README * feat(nym-node-status-agent): add multi-API support with random selection Agents can now connect to multiple APIs and randomly select one for each testrun: - Accept multiple --server arguments in format "address:port:auth_key" - Randomly shuffle server list before attempting connections - Try each server until a testrun is obtained - Submit results back only to the API that provided the testrun - Continue to next server if one is down or has no testruns available * feat(nym-node-status): implement primary/secondary server architecture - Agent now requests testruns only from primary server (first in list) - Results are submitted to all configured servers in parallel - Secondary servers accept external testruns via new v2 endpoint - Added auto-creation of gateway and testrun records on secondary servers - New database queries: get_or_create_gateway, insert_external_testrun - Client library enhanced with submit_results_with_context method * Bump Node status API version * Fix build workdir * Bump to 3.1.4 * Fix types and queries * 3.1.6 * Fix gateway perf, bump 3.1.7 * NodeId -> i32, 3.1.8 * Bump agent version * i64 -> i32 * Use image yq * Migration and more types * Update remaining JSONB columns * Simplify server config * Update build path * Change delimiter * bump agent * Split up pg and sqlite builds * More typing fixes, build-and-push script * Fix Dockerfile-pg * Bump node-status-api * TYping * Agent build script * More logging around testruns * Fail loudly on read errors * Cleanup * Debug get gateways query * Fix get_gateways query * Use pg cert, 3.1.16 * Submit regular results to primary server * Bump freshenss cutoff * Update Cargo.lock * fix: resolve rebase conflicts and compilation errors After rebasing onto develop, fixed several issues: - Fixed borrowed data escapes error by using sqlx::query directly in transaction functions - Removed unused imports and cleaned up code - Maintained database-specific implementations for transaction functions * fmt * Make PG default to make lives easier * Performance improvements for Explorer v2 * Fix sqlite build * Fix PG migration * Tests round 1 * DB tests * More tests * And some more tests * And some more, more tests * cargo fmt * Fix some failing lints * Fix lioness version problems * Clippy in tests --------- Co-authored-by: dynco-nym <173912580+dynco-nym@users.noreply.github.com>
118 lines
3.4 KiB
Rust
118 lines
3.4 KiB
Rust
use crate::probe::GwProbe;
|
|
use clap::{Parser, Subcommand};
|
|
use nym_bin_common::bin_info;
|
|
use nym_crypto::asymmetric::ed25519::PrivateKey;
|
|
use std::{env, sync::OnceLock};
|
|
|
|
pub(crate) mod generate_keypair;
|
|
pub(crate) mod run_probe;
|
|
|
|
#[derive(Debug)]
|
|
pub(crate) struct ServerConfig {
|
|
pub(crate) address: String,
|
|
pub(crate) port: u16,
|
|
pub(crate) auth_key: PrivateKey,
|
|
}
|
|
|
|
// Helper for passing LONG_VERSION to clap
|
|
fn pretty_build_info_static() -> &'static str {
|
|
static PRETTY_BUILD_INFORMATION: OnceLock<String> = OnceLock::new();
|
|
PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print())
|
|
}
|
|
|
|
fn parse_server_config(s: &str) -> Result<ServerConfig, String> {
|
|
let parts: Vec<&str> = s.split('|').collect();
|
|
if parts.len() != 2 {
|
|
return Err("Server config must be in format 'address|port'".to_string());
|
|
}
|
|
|
|
let address = parts[0].to_string();
|
|
let port = parts[1]
|
|
.parse::<u16>()
|
|
.map_err(|_| "Invalid port number".to_string())?;
|
|
let auth_key =
|
|
PrivateKey::from_base58_string(env::var("NODE_STATUS_AGENT_AUTH_KEY").unwrap()).unwrap();
|
|
|
|
Ok(ServerConfig {
|
|
address,
|
|
port,
|
|
auth_key,
|
|
})
|
|
}
|
|
|
|
#[derive(Parser, Debug)]
|
|
#[clap(author = "Nymtech", version, long_version = pretty_build_info_static(), about)]
|
|
pub(crate) struct Args {
|
|
#[command(subcommand)]
|
|
pub(crate) command: Command,
|
|
}
|
|
|
|
#[derive(Subcommand, Debug)]
|
|
pub(crate) enum Command {
|
|
RunProbe {
|
|
/// Server configurations in format "address:port:auth_key"
|
|
/// Can be specified multiple times for multiple servers
|
|
#[arg(short, long, required = true)]
|
|
server: Vec<String>,
|
|
|
|
/// path of binary to run
|
|
#[arg(long, env = "NODE_STATUS_AGENT_PROBE_PATH")]
|
|
probe_path: String,
|
|
|
|
/// mnemonic for acquiring zk-nyms
|
|
#[arg(long, env = "NYM_NODE_MNEMONICS")]
|
|
mnemonic: String,
|
|
|
|
#[arg(
|
|
long,
|
|
env = "NODE_STATUS_AGENT_PROBE_EXTRA_ARGS",
|
|
value_delimiter = ','
|
|
)]
|
|
probe_extra_args: Vec<String>,
|
|
},
|
|
|
|
GenerateKeypair {
|
|
#[arg(long)]
|
|
path: Option<String>,
|
|
},
|
|
}
|
|
|
|
impl Args {
|
|
pub(crate) async fn execute(&self) -> anyhow::Result<()> {
|
|
match &self.command {
|
|
Command::RunProbe {
|
|
server,
|
|
probe_path,
|
|
mnemonic,
|
|
probe_extra_args,
|
|
} => {
|
|
// Parse server configs
|
|
let mut servers = Vec::new();
|
|
for s in server {
|
|
match parse_server_config(s) {
|
|
Ok(config) => servers.push(config),
|
|
Err(e) => {
|
|
tracing::error!("Invalid server config '{}': {}", s, e);
|
|
anyhow::bail!("Invalid server config '{}': {}", s, e);
|
|
}
|
|
}
|
|
}
|
|
|
|
run_probe::run_probe(&servers, probe_path, mnemonic, probe_extra_args)
|
|
.await
|
|
.inspect_err(|err| {
|
|
tracing::error!("{err}");
|
|
})?
|
|
}
|
|
Command::GenerateKeypair { path } => {
|
|
let path = path
|
|
.to_owned()
|
|
.unwrap_or_else(|| String::from("private-key"));
|
|
generate_keypair::generate_key_pair(path)?
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|