Contractless/src/bin/lookup_node_time.rs

78 lines
2.6 KiB
Rust

use blockchain::common::cli_prompts::{prompt_hidden_nonempty, prompt_wallet_path};
use blockchain::common::network_startup::get_connections;
use blockchain::env;
use blockchain::records::memory::response_channels::generate_uid;
use blockchain::standalone_tools::connections::handshake;
use blockchain::{TimeZone, Utc};
#[tokio::main]
async fn main() {
// Command 4 asks a peer for its current UTC timestamp.
let rpc_command = 4;
// This lookup takes no arguments beyond the wallet key used for the handshake.
let args: Vec<String> = env::args().collect();
if args.len() != 1 {
println!("Usage: ./lookup_node_time");
return;
}
let wallet_path = prompt_wallet_path().await;
let encryption_key = prompt_hidden_nonempty(
"What is your wallet decryption key? ",
"Wallet key cannot be empty. Please try again.",
)
.await;
// Try each configured peer until one returns a 4-byte timestamp.
let connections = get_connections().await;
let mut connected = false;
for conn in connections {
if connected {
break;
}
let socket_address = conn.parse().expect("Failed to parse the socket address");
let result = handshake::connect_and_handshake(
socket_address,
"".to_string(),
rpc_command,
handshake::HandshakeWallet::WalletKey {
encryption_key: encryption_key.clone(),
wallet_path: wallet_path.clone(),
},
generate_uid(),
)
.await;
match result {
Ok(response) if response.len() == 4 => {
let timestamp = u32::from_le_bytes(response[0..4].try_into().unwrap());
let time = Utc
.timestamp_opt(timestamp as i64, 0)
.single()
.map(|datetime| datetime.format("%H:%M:%S UTC").to_string())
.unwrap_or_else(|| "invalid UTC timestamp".to_string());
println!("timestamp: {timestamp}");
println!("time: {time}");
connected = true;
}
Ok(response) => {
// Text errors are printed directly; unknown binary is ignored so another peer can be tried.
let response_text = String::from_utf8_lossy(&response);
let trimmed = response_text.trim();
if !trimmed.is_empty() {
println!("{trimmed}");
connected = true;
}
}
Err(_) => connected = false,
}
}
if !connected {
eprintln!("failed to connect");
}
}