node: fetch refs announcements

Ref announcements contain the namespace (NID) and the SHA of the new
`rad/sigrefs`. This information can be used by the fetch protocol to
fetch only those `Oid`s for those namespaces.

Add a new stage `SigrefsAnnouncement` that captures this behaviour by
only asking for the advertised `Oid`s and updating the corresponding
`rad/sigrefs` for each namespace. Note that this is a special case of
the `SpecialRefs` stage and so the protocol chooses between these two
by checking if there was announcement passed through. The following
stage, `DataRefs`, stays the same.

Note that this stage can only be activated via a `pull`, and `clone`
stays the same.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
Fintan Halpenny
2023-11-09 17:47:10 +01:00
committed by cloudhead
parent d27cd0db0c
commit dd16356e4e
7 changed files with 204 additions and 40 deletions
+4 -11
View File
@@ -1,8 +1,7 @@
use std::collections::{HashMap, VecDeque};
use std::collections::VecDeque;
use std::time;
use log::*;
use radicle::git;
use radicle::storage::refs::RefsAt;
use crate::prelude::*;
@@ -29,8 +28,8 @@ pub enum Io {
remote: NodeId,
/// Namespaces being fetched.
namespaces: Namespaces,
/// If a refs announcements was made.
refs_at: Option<HashMap<NodeId, git::Oid>>,
/// If the node is fetching specific `rad/sigrefs`.
refs_at: Option<Vec<RefsAt>>,
/// Fetch timeout.
timeout: time::Duration,
},
@@ -92,13 +91,7 @@ impl Outbox {
refs_at: Vec<RefsAt>,
timeout: time::Duration,
) {
let refs_at = {
let refs = refs_at
.into_iter()
.map(|RefsAt { remote, at }| (remote, at))
.collect::<HashMap<_, _>>();
(!refs.is_empty()).then_some(refs)
};
let refs_at = (!refs_at.is_empty()).then_some(refs_at);
self.io.push_back(Io::Fetch {
rid,
namespaces,
+2
View File
@@ -828,6 +828,7 @@ where
rid,
remote,
timeout,
refs_at,
..
} => {
log::trace!(target: "wire", "Processing fetch for {rid} from {remote}..");
@@ -850,6 +851,7 @@ where
fetch: FetchRequest::Initiator {
rid,
remote,
refs_at,
timeout,
},
stream,
+7 -2
View File
@@ -11,6 +11,7 @@ use crossbeam_channel as chan;
use radicle::identity::Id;
use radicle::prelude::NodeId;
use radicle::storage::refs::RefsAt;
use radicle::storage::{ReadRepository, ReadStorage};
use radicle::{crypto, git, Storage};
use radicle_fetch::FetchLimit;
@@ -95,6 +96,8 @@ pub enum FetchRequest {
rid: Id,
/// Remote peer we are interacting with.
remote: NodeId,
/// If this fetch is for a particular set of `rad/sigrefs`.
refs_at: Option<Vec<RefsAt>>,
/// Fetch timeout.
timeout: time::Duration,
},
@@ -215,11 +218,12 @@ impl Worker {
FetchRequest::Initiator {
rid,
remote,
refs_at,
// TODO: nowhere to use this currently
timeout: _timeout,
} => {
log::debug!(target: "worker", "Worker processing outgoing fetch for {}", rid);
let result = self.fetch(rid, remote, channels);
let result = self.fetch(rid, remote, refs_at, channels);
FetchResult::Initiator { rid, result }
}
FetchRequest::Responder { remote } => {
@@ -265,6 +269,7 @@ impl Worker {
&mut self,
rid: Id,
remote: NodeId,
refs_at: Option<Vec<RefsAt>>,
channels: channels::ChannelsFlush,
) -> Result<fetch::FetchResult, FetchError> {
let FetchConfig {
@@ -292,7 +297,7 @@ impl Worker {
channels,
)?;
Ok(handle.fetch(rid, &self.storage, *limit, remote)?)
Ok(handle.fetch(rid, &self.storage, *limit, remote, refs_at)?)
}
}
+3 -1
View File
@@ -6,6 +6,7 @@ use radicle::crypto::PublicKey;
use radicle::git::UserInfo;
use radicle::prelude::Id;
use radicle::storage::git::Repository;
use radicle::storage::refs::RefsAt;
use radicle::storage::{ReadStorage as _, RefUpdate, WriteRepository as _};
use radicle::Storage;
use radicle_fetch::{BlockList, FetchLimit, Tracked};
@@ -59,6 +60,7 @@ impl Handle {
storage: &Storage,
limit: FetchLimit,
remote: PublicKey,
refs_at: Option<Vec<RefsAt>>,
) -> Result<FetchResult, error::Fetch> {
let result = match self {
Self::Clone { mut handle, tmp } => {
@@ -69,7 +71,7 @@ impl Handle {
}
Self::Pull { mut handle } => {
log::debug!(target: "worker", "{} pulling from {remote}", handle.local());
radicle_fetch::pull(&mut handle, limit, remote)?
radicle_fetch::pull(&mut handle, limit, remote, refs_at)?
}
};