Commit 5e200e9e authored by Damian Johnson's avatar Damian Johnson
Browse files

Downloading votes via other authorities when unavailable directly

Suggestion from Karsten that we should fall back to download votes via other
authorities when that authority is down or refusind directory requests.
parent 9d127926
Loading
Loading
Loading
Loading
+22 −21
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ EMAIL_SUBJECT = 'Consensus issues'
CONFIG = stem.util.conf.config_dict("consensus_health", {
  'msg': {},
  'authority_fingerprints': {},
  'authority_v3ident': {},
  'bandwidth_authorities': [],
  'known_params': [],
})
@@ -121,16 +122,11 @@ def main():
  config = stem.util.conf.get_config("consensus_health")
  config.load(util.get_path('data', 'consensus_health.cfg'))

  # Downloading the consensus and vote from all authorities, then running our
  # checks over them. If we fail to download a consensus then we skip
  # downloading a vote from that authority. If all votes can't be fetched then
  # our checks are skipped.

  consensuses, consensus_fetching_issues = get_consensuses()
  votes, vote_fetching_issues = get_votes(consensuses.keys())
  votes, vote_fetching_issues = get_votes()
  issues = consensus_fetching_issues + vote_fetching_issues

  if votes:
  if consensuses and votes:
    issues += run_checks(consensuses, votes)
  else:
    log.warn("Unable to retrieve any votes. Skipping checks.")
@@ -482,39 +478,30 @@ def bandwidth_authorities_in_sync(latest_consensus, consensuses, votes):
      break


def get_consensuses(authorities = None):
def get_consensuses():
  """
  Provides a mapping of directory authority nicknames to their present consensus.

  :param list authorities: optional list of authority nicknames, if present
    then only these authorities will be queried

  :returns: tuple of the form ({authority => consensus}, issues)
  """

  return _get_documents(authorities, 'consensus', '/tor/status-vote/current/consensus')
  return _get_documents('consensus', '/tor/status-vote/current/consensus')


def get_votes(authorities = None):
def get_votes():
  """
  Provides a mapping of directory authority nicknames to their present vote.

  :param list authorities: optional list of authority nicknames, if present
    then only these authorities will be queried

  :returns: tuple of the form ({authority => vote}, issues)
  """

  return _get_documents(authorities, 'vote', '/tor/status-vote/current/authority')
  return _get_documents('vote', '/tor/status-vote/current/authority')


def _get_documents(authorities, label, resource):
def _get_documents(label, resource):
  queries, documents, issues = {}, {}, []

  for authority, endpoint in stem.descriptor.remote.DIRECTORY_AUTHORITIES.items():
    if authorities is not None and not authority in authorities:
      continue

    queries[authority] = downloader.query(
      resource,
      endpoints = [endpoint],
@@ -525,6 +512,20 @@ def _get_documents(authorities, label, resource):
    try:
      documents[authority] = query.run()[0]
    except Exception, exc:
      if label == 'vote' and authority in CONFIG['authority_v3ident']:
        # try to download the vote via the other authorities

        query = downloader.query(
          '/tor/status-vote/current/%s' % CONFIG['authority_v3ident'][authority],
          default_params = False,
        )

        query.run(True)

        if not query.error:
          documents[authority] = list(query)[0]
          continue

      msg = "Unable to retrieve the %s from %s (%s): %s" % (label, authority, query.download_url, exc)

      log.info(msg)
+11 −1
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ msg TOR_OUT_OF_DATE => The following authorities are an out of date version of
msg BADEXIT_OUT_OF_SYNC => Authorities disagree about the BadExit flag for %s (with flag: %s, without flag: %s)
msg BANDWIDTH_AUTHORITIES_OUT_OF_SYNC => Bandwidth authorities have a substantially different number of measured entreis: %s

# authority fingerprints, as per...
# authority fingerprints and v3ident, as per...
# https://gitweb.torproject.org/tor.git/blob/f631b73:/src/or/config.c#l816

authority_fingerprints moria1 => 9695DFC35FFEB861329B9F1AB04C46397020CE31
@@ -30,6 +30,16 @@ authority_fingerprints urras => 0AD3FA884D18F89EEA2D89C019379E0E7FD94417
authority_fingerprints maatuska => BD6A829255CB08E66FBE7D3748363586E46B3810
authority_fingerprints Faravahar => CF6D0AAFB385BE71B8E111FC5CFF4B47923733BC

authority_v3ident moria1 => D586D18309DED4CD6D57C18FDB97EFA96D330566
authority_v3ident tor26 => 14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4
authority_v3ident dizum => E8A9C45EDE6D711294FADF8E7951F4DE6CA56B58
authority_v3ident turtles => 27B6B5996C426270A5C95488AA5BCEB6BCC86956
authority_v3ident gabelmoo => ED03BB616EB2F60BEC80151114BB25CEF515B226
authority_v3ident dannenberg => 585769C78764D58426B8B52B6651A5A71137189A
authority_v3ident urras => 80550987E1D626E3EBA5E5E75A458DE0626D088C
authority_v3ident maatuska => 49015F787433103580E3B66A1707A00E60F2D15B
authority_v3ident Faravahar => EFCBE720AB3A82B99F9E953CD5BF50F7EEFC7B97

# directory authorities that run bandwidth scanners

bandwidth_authorities turtles