fetch: always fetch canonical rad/id
The following scenario was noticed: If a node has a `rad/id` that is behind the one it is fetching from, where a delegate was added, then verification will fail since it will not fetch the new delegate -- if the scope is set to `Followed`. Irregardless if the `rad/id` is ahead or behind, the reference should be fetched to use as the delegates anchor since it will tell the fetching side which delegates in can fetch from the remote. If any of those delegates are missing then the remote is indeed lying. This is safe since the `refs/rad/id` reference is only updated by computing the COB rather than setting the OID, so it will not update through the fetch protocol itself. Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com> X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
parent
f7b53139f4
commit
119d48bbbc
|
|
@ -59,11 +59,12 @@ where
|
|||
if local == remote {
|
||||
return Err(Error::ReplicateSelf);
|
||||
}
|
||||
let state = FetchState::default();
|
||||
let handshake = handle
|
||||
.transport
|
||||
.handshake()
|
||||
.map_err(|err| Error::Handshake { err })?;
|
||||
let state = FetchState::default();
|
||||
|
||||
// N.b. ensure that we ignore the local peer's key.
|
||||
handle.blocked.extend([local]);
|
||||
state
|
||||
|
|
@ -90,18 +91,7 @@ where
|
|||
.transport
|
||||
.handshake()
|
||||
.map_err(|err| Error::Handshake { err })?;
|
||||
let mut state = FetchState::default();
|
||||
state
|
||||
.run_stage(
|
||||
handle,
|
||||
&handshake,
|
||||
&stage::CanonicalId {
|
||||
remote,
|
||||
limit: limit.special,
|
||||
},
|
||||
)
|
||||
.map_err(|e| Error::from(state::error::Protocol::from(e)))?;
|
||||
|
||||
let state = FetchState::default();
|
||||
state
|
||||
.run(handle, &handshake, limit, remote, None)
|
||||
.map_err(Error::Protocol)
|
||||
|
|
|
|||
|
|
@ -378,6 +378,18 @@ impl FetchState {
|
|||
where
|
||||
S: transport::ConnectionStream,
|
||||
{
|
||||
// N.b. we always fetch the `rad/id` since our delegate set
|
||||
// might be further ahead than theirs, e.g. we are the
|
||||
// deciding vote on adding a delegate.
|
||||
self.run_stage(
|
||||
handle,
|
||||
&handshake,
|
||||
&stage::CanonicalId {
|
||||
remote,
|
||||
limit: limit.special,
|
||||
},
|
||||
)?;
|
||||
|
||||
// N.b. The error case here should not happen. In the case of
|
||||
// a `clone` we have asked for refs/rad/id and ensured it was
|
||||
// fetched. In the case of `pull` the repository should have
|
||||
|
|
|
|||
Loading…
Reference in New Issue