use std::error::Error; use ed25519_dalek::{ed25519::signature::SignerMut, Signature}; use futures::prelude::*; use libp2p::{ mdns, request_response::{self, ProtocolSupport}, swarm::SwarmEvent, }; use tracing_subscriber::EnvFilter; use cll2v0::{ db, keys, messages::{MyRequest, MyResponse, MyResult}, protocol::{mk_swarm, MyBehaviourEvent}, }; use clap::{Parser, Subcommand}; /// cll2v0 is a playground for rust libraries. /// This is signing service. #[derive(Parser)] #[command(arg_required_else_help(true), version, about)] struct Args { #[command(subcommand)] cmd: Option, } #[derive(Subcommand)] enum Command { /// Start server Start(ServerParams), } #[derive(clap::Args, Debug)] pub struct ServerParams { /// Server listening address #[arg(long, default_value = "/ip4/0.0.0.0/tcp/52321")] pub listen_on: String, /// Signing key of server libp2p part #[arg( long, default_value = "deadbeef00000000000000000000000000000000000000000000000000000000" )] pub skey: String, } fn main() -> Result<(), Box> { match Args::parse().cmd { Some(Command::Start(params)) => tokio::runtime::Builder::new_multi_thread() .enable_all() .build() .unwrap() .block_on(start(params)), _ => { panic!("oops") } } } pub async fn start(params: ServerParams) -> Result<(), Box> { let ServerParams { skey: skey_hex, listen_on, } = params; if true { let _ = tracing_subscriber::fmt() .with_env_filter(EnvFilter::from_default_env()) .try_init(); } let keypair = keys::libp2p_kp_from_hex(skey_hex)?; let peer_id = libp2p_identity::PublicKey::from(keypair.public()).to_peer_id(); println!("PEER_ID : {}", peer_id); let (keychain, pool) = db::start_db().await?; let mut swarm = mk_swarm(&keypair.clone().into(), ProtocolSupport::Inbound)?; swarm.listen_on(listen_on.parse()?)?; loop { match swarm.select_next_some().await { // MDNS BEHAVIOR SwarmEvent::Behaviour(MyBehaviourEvent::Mdns(mdns::Event::Expired(list))) => { for (peer_id, _multiaddr) in list { println!("mDNS discover peer has expired: {peer_id}"); // swarm.behaviour_mut().gossipsub.remove_explicit_peer(&peer_id); } } SwarmEvent::Behaviour(MyBehaviourEvent::ReqRes(request_response::Event::Message { peer: _peer, message: libp2p::request_response::Message::Request { request, channel, .. }, })) => { // println!("Req : {:?} {:?} {:?}", peer, channel, hex::encode(request.body.clone()), ); println!("REQSIG : {}", hex::encode(request.sig.clone()),); let MyRequest { key, body, sig } = request; // FIXME :: MAP ERROR. let sig_arr: [u8; 64] = sig.clone().try_into().unwrap(); if let Ok(ekey) = keys::from_bytes(key.into()) { if let Ok(_) = ekey.verify_strict(&body, &Signature::from_bytes(&sig_arr)) { if let Ok(pkey) = db::get_persistent_key(&pool, &ekey).await { if let Some(skey) = keychain.get(&pkey.to_bytes()) { let _ = swarm.behaviour_mut().req_res.send_response( channel, MyResult::Okay(MyResponse { sig: skey.clone().sign(&body).to_bytes().into(), }), ); } else { println!("err0") }; } else { println!("err1"); } } else { println!("err2"); } } } e => { println!("OTHER {:?}", e) } } } }