diff --git a/radicle-cli/src/commands/init.rs b/radicle-cli/src/commands/init.rs index 9f07d17d..929b9097 100644 --- a/radicle-cli/src/commands/init.rs +++ b/radicle-cli/src/commands/init.rs @@ -8,7 +8,7 @@ use anyhow::{anyhow, bail, Context as _}; use radicle::crypto::ssh; use radicle::git::RefString; -use radicle::node::NodeId; +use radicle::node::{Handle, NodeId}; use crate::git; use crate::terminal as term; @@ -34,6 +34,7 @@ Options --set-upstream, -u Setup the upstream of the default branch --setup-signing Setup the radicle key as a signing key for this repository --no-confirm Don't ask for confirmation during setup + --no-sync Don't announce the new project to the network --help Print help "#, }; @@ -47,6 +48,7 @@ pub struct Options { pub interactive: Interactive, pub setup_signing: bool, pub set_upstream: bool, + pub sync: bool, } impl Args for Options { @@ -62,6 +64,7 @@ impl Args for Options { let mut interactive = Interactive::Yes; let mut set_upstream = false; let mut setup_signing = false; + let mut sync = true; while let Some(arg) = parser.next()? { match arg { @@ -106,6 +109,12 @@ impl Args for Options { Long("no-confirm") => { interactive = Interactive::No; } + Long("sync") => { + sync = true; + } + Long("no-sync") => { + sync = false; + } Long("help") => { return Err(Error::Help.into()); } @@ -125,6 +134,7 @@ impl Args for Options { interactive, set_upstream, setup_signing, + sync, }, vec![], )) @@ -221,6 +231,14 @@ pub fn init(options: Options, profile: &profile::Profile) -> anyhow::Result<()> // Setup radicle signing key. self::setup_signing(profile.id(), &repo, interactive)?; } + if options.sync { + let spinner = term::spinner("Announcing refs.."); + if let Err(e) = radicle::Node::new(profile.socket()).announce_refs(id) { + spinner.error(e); + } else { + spinner.finish(); + } + } term::blank(); term::info!( diff --git a/radicle-cli/src/terminal/spinner.rs b/radicle-cli/src/terminal/spinner.rs index d2ccd7e9..ad9ac8dc 100644 --- a/radicle-cli/src/terminal/spinner.rs +++ b/radicle-cli/src/terminal/spinner.rs @@ -35,7 +35,7 @@ impl Spinner { pub fn error(mut self, msg: impl ToString) { let msg = msg.to_string(); - self.message = format!("{} ({})", self.message, msg); + self.message = format!("{} (error: {})", self.message, msg); self.set_failed(); } diff --git a/radicle-httpd/src/api/test.rs b/radicle-httpd/src/api/test.rs index 92ca2f92..96278d17 100644 --- a/radicle-httpd/src/api/test.rs +++ b/radicle-httpd/src/api/test.rs @@ -90,6 +90,7 @@ pub fn seed(dir: &Path) -> Context { interactive: false.into(), setup_signing: false, set_upstream: false, + sync: false, }, &profile, ) diff --git a/radicle-node/src/service.rs b/radicle-node/src/service.rs index ce551bae..3ca20a72 100644 --- a/radicle-node/src/service.rs +++ b/radicle-node/src/service.rs @@ -91,8 +91,6 @@ pub enum Error { #[error(transparent)] Storage(#[from] storage::Error), #[error(transparent)] - Fetch(#[from] storage::FetchError), - #[error(transparent)] Routing(#[from] routing::Error), } @@ -701,19 +699,13 @@ where return Ok(false); } - if let Err(err) = self.process_inventory( + if let Err(err) = self.sync_inventory( message.inventory.as_slice(), *announcer, &message.timestamp, ) { error!("Error processing inventory from {}: {}", announcer, err); - if let Error::Fetch(storage::FetchError::Verify(err)) = err { - // Disconnect the peer if it is the signer of this message. - if announcer == relayer { - return Err(session::Error::VerificationFailed(err)); - } - } // There's not much we can do if the peer sending us this message isn't the // origin of it. return Ok(false); @@ -722,6 +714,13 @@ where } // Process a peer inventory update announcement by (maybe) fetching. AnnouncementMessage::Refs(message) => { + // We update inventories when receiving ref announcements, as these could come + // from a new repository being initialized. + if let Ok(updated) = self.routing.insert(message.id, *relayer, message.timestamp) { + if updated { + info!(target: "service", "Routing table updated for {} with seed {relayer}", message.id); + } + } // TODO: Buffer/throttle fetches. // TODO: Check that we're tracking this user as well. if self @@ -743,7 +742,8 @@ where return Ok(true); } else { - debug!(target: "service", + debug!( + target: "service", "Ignoring refs announcement from {announcer}: repository {} isn't tracked", message.id ); @@ -959,7 +959,9 @@ where } /// Process a peer inventory announcement by updating our routing table. - fn process_inventory( + /// This function expects the peer's full inventory, and prunes entries that are not in the + /// given inventory. + fn sync_inventory( &mut self, inventory: &[Id], from: NodeId,