73 lines
2.3 KiB
Rust
73 lines
2.3 KiB
Rust
|
|
use blockchain::common::cli_prompts::prompt_hidden_nonempty;
|
||
|
|
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::wallets::structures::Wallet;
|
||
|
|
|
||
|
|
#[tokio::main]
|
||
|
|
async fn main() {
|
||
|
|
// Command 26 is currently handled by the server as the block-IP command.
|
||
|
|
let rpc_command = 26;
|
||
|
|
|
||
|
|
// The server owner supplies the IP to block; the wallet key signs the request.
|
||
|
|
let args: Vec<String> = env::args().collect();
|
||
|
|
if args.len() != 2 {
|
||
|
|
println!("Usage: ./server_owner_block_ip <ip>");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
let ip = args[1].trim().to_string();
|
||
|
|
|
||
|
|
let wallet_key = prompt_hidden_nonempty(
|
||
|
|
"What is your wallet decryption key? ",
|
||
|
|
"Wallet key cannot be empty. Please try again.",
|
||
|
|
)
|
||
|
|
.await;
|
||
|
|
|
||
|
|
// Server-side verification expects a signature over the exact IP string.
|
||
|
|
let wallet = match Wallet::try_obtain_wallet(wallet_key.clone(), None).await {
|
||
|
|
Ok(wallet) => wallet,
|
||
|
|
Err(err) => {
|
||
|
|
eprintln!("Wallet decryption failed: {err}");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
let signature = Wallet::sign_transaction(&ip, &wallet.saved.private_key).await;
|
||
|
|
let payload = format!("{ip}|{signature}");
|
||
|
|
|
||
|
|
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,
|
||
|
|
payload.clone(),
|
||
|
|
rpc_command,
|
||
|
|
handshake::HandshakeWallet::WalletKey(wallet_key.clone()),
|
||
|
|
generate_uid(),
|
||
|
|
)
|
||
|
|
.await;
|
||
|
|
|
||
|
|
match result {
|
||
|
|
Ok(response) => {
|
||
|
|
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");
|
||
|
|
}
|
||
|
|
}
|