use crate::generated::io_haveno_protobuffer::{network_envelope, NetworkEnvelope};
use bytes::BytesMut;
use prost::Message;
use anyhow::Result;
use tokio::{
io::{AsyncReadExt, AsyncWriteExt},
net::TcpStream,
time::{timeout, Duration},
};
pub type EnvMsg = network_envelope::Message;
pub async fn send_envelope(stream: &mut TcpStream, env: &NetworkEnvelope) -> Result<()> {
let mut body = Vec::new();
env.encode(&mut body)?;
let mut frame = BytesMut::with_capacity(10 + body.len());
prost::encoding::encode_varint(body.len() as u64, &mut frame);
frame.extend_from_slice(&body);
stream.write_all(&frame).await?;
Ok(())
}
pub async fn recv_envelope(stream: &mut TcpStream) -> Result<Option<NetworkEnvelope>> {
let mut varint_buf = BytesMut::with_capacity(10);
let timeout_duration = Duration::from_secs(30);
loop {
let mut byte = [0u8; 1];
timeout(timeout_duration, stream.read_exact(&mut byte)).await??;
varint_buf.extend_from_slice(&byte);
if byte[0] & 0x80 == 0 {
break;
}
}
let mut cursor = &varint_buf[..];
let len = prost::encoding::decode_varint(&mut cursor)? as usize;
let mut msg_buf = vec![0u8; len];
timeout(timeout_duration, stream.read_exact(&mut msg_buf)).await??;
let envelope = NetworkEnvelope::decode(&*msg_buf)?;
Ok(Some(envelope))
}
pub fn build_envelope(message: network_envelope::Message) -> NetworkEnvelope {
let json = std::fs::read_to_string("config.json");
let config: crate::utils::config::Config = serde_json::from_str(&json.unwrap()).unwrap();
NetworkEnvelope {
message_version: config.p2p_version.into(), message: Some(message),
}.into()
}