From 4a98ed13013cd0cd85ada3c61dc535ebf852dd0c Mon Sep 17 00:00:00 2001
From: eta <tor@eta.st>
Date: Fri, 22 Apr 2022 16:39:28 +0100
Subject: [PATCH] tor-dirmgr: move query_into_requests into bootstrap.rs

- There's no good reason these functions needed to be part of the
  dirmgr, apart from needing a runtime and a store.
- However, we can just add those as arguments and copy them over. This
  commit does that.
---
 crates/tor-dirmgr/src/bootstrap.rs | 64 +++++++++++++++++++++++++++++-
 crates/tor-dirmgr/src/lib.rs       | 51 ++++--------------------
 2 files changed, 71 insertions(+), 44 deletions(-)

diff --git a/crates/tor-dirmgr/src/bootstrap.rs b/crates/tor-dirmgr/src/bootstrap.rs
index 61a2a2ebb4..da4b478da5 100644
--- a/crates/tor-dirmgr/src/bootstrap.rs
+++ b/crates/tor-dirmgr/src/bootstrap.rs
@@ -11,7 +11,7 @@ use std::{
 use crate::{
     docid::{self, ClientRequest},
     state::WriteNetDir,
-    upgrade_weak_ref, DirMgr, DirState, DocId, DocumentText, Error, Readiness, Result,
+    upgrade_weak_ref, DirMgr, DirState, DocId, DocQuery, DocumentText, Error, Readiness, Result,
 };
 
 use futures::channel::oneshot;
@@ -27,6 +27,7 @@ use crate::storage::Store;
 use once_cell::sync::Lazy;
 #[cfg(test)]
 use std::sync::Mutex;
+use tor_netdoc::doc::netstatus::ConsensusFlavor;
 
 /// Load a set of documents from a `Store`, returning all documents found in the store.
 /// Note that this may be less than the number of documents in `missing`.
@@ -41,6 +42,67 @@ fn load_documents_from_store(
     Ok(loaded)
 }
 
+/// Construct an appropriate ClientRequest to download a consensus
+/// of the given flavor.
+// FIXME(eta): remove pub
+pub(crate) fn make_consensus_request(
+    now: SystemTime,
+    flavor: ConsensusFlavor,
+    store: &dyn Store,
+) -> Result<ClientRequest> {
+    let mut request = tor_dirclient::request::ConsensusRequest::new(flavor);
+
+    let default_cutoff = crate::default_consensus_cutoff(now)?;
+
+    match store.latest_consensus_meta(flavor) {
+        Ok(Some(meta)) => {
+            let valid_after = meta.lifetime().valid_after();
+            request.set_last_consensus_date(std::cmp::max(valid_after, default_cutoff));
+            request.push_old_consensus_digest(*meta.sha3_256_of_signed());
+        }
+        latest => {
+            if let Err(e) = latest {
+                warn!("Error loading directory metadata: {}", e);
+            }
+            // If we don't have a consensus, then request one that's
+            // "reasonably new".  That way, our clock is set far in the
+            // future, we won't download stuff we can't use.
+            request.set_last_consensus_date(default_cutoff);
+        }
+    }
+
+    Ok(ClientRequest::Consensus(request))
+}
+
+/// Convert a DocQuery into a set of ClientRequests, suitable for sending
+/// to a directory cache.
+// FIXME(eta): remove pub
+pub(crate) fn query_into_requests<R: Runtime>(
+    rt: &R,
+    q: DocQuery,
+    store: &dyn Store,
+) -> Result<Vec<ClientRequest>> {
+    let mut res = Vec::new();
+    for q in q.split_for_download() {
+        match q {
+            DocQuery::LatestConsensus { flavor, .. } => {
+                res.push(make_consensus_request(rt.wallclock(), flavor, store)?);
+            }
+            DocQuery::AuthCert(ids) => {
+                res.push(ClientRequest::AuthCert(ids.into_iter().collect()));
+            }
+            DocQuery::Microdesc(ids) => {
+                res.push(ClientRequest::Microdescs(ids.into_iter().collect()));
+            }
+            #[cfg(feature = "routerdesc")]
+            DocQuery::RouterDesc(ids) => {
+                res.push(ClientRequest::RouterDescs(ids.into_iter().collect()));
+            }
+        }
+    }
+    Ok(res)
+}
+
 /// Testing helper: if this is Some, then we return it in place of any
 /// response to fetch_single.
 ///
diff --git a/crates/tor-dirmgr/src/lib.rs b/crates/tor-dirmgr/src/lib.rs
index 8a6869ee6f..8766dc8f3c 100644
--- a/crates/tor-dirmgr/src/lib.rs
+++ b/crates/tor-dirmgr/src/lib.rs
@@ -804,57 +804,22 @@ impl<R: Runtime> DirMgr<R> {
     /// This conversion has to be a function of the dirmgr, since it may
     /// require knowledge about our current state.
     fn query_into_requests(&self, q: DocQuery) -> Result<Vec<ClientRequest>> {
-        let mut res = Vec::new();
-        for q in q.split_for_download() {
-            match q {
-                DocQuery::LatestConsensus { flavor, .. } => {
-                    res.push(self.make_consensus_request(self.runtime.wallclock(), flavor)?);
-                }
-                DocQuery::AuthCert(ids) => {
-                    res.push(ClientRequest::AuthCert(ids.into_iter().collect()));
-                }
-                DocQuery::Microdesc(ids) => {
-                    res.push(ClientRequest::Microdescs(ids.into_iter().collect()));
-                }
-                #[cfg(feature = "routerdesc")]
-                DocQuery::RouterDesc(ids) => {
-                    res.push(ClientRequest::RouterDescs(ids.into_iter().collect()));
-                }
-            }
-        }
-        Ok(res)
+        // FIXME(eta): this code is not long for this world
+        let store = self.store.lock().expect("Directory storage lock poisoned");
+        bootstrap::query_into_requests(&self.runtime, q, store.deref())
     }
 
     /// Construct an appropriate ClientRequest to download a consensus
     /// of the given flavor.
+    #[allow(dead_code)]
     fn make_consensus_request(
         &self,
         now: SystemTime,
         flavor: ConsensusFlavor,
     ) -> Result<ClientRequest> {
-        let mut request = tor_dirclient::request::ConsensusRequest::new(flavor);
-
-        let default_cutoff = default_consensus_cutoff(now)?;
-
-        let r = self.store.lock().expect("Directory storage lock poisoned");
-        match r.latest_consensus_meta(flavor) {
-            Ok(Some(meta)) => {
-                let valid_after = meta.lifetime().valid_after();
-                request.set_last_consensus_date(std::cmp::max(valid_after, default_cutoff));
-                request.push_old_consensus_digest(*meta.sha3_256_of_signed());
-            }
-            latest => {
-                if let Err(e) = latest {
-                    warn!("Error loading directory metadata: {}", e);
-                }
-                // If we don't have a consensus, then request one that's
-                // "reasonably new".  That way, our clock is set far in the
-                // future, we won't download stuff we can't use.
-                request.set_last_consensus_date(default_cutoff);
-            }
-        }
-
-        Ok(ClientRequest::Consensus(request))
+        // FIXME(eta): this code is not long for this world
+        let store = self.store.lock().expect("Directory storage lock poisoned");
+        bootstrap::make_consensus_request(now, flavor, store.deref())
     }
 
     /// Given a request we sent and the response we got from a
@@ -1053,7 +1018,7 @@ const CONSENSUS_ALLOW_SKEW: Duration = Duration::from_secs(3600 * 48);
 
 /// Given a time `now`, return the age of the oldest consensus that we should
 /// request at that time.
-fn default_consensus_cutoff(now: SystemTime) -> Result<SystemTime> {
+pub(crate) fn default_consensus_cutoff(now: SystemTime) -> Result<SystemTime> {
     let cutoff = time::OffsetDateTime::from(now - CONSENSUS_ALLOW_SKEW);
     // We now round cutoff to the next hour, so that we aren't leaking our exact
     // time to the directory cache.
-- 
GitLab