Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
node: Keep private repos out of inventory
cloudhead committed 1 year ago
commit 614f3e7b77aaf185ec15a44a2d2fcaab152070b9
parent f0e2018ac564746ad468ba6bc68c60b85eb804b6
2 files changed +60 -10
modified radicle-node/src/service.rs
@@ -687,6 +687,7 @@ where
            .seeded_by(&nid)?
            .collect::<Result<HashMap<_, _>, _>>()?;
        let mut inventory = BTreeSet::new();
+
        let mut private = BTreeSet::new();

        for repo in self.storage.repositories()? {
            let rid = repo.rid;
@@ -699,6 +700,8 @@ where
            // Add public repositories to inventory.
            if repo.doc.visibility.is_public() {
                inventory.insert(rid);
+
            } else {
+
                private.insert(rid);
            }
            // If we have no owned refs for this repo, then there's nothing to announce.
            let Some(updated_at) = repo.synced_at else {
@@ -728,15 +731,19 @@ where
            }
        }

-
        {
-
            // Ensure that our inventory is recorded in our routing table, and we are seeding
-
            // all of it. It can happen that inventory is not properly seeded if for eg. the
-
            // user creates a new repository while the node is stopped.
-
            self.db
-
                .routing_mut()
-
                .add_inventory(inventory.iter(), nid, time.into())?;
-
            self.inventory = gossip::inventory(self.timestamp(), inventory);
-
        }
+
        // Ensure that our inventory is recorded in our routing table, and we are seeding
+
        // all of it. It can happen that inventory is not properly seeded if for eg. the
+
        // user creates a new repository while the node is stopped.
+
        self.db
+
            .routing_mut()
+
            .add_inventory(inventory.iter(), nid, time.into())?;
+
        self.inventory = gossip::inventory(self.timestamp(), inventory);
+

+
        // Ensure that private repositories are not in our inventory. It's possible that
+
        // a repository was public and then it was made private.
+
        self.db
+
            .routing_mut()
+
            .remove_inventories(private.iter(), &nid)?;

        // Setup subscription filter for seeded repos.
        self.filter = Filter::new(
modified radicle/src/node/routing.rs
@@ -51,8 +51,14 @@ pub trait Store {
        node: NodeId,
        time: Timestamp,
    ) -> Result<Vec<(RepoId, InsertResult)>, Error>;
-
    /// Remove a node for the given id.
+
    /// Remove an inventory from the given node.
    fn remove_inventory(&mut self, id: &RepoId, node: &NodeId) -> Result<bool, Error>;
+
    /// Remove multiple inventories from the given node.
+
    fn remove_inventories<'a>(
+
        &mut self,
+
        ids: impl IntoIterator<Item = &'a RepoId>,
+
        node: &NodeId,
+
    ) -> Result<(), Error>;
    /// Iterate over all entries in the routing table.
    fn entries(&self) -> Result<Box<dyn Iterator<Item = (RepoId, NodeId)>>, Error>;
    /// Get the total number of routing entries.
@@ -172,6 +178,27 @@ impl Store for Database {
        Ok(self.db.change_count() > 0)
    }

+
    fn remove_inventories<'a>(
+
        &mut self,
+
        rids: impl IntoIterator<Item = &'a RepoId>,
+
        nid: &NodeId,
+
    ) -> Result<(), Error> {
+
        let mut stmt = self
+
            .db
+
            .prepare("DELETE FROM routing WHERE repo = ? AND node = ?")?;
+

+
        transaction(&self.db, |_| {
+
            for rid in rids.into_iter() {
+
                stmt.bind((1, rid))?;
+
                stmt.bind((2, nid))?;
+

+
                stmt.iter().next();
+
                stmt.reset()?;
+
            }
+
            Ok::<_, Error>(())
+
        })
+
    }
+

    fn len(&self) -> Result<usize, Error> {
        let stmt = self.db.prepare("SELECT COUNT(1) FROM routing")?;
        let count: i64 = stmt
@@ -402,6 +429,22 @@ mod test {
    }

    #[test]
+
    fn test_remove_many() {
+
        let id1 = arbitrary::gen::<RepoId>(1);
+
        let id2 = arbitrary::gen::<RepoId>(1);
+
        let id3 = arbitrary::gen::<RepoId>(1);
+
        let node = arbitrary::gen::<NodeId>(1);
+
        let mut db = database(":memory:");
+

+
        db.add_inventory([&id1, &id2, &id3], node, Timestamp::EPOCH)
+
            .unwrap();
+
        assert_eq!(db.len().unwrap(), 3);
+

+
        db.remove_inventories([&id1, &id3], &node).unwrap();
+
        assert_eq!(db.len().unwrap(), 1);
+
    }
+

+
    #[test]
    fn test_len() {
        let mut db = database(":memory:");
        let ids = arbitrary::vec::<RepoId>(10);