## Inconsistent Guard flag assignment

TL;DR: we observed that the result of the consensus computation, taking in account all the votes, may lead to assign a flag Guard to a relay that does not verify all constraints from the specifications.

The Tor specifications gives the following constraints for a possible guard:

```
"Guard" -- A router is a possible Guard if all of the following apply:
- It is Fast,
- It is Stable,
- Its Weighted Fractional Uptime is at least the median for "familiar"
active routers,
- It is "familiar",
- Its bandwidth is at least AuthDirGuardBWGuarantee (if set, 2 MB by
default), OR its bandwidth is among the 25% fastest relays,
- It qualifies for the V2Dir flag as described below (this
constraint was added in 0.3.3.x, because in 0.3.0.x clients
started avoiding guards that didn't also have the V2Dir flag).
To calculate weighted fractional uptime, compute the fraction
of time that the router is up in any given day, weighting so that
downtime and uptime in the past counts less.
A node is 'familiar' if 1/8 of all active nodes have appeared more
recently than it, OR it has been around for a few weeks.
```

Currently, regarding bandwidth, the lower bar for the Guard flag is 2000 (AuthDirGuardBWGuarantee). However, we may found sometimes in recent consensus Guard relays with less than 2000 consensus weight. Here is an example, and some vote info to understand the problem:

```
r nibbana AltmzrwHD8sFGdIGzwz0llwgyW4zSkWB4u/6jLGBDzfsWCuKv5KWrg 2019-04-04 10:21:46 185.100.85.61 443 80
s Exit Fast Guard HSDir Running Stable V2Dir Valid
v Tor 0.3.4.8
pr Cons=1-2 Desc=1-2 DirCache=1-2 HSDir=1-2 HSIntro=3-4 HSRend=1-2 Link=1-5 LinkAuth=1,3 Microdesc=1-2 Relay=1-2
w Bandwidth=1860
```

Here are all the bandwidth lines and flags lines of nibbana from the 8 votes:

s Exit Fast Guard HSDir Running Stable V2Dir Valid w Bandwidth=2621

s Exit Fast HSDir Running Stable V2Dir Valid w Bandwidth=2621 Measured=1860

s Exit Fast Guard HSDir Running Stable V2Dir Valid w Bandwidth=2621 Measured=5000

s Exit Fast Guard HSDir Running Stable V2Dir Valid w Bandwidth=2621 Measured=2180

s Exit Fast Running Stable V2Dir Valid w Bandwidth=2621 Measured=1670

s Exit Fast Guard HSDir Running Stable V2Dir Valid w Bandwidth=2621

s Exit Fast HSDir Running Stable V2Dir Valid w Bandwidth=2621 Measured=1760

s Exit Fast Guard HSDir Running Stable V2Dir Valid w Bandwidth=2621

Given the votes, we can make the following observations:

- All votes seem to verify the constraint (no Guard flag if Measured bandwidth < 2000)
- We have 5 over 8 votes with the flag Guard, but only 2 over 5 if we consider only the votes with measured bandwidth
- Among 5 Measured bandwidth lines, the median is 1860, which is inline with the value in the consensus.

So, giving those observation, the inconsistency seems that the Guard flag is decided over the total number of votes instead of the 5 votes with measured bandwidth. We can dig a bit more and confirm this by looking in src/feature/dirauth/dirvote.c, function networkstatus_compute_consensus. Starting at line 2081 (on master), we can see that it's going through all the votes to compute the guard flag, and the condition is that the number of Guard flags within the votes must be higher than half of the number of votes (here, we have 5/8 so it works).

Solution: We probably want to decide the guard flag upon the votes which have a Measured bandwidth line and ignore the other votes (only for the guard flag). This is just a few lines of codes :)