Skip to content

Commit

Permalink
replication: update delegate on fast-forward
Browse files Browse the repository at this point in the history
When a delegate's rad/id already exists we check that the
rad/ids/<urn.id> for the project being replicated is a fast-forward for
rad/id. If that's the case we can safely update the rad/id to the latest
tip.

The `fast_forward` function works as follows:
1. Get tip of rad/id
2. Check the verified person's tip is a descendant of 1.
3. If so, update rad/id

Signed-off-by: Fintan Halpenny <[email protected]>
  • Loading branch information
FintanH committed Jul 1, 2021
1 parent 903cec5 commit fba6595
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 10 deletions.
17 changes: 16 additions & 1 deletion librad/src/git/identities/person.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

use std::{convert::TryFrom, fmt::Debug};

use radicle_git_ext::{is_not_found_err, OneLevel};
use radicle_git_ext::{self as ext, is_not_found_err, OneLevel};

use super::{
super::{
Expand Down Expand Up @@ -189,6 +189,21 @@ where
Ok(verified(storage).newer(a, b)?)
}

pub fn fast_forward(storage: &Storage, latest: &VerifiedPerson) -> Result<Option<ext::Oid>, Error> {
let urn = latest.urn().with_path(None);
let id_ref = super::common::IdRef::from(&urn);
let canonical = id_ref.oid(storage)?;
let tip = latest.content_id;
Ok(if storage.as_raw().graph_descendant_of(*tip, *canonical)? {
id_ref
.update(storage, tip, &format!("fast-forward to {}", tip))
.map_err(|e| Error::Store(e.into()))?;
Some(tip)
} else {
None
})
}

fn identities<S>(storage: &S) -> Identities<Person>
where
S: AsRef<storage::ReadOnly>,
Expand Down
14 changes: 10 additions & 4 deletions librad/src/git/replication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -805,9 +805,15 @@ mod project {
project_urn: &Urn,
) -> Result<(), Error> {
let delegate_urn = person.urn();
ensure_rad_id(storage, &delegate_urn, person.content_id)?;
tracking::track(storage, &delegate_urn, peer)?;
tracking::track(storage, project_urn, peer)?;

// if the identity is known we see if we can fast-forward it
if storage.has_urn(&delegate_urn)? {
identities::person::fast_forward(storage, person)?;
} else {
ensure_rad_id(storage, &delegate_urn, person.content_id)?;
tracking::track(storage, &delegate_urn, peer)?;
tracking::track(storage, project_urn, peer)?;
}

// Now point our view to the top-level
symref(
Expand Down Expand Up @@ -927,7 +933,7 @@ mod project {
S: AsRef<storage::ReadOnly>,
{
let storage = storage.as_ref();
identities::project::verify_with(storage, &urn, |delegate| {
identities::project::verify_with(storage, urn, |delegate| {
let refname =
Reference::rad_delegate(Namespace::from(urn.clone()), &delegate).with_remote(peer);
storage.reference_oid(&refname).map(|oid| oid.into())
Expand Down
4 changes: 2 additions & 2 deletions test/src/rad/identities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ impl TestPerson {
let res = to
.using_storage(move |storage| {
let fetcher = fetcher::PeerToPeer::new(urn, remote_peer, remote_addrs)
.build(&storage)
.build(storage)
.unwrap()
.unwrap();
replication::replicate(&storage, fetcher, cfg, None)
replication::replicate(storage, fetcher, cfg, None)
})
.await??;
Ok(res)
Expand Down
6 changes: 3 additions & 3 deletions test/src/test/integration/librad/scenario/updated_delegate.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2019-2020 The Radicle Foundation <[email protected]>
// Copyright © 2021 The Radicle Link Contributors
//
// This file is part of radicle-link, distributed under the GPLv3 with Radicle
// Linking Exception. For full terms see the included LICENSE file.
Expand Down Expand Up @@ -39,7 +39,7 @@ fn can_replicate_with_updated_delegate() {

let person = {
let person = peer1
.using_storage(move |storage| TestPerson::create(&storage))
.using_storage(move |storage| TestPerson::create(storage))
.await
.unwrap()
.unwrap();
Expand All @@ -59,7 +59,7 @@ fn can_replicate_with_updated_delegate() {

let person = {
let person = peer1
.using_storage(move |storage| person.update(&storage))
.using_storage(move |storage| person.update(storage))
.await
.unwrap()
.unwrap();
Expand Down

0 comments on commit fba6595

Please sign in to comment.