Commit a3b4fe6a authored by Hiro's avatar Hiro 🏄
Browse files

Add method to get microdesc hash mapped to consensus methods

parent 9ff01672
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -4,10 +4,7 @@
package org.torproject.descriptor;

import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.*;

/**
 * Contains an entry in a network status in the version 2 or 3 directory
@@ -199,4 +196,12 @@ public interface NetworkStatusEntry extends Serializable {
   * @since 1.2.20
   */
  Set<String> getSupportedConsensusMethods();

  /**
   * Return the server's supported consensus methods to the corresponding
   * microdescriptors hashes, or null if the status
   * entry didn't contain this information or if the status is not a vote.
   *
   */
  Map<String, Set<String>> getHashToConsensusMethods();
}
+29 −5
Original line number Diff line number Diff line
@@ -10,8 +10,10 @@ import org.torproject.descriptor.DescriptorParseException;
import org.torproject.descriptor.NetworkStatusEntry;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -279,8 +281,8 @@ public class NetworkStatusEntryImpl implements NetworkStatusEntry {
    }
  }

  private void parseMLine(String line, String[] parts)
      throws DescriptorParseException {

  private void parseMLine(String line, String[] parts) throws DescriptorParseException {
    boolean isValid = true;
    if (this.microdescriptorDigests == null) {
      this.microdescriptorDigests = new HashSet<>();
@@ -288,23 +290,38 @@ public class NetworkStatusEntryImpl implements NetworkStatusEntry {
    if (this.supportedConsensusMethods == null) {
      this.supportedConsensusMethods = new HashSet<>();
    }
    if (this.hashToConsensusMethods == null) {
      this.hashToConsensusMethods = new HashMap<>();
    }

    if (parts.length == 2) {
      ParseHelper.verifyThirtyTwoByteBase64String(line, parts[1]);
      this.microdescriptorDigests.add(parts[1]);
      // Add to the map with an empty set of methods
      this.hashToConsensusMethods.put(parts[1], new HashSet<>());
    } else if (parts.length == 3 && parts[2].length() > 7) {
      /* 7 == "sha256=".length() */
      ParseHelper.verifyThirtyTwoByteBase64String(line,
          parts[2].substring(7));
      this.microdescriptorDigests.add(parts[2].substring(7));
      String hash = parts[2].substring(7);
      ParseHelper.verifyThirtyTwoByteBase64String(line, hash);
      this.microdescriptorDigests.add(hash);
      this.supportedConsensusMethods.add(parts[1]);

      // Split and add methods
      String[] methods = parts[1].split(",", -1);
      Set<String> methodSet = new HashSet<>(Arrays.asList(methods));
      for (String method : methods) {
        if (method.length() < 1) {
          isValid = false;
          break;
        }
      }

      // Add the hash and corresponding methods to the map
      if (isValid) {
        this.hashToConsensusMethods.put(hash, methodSet);
      }
    }

    if (!isValid) {
      throw new DescriptorParseException("Illegal line '" + line + "'.");
    }
@@ -474,4 +491,11 @@ public class NetworkStatusEntryImpl implements NetworkStatusEntry {
    return this.supportedConsensusMethods == null ? null
        : new HashSet<>(this.supportedConsensusMethods);
  }

  private Map<String, Set<String>> hashToConsensusMethods;

  @Override
  public Map<String, Set<String>> getHashToConsensusMethods() {
    return this.hashToConsensusMethods;
  }
}
+5 −1
Original line number Diff line number Diff line
@@ -718,7 +718,11 @@ public class RelayNetworkStatusVoteImplTest {
        nse.getVersion());
    assertTrue(nse.getMicrodescriptorDigestsSha256Base64().contains(
        "9ciEx9t0McXk9A06I7qwN7pxuNOdpCP64RV/6cx2Zkc"));
    assertEquals("[8,9,10,11]", nse.getSupportedConsensusMethods());
    assertEquals("[8,9,10,11]",
        nse.getSupportedConsensusMethods().toString());
    assertEquals(
        "{9ciEx9t0McXk9A06I7qwN7pxuNOdpCP64RV/6cx2Zkc=[11, 8, 9, 10]}",
        nse.getHashToConsensusMethods().toString());
    assertEquals(3, vote.getDirKeyCertificateVersion());
    assertEquals("80550987E1D626E3EBA5E5E75A458DE0626D088C",
        vote.getIdentity());