From 77ced78b31d70f797892e57981a084d307891ef9 Mon Sep 17 00:00:00 2001 From: Alexis Sellier Date: Wed, 31 Aug 2022 14:20:19 +0200 Subject: [PATCH] node: Start sketching out node announcements Signed-off-by: Alexis Sellier --- node/src/crypto.rs | 2 ++ node/src/protocol.rs | 59 ++++++++++++++++++++++++++++++++----------- node/src/test/peer.rs | 5 +++- 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/node/src/crypto.rs b/node/src/crypto.rs index 9e262ac8..2e61cac3 100644 --- a/node/src/crypto.rs +++ b/node/src/crypto.rs @@ -4,6 +4,8 @@ use ed25519_consensus as ed25519; use serde::{Deserialize, Serialize}; use thiserror::Error; +pub use ed25519::Signature; + pub trait Signer { /// Return this signer's public/verification key. fn public_key(&self) -> &PublicKey; diff --git a/node/src/protocol.rs b/node/src/protocol.rs index 9f530e3d..df48b238 100644 --- a/node/src/protocol.rs +++ b/node/src/protocol.rs @@ -2,7 +2,6 @@ use std::ops::{Deref, DerefMut}; use std::{collections::VecDeque, fmt, io, net, net::IpAddr}; -use ed25519_consensus::VerificationKey; use fastrand::Rng; use git_url::Url; use log::*; @@ -29,12 +28,28 @@ pub type Routing = HashMap>; /// Seconds since epoch. pub type Timestamp = u64; +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] +// TODO: We should check the length and charset when deserializing. +pub struct Hostname(String); + /// Peer public protocol address. -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] pub enum Address { - Tor { key: VerificationKey, port: u16 }, - Tcp { addr: net::SocketAddr }, - Dns { host: String, port: u16 }, + /// Tor V3 onion address. + Onion { + key: crypto::PublicKey, + port: u16, + checksum: u16, + version: u8, + }, + Ip { + ip: net::IpAddr, + port: u16, + }, + Hostname { + host: Hostname, + port: u16, + }, } pub const NETWORK_MAGIC: u32 = 0x819b43d9; @@ -64,6 +79,23 @@ pub struct Envelope { pub msg: Message, } +/// Advertized node feature. Signals what services the node supports. +pub type NodeFeatures = [u8; 32]; + +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] +pub struct NodeAnnouncement { + /// Node identifier. + id: NodeId, + /// Advertized features. + features: NodeFeatures, + /// Monotonic timestamp. + timestamp: Timestamp, + /// Non-unique alias. Must be valid UTF-8. + alias: [u8; 32], + /// Announced addresses. + addresses: Vec
, +} + /// Message payload. /// These are the messages peers send to each other. #[derive(Debug, Serialize, Deserialize, Clone)] @@ -77,10 +109,12 @@ pub enum Message { addrs: Vec
, git: Url, }, - /// Get node addresses from a peer. - GetAddrs, - /// Send node addresses to a peer. Sent in response to [`Message::GetAddrs`]. - Addrs { addrs: Vec }, + Node { + /// Signature over the announcement, by the node being announced. + signature: crypto::Signature, + /// Unsigned node announcement. + announcement: NodeAnnouncement, + }, /// Get a peer's inventory. GetInventory { ids: Vec }, /// Send our inventory to a peer. Sent in response to [`Message::GetInventory`]. @@ -1035,12 +1069,7 @@ impl Peer { })); } } - (PeerState::Negotiated { .. }, Message::GetAddrs) => { - // TODO: Send peer addresses. - todo!(); - } - (PeerState::Negotiated { .. }, Message::Addrs { .. }) => { - // TODO: Update address book. + (PeerState::Negotiated { .. }, Message::Node { .. }) => { todo!(); } (PeerState::Negotiated { .. }, Message::Hello { .. }) => { diff --git a/node/src/test/peer.rs b/node/src/test/peer.rs index eb33f5f2..7b10119f 100644 --- a/node/src/test/peer.rs +++ b/node/src/test/peer.rs @@ -149,7 +149,10 @@ where Message::hello( peer.id(), self.local_time().as_secs(), - vec![Address::Tcp { addr: remote }], + vec![Address::Ip { + ip: remote.ip(), + port: remote.port(), + }], git, ), );