【Rust】Peer情報をnode ip listに書き込む

bitcoinのIPアドレスリストは、ipアドレスとUnix timeが対になっている
(参考↓)
https://qiita.com/onokatio/items/04f23b7300dec7e287cb
その他にも、ipv4/ipv6や、ping, lastsend, lastrec, id, versionなどの情報も含まれる。

handshake後にpeers.datのファイルに書き込むようにして、ping, pongの箇所は、enumでactive/inactiveのstatusで表現することにした。

use serde::{Serialize, Deserialize};
use std::{io::Write};
use chrono::{Utc,DateTime};
use std::fs::OpenOptions;

#[derive(Serialize, Deserialize, Clone, Debug)]
enum Status {
    ACTIVE,
    INACTIVE,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
struct Peer {
    ip: String,
    unixtime: i64,
    nodetype: String,
    version: String,
    status: Status,
}

fn main(){
    let utc_datetime: DateTime<Utc> = Utc::now();
    println!("{}", utc_datetime.timestamp());

    let peer = Peer {ip: "192.168.33.10".to_string(), unixtime: utc_datetime.timestamp(), nodetype: "c".to_string(), version: "1.0.1".to_string(), status: Status::ACTIVE};
    println!("{:?}", peer);
    let serialized: Vec<u8> = serde_json::to_vec(&peer).unwrap();
    let mut file_ref = OpenOptions::new()
                        .append(true)
                        .open("./data/peers.dat")
                        .expect("Unable to open file");
    file_ref.write_all(&serialized).expect("write failed");
    file_ref.write_all(b"\n").expect("write failed");
}

Running `target/debug/sample`
1740366182
Peer { ip: “192.168.33.10”, unixtime: 1740366182, nodetype: “c”, version: “1.0.1”, status: ACTIVE }

nodeipリストをどうゆう風にするか、ファイルを分割するか、データ型などずっと悩んでいたけど、他のチェーンの設計は参考になりますね。

ちなみに取り出す際↓

fn get_peers() -> Result<Vec<Peer>, Box<dyn std::error::Error>>  {

    let mut peers: Vec<Peer> = Vec::new();
    for result in BufReader::new(File::open("./data/peers.dat")?).lines() {
        let line: Peer = serde_json::from_str(&result?).unwrap();
        peers.push(line);
    }
    Ok(peers)
}