From 1ff8f625ff4922894a72d7d62290e125354b00d0 Mon Sep 17 00:00:00 2001 From: Alexis Sellier Date: Wed, 24 Aug 2022 21:02:54 +0200 Subject: [PATCH] node: Send git url during handshake Signed-off-by: Alexis Sellier --- node/Cargo.toml | 1 + node/src/protocol.rs | 22 ++++++++++++++-------- node/src/test/peer.rs | 8 ++++++-- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/node/Cargo.toml b/node/Cargo.toml index 48a190f0..c26f0202 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -14,6 +14,7 @@ colored = { version = "1.9.0" } fastrand = { version = "1.8.0" } git-ref-format = { version = "0", features = ["serde", "macro"] } git2 = { version = "0.13" } +git-url = { version = "0.3.5", features = ["serde1"] } multibase = { version = "0.9.1" } log = { version = "0.4.17", features = ["std"] } once_cell = { version = "1.13" } diff --git a/node/src/protocol.rs b/node/src/protocol.rs index cccae179..d8990094 100644 --- a/node/src/protocol.rs +++ b/node/src/protocol.rs @@ -3,6 +3,7 @@ use std::ops::{Deref, DerefMut}; use std::{collections::VecDeque, fmt, io, net, net::IpAddr}; use fastrand::Rng; +use git_url::Url; use log::*; use nakamoto::{LocalDuration, LocalTime}; use nakamoto_net as nakamoto; @@ -56,7 +57,7 @@ pub struct Envelope { #[derive(Debug, Serialize, Deserialize, Clone)] pub enum Message { /// Say hello to a peer. This is the first message sent to a peer after connection. - Hello { version: u32 }, + Hello { version: u32, git: Url }, /// Get node addresses from a peer. GetAddrs, /// Send node addresses to a peer. Sent in response to [`Message::GetAddrs`]. @@ -84,9 +85,10 @@ impl From for Envelope { } impl Message { - pub fn hello() -> Self { + pub fn hello(git: Url) -> Self { Self::Hello { version: PROTOCOL_VERSION, + git, } } @@ -152,6 +154,8 @@ pub struct Config { pub remote_tracking: RemoteTracking, /// Whether or not our node should relay inventories. pub relay: bool, + /// Our Git URL for fetching projects. + pub git_url: Url, } impl Default for Config { @@ -161,6 +165,7 @@ impl Default for Config { project_tracking: ProjectTracking::default(), remote_tracking: RemoteTracking::default(), relay: true, + git_url: Url::default(), } } } @@ -471,13 +476,12 @@ where // For inbound connections, we wait for the remote to say "Hello" first. // TODO: How should we deal with multiple peers connecting from the same IP address? if link.is_outbound() { - let since = self.local_time(); + let git = self.config.git_url.clone(); if let Some(peer) = self.peers.get_mut(&id) { self.context - .write_all(peer.addr, [Message::hello(), Message::get_inventory([])]); + .write_all(peer.addr, [Message::hello(git), Message::get_inventory([])]); - peer.state = PeerState::Negotiated { since }; peer.attempts = 0; } } else { @@ -780,7 +784,7 @@ enum PeerState { #[default] Initial, /// State after successful handshake. - Negotiated { since: LocalTime }, + Negotiated { since: LocalTime, git: Url }, /// When a peer is disconnected. Disconnected { since: LocalTime }, } @@ -848,7 +852,7 @@ impl Peer { debug!("Received {:?} from {}", &envelope.msg, self.id()); match envelope.msg { - Message::Hello { version } => { + Message::Hello { version, git } => { if version != PROTOCOL_VERSION { return Err(PeerError::WrongVersion(version)); } @@ -856,10 +860,12 @@ impl Peer { // Nb. This is a very primitive handshake. Eventually we should have anyhow // extra "acknowledgment" message sent when the `Hello` is well received. if self.link.is_inbound() { - ctx.write_all(self.addr, [Message::hello(), Message::get_inventory([])]); + let git = ctx.config.git_url.clone(); + ctx.write_all(self.addr, [Message::hello(git), Message::get_inventory([])]); } self.state = PeerState::Negotiated { since: ctx.clock.local_time(), + git, }; } else { // TODO: Handle misbehavior. diff --git a/node/src/test/peer.rs b/node/src/test/peer.rs index ebf8fab4..e17f7e1b 100644 --- a/node/src/test/peer.rs +++ b/node/src/test/peer.rs @@ -1,6 +1,7 @@ use std::net; use std::ops::{Deref, DerefMut}; +use git_url::Url; use log::*; use nakamoto_net::simulator; use nakamoto_net::Protocol as _; @@ -120,10 +121,12 @@ where pub fn connect_from(&mut self, remote: &net::SocketAddr) { let local = net::SocketAddr::new(self.ip, self.rng.u16(..)); + let git = format!("file://{}.git", remote.ip()); + let git = Url::from_bytes(git.as_bytes()).unwrap(); self.initialize(); self.protocol.connected(*remote, &local, Link::Inbound); - self.receive(remote, Message::hello()); + self.receive(remote, Message::hello(git)); let mut msgs = self.messages(remote); msgs.find(|m| matches!(m, Message::Hello { .. })) @@ -144,7 +147,8 @@ where msgs.find(|m| matches!(m, Message::GetInventory { .. })) .expect("`get-inventory` is sent"); - self.receive(remote, Message::hello()); + let git = self.config().git_url.clone(); + self.receive(remote, Message::hello(git)); } /// Drain outgoing messages sent from this peer to the remote address.