[tor-commits] [metrics-lib/master] Parse "shared-rand-.*" lines in consensuses and votes.

karsten at torproject.org karsten at torproject.org
Tue Feb 14 14:34:14 UTC 2017


commit 110cb01250703d2825d956752ec84557583144ec
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date:   Mon Feb 13 15:54:06 2017 +0100

    Parse "shared-rand-.*" lines in consensuses and votes.
---
 CHANGELOG.md                                       |   1 +
 .../descriptor/RelayNetworkStatusConsensus.java    |  34 +++++++
 .../descriptor/RelayNetworkStatusVote.java         |  55 +++++++++++
 .../impl/RelayNetworkStatusConsensusImpl.java      |  69 +++++++++++++-
 .../impl/RelayNetworkStatusVoteImpl.java           | 104 ++++++++++++++++++++-
 .../descriptor/impl/ConsensusBuilder.java          |  30 ++++++
 .../impl/RelayNetworkStatusConsensusImplTest.java  |  15 +++
 .../impl/RelayNetworkStatusVoteImplTest.java       |  97 +++++++++++++++++++
 8 files changed, 402 insertions(+), 3 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6bcfea9..a760143 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,7 @@
    - Parse "proto" lines in server descriptors, "pr" lines in status
      entries, and "(recommended|required)-(client|relay)-protocols"
      lines in consensuses and votes.
+   - Parse "shared-rand-.*" lines in consensuses and votes.
 
 
 # Changes in version 1.5.0 - 2016-10-19
diff --git a/src/main/java/org/torproject/descriptor/RelayNetworkStatusConsensus.java b/src/main/java/org/torproject/descriptor/RelayNetworkStatusConsensus.java
index b004b66..57a8dd6 100644
--- a/src/main/java/org/torproject/descriptor/RelayNetworkStatusConsensus.java
+++ b/src/main/java/org/torproject/descriptor/RelayNetworkStatusConsensus.java
@@ -179,6 +179,40 @@ public interface RelayNetworkStatusConsensus extends Descriptor {
   public SortedMap<String, Integer> getConsensusParams();
 
   /**
+   * Return the number of commits used to generate the second-to-last shared
+   * random value, or -1 if the consensus does not contain a second-to-last
+   * shared random value.
+   *
+   * @since 1.6.0
+   */
+  public int getSharedRandPreviousNumReveals();
+
+  /**
+   * Return the second-to-last shared random value, encoded in base64, or null
+   * if the consensus does not contain a second-to-last shared random value.
+   *
+   * @since 1.6.0
+   */
+  public String getSharedRandPreviousValue();
+
+  /**
+   * Return the number of commits used to generate the latest shared random
+   * value, or -1 if the consensus does not contain the latest shared random
+   * value.
+   *
+   * @since 1.6.0
+   */
+  public int getSharedRandCurrentNumReveals();
+
+  /**
+   * Return the latest shared random value, encoded in base64, or null if the
+   * consensus does not contain the latest shared random value.
+   *
+   * @since 1.6.0
+   */
+  public String getSharedRandCurrentValue();
+
+  /**
    * Return directory source entries for each directory authority that
    * contributed to the consensus, with map keys being SHA-1 digests of
    * the authorities' identity keys in the version 3 directory protocol,
diff --git a/src/main/java/org/torproject/descriptor/RelayNetworkStatusVote.java b/src/main/java/org/torproject/descriptor/RelayNetworkStatusVote.java
index 9ea804d..cfb012b 100644
--- a/src/main/java/org/torproject/descriptor/RelayNetworkStatusVote.java
+++ b/src/main/java/org/torproject/descriptor/RelayNetworkStatusVote.java
@@ -306,6 +306,61 @@ public interface RelayNetworkStatusVote extends Descriptor {
   public String getContactLine();
 
   /**
+   * Return whether this directory authority supports and can participate in
+   * the shared random protocol.
+   *
+   * @since 1.6.0
+   */
+  public boolean isSharedRandParticipate();
+
+  /**
+   * Return all currently known directory authority commit lines for the shared
+   * randomness protocol in the original format as they are contained in this
+   * vote, or null if this vote does not contain any such line.
+   *
+   * <pre>
+   * "shared-rand-commit" SP Version SP AlgName SP Identity SP Commit
+   *     [SP Reveal] NL
+   * </pre>
+   *
+   * @since 1.6.0
+   */
+  public List<String> getSharedRandCommitLines();
+
+  /**
+   * Return the number of commits used to generate the second-to-last shared
+   * random value, or -1 if this vote does not contain a second-to-last shared
+   * random value.
+   *
+   * @since 1.6.0
+   */
+  public int getSharedRandPreviousNumReveals();
+
+  /**
+   * Return the second-to-last shared random value, encoded in base64, or null
+   * if this vote does not contain a second-to-last shared random value.
+   *
+   * @since 1.6.0
+   */
+  public String getSharedRandPreviousValue();
+
+  /**
+   * Return the number of commits used to generate the latest shared random
+   * value, or -1 if this vote does not contain the latest shared random value.
+   *
+   * @since 1.6.0
+   */
+  public int getSharedRandCurrentNumReveals();
+
+  /**
+   * Return the latest shared random value, encoded in base64, or null if this
+   * vote does not contain the latest shared random value.
+   *
+   * @since 1.6.0
+   */
+  public String getSharedRandCurrentValue();
+
+  /**
    * Return the version of the directory key certificate used by this
    * authority, which must be 3 or higher.
    *
diff --git a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
index fd4cf7e..dcb8938 100644
--- a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
@@ -54,8 +54,9 @@ public class RelayNetworkStatusConsensusImpl extends NetworkStatusImpl
     Set<String> atMostOnceKeywords = new HashSet<>(Arrays.asList((
         "client-versions,server-versions,recommended-client-protocols,"
         + "recommended-relay-protocols,required-client-protocols,"
-        + "required-relay-protocols,params,directory-footer,"
-        + "bandwidth-weights").split(",")));
+        + "required-relay-protocols,params,shared-rand-previous-value,"
+        + "shared-rand-current-value,directory-footer,bandwidth-weights")
+        .split(",")));
     this.checkAtMostOnceKeywords(atMostOnceKeywords);
     this.checkFirstKeyword("network-status-version");
     this.clearParsedKeywords();
@@ -147,6 +148,12 @@ public class RelayNetworkStatusConsensusImpl extends NetworkStatusImpl
         case "params":
           this.parseParamsLine(line, parts);
           break;
+        case "shared-rand-previous-value":
+          this.parseSharedRandPreviousValueLine(line, parts);
+          break;
+        case "shared-rand-current-value":
+          this.parseSharedRandCurrentValueLine(line, parts);
+          break;
         default:
           if (this.failUnrecognizedDescriptorLines) {
             throw new DescriptorParseException("Unrecognized line '"
@@ -350,6 +357,36 @@ public class RelayNetworkStatusConsensusImpl extends NetworkStatusImpl
         parts, 1, "=");
   }
 
+  private void parseSharedRandPreviousValueLine(String line, String[] parts)
+      throws DescriptorParseException {
+    if (parts.length != 3) {
+      throw new DescriptorParseException("Illegal line '" + line
+          + "' in vote.");
+    }
+    try {
+      this.sharedRandPreviousNumReveals = Integer.parseInt(parts[1]);
+    } catch (NumberFormatException e) {
+      throw new DescriptorParseException("Illegal line '" + line
+          + "' in vote.");
+    }
+    this.sharedRandPreviousValue = parts[2];
+  }
+
+  private void parseSharedRandCurrentValueLine(String line, String[] parts)
+      throws DescriptorParseException {
+    if (parts.length != 3) {
+      throw new DescriptorParseException("Illegal line '" + line
+          + "' in vote.");
+    }
+    try {
+      this.sharedRandCurrentNumReveals = Integer.parseInt(parts[1]);
+    } catch (NumberFormatException e) {
+      throw new DescriptorParseException("Illegal line '" + line
+          + "' in vote.");
+    }
+    this.sharedRandCurrentValue = parts[2];
+  }
+
   private void parseBandwidthWeightsLine(String line, String[] parts)
       throws DescriptorParseException {
     this.bandwidthWeights = ParseHelper.parseKeyValueIntegerPairs(line,
@@ -486,6 +523,34 @@ public class RelayNetworkStatusConsensusImpl extends NetworkStatusImpl
         : new TreeMap<>(this.consensusParams);
   }
 
+  private int sharedRandPreviousNumReveals = -1;
+
+  @Override
+  public int getSharedRandPreviousNumReveals() {
+    return this.sharedRandPreviousNumReveals;
+  }
+
+  private String sharedRandPreviousValue = null;
+
+  @Override
+  public String getSharedRandPreviousValue() {
+    return this.sharedRandPreviousValue;
+  }
+
+  private int sharedRandCurrentNumReveals = -1;
+
+  @Override
+  public int getSharedRandCurrentNumReveals() {
+    return this.sharedRandCurrentNumReveals;
+  }
+
+  private String sharedRandCurrentValue = null;
+
+  @Override
+  public String getSharedRandCurrentValue() {
+    return this.sharedRandCurrentValue;
+  }
+
   private SortedMap<String, Integer> bandwidthWeights;
 
   @Override
diff --git a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
index 619b2c1..1f64173 100644
--- a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
@@ -54,7 +54,8 @@ public class RelayNetworkStatusVoteImpl extends NetworkStatusImpl
         "consensus-methods,client-versions,server-versions,"
         + "recommended-client-protocols,recommended-relay-protocols,"
         + "required-client-protocols,required-relay-protocols,"
-        + "flag-thresholds,params,contact,"
+        + "flag-thresholds,params,contact,shared-rand-participate,"
+        + "shared-rand-previous-value,shared-rand-current-value,"
         + "legacy-key,dir-key-crosscert,dir-address,directory-footer")
         .split(",")));
     this.checkAtMostOnceKeywords(atMostOnceKeywords);
@@ -149,6 +150,18 @@ public class RelayNetworkStatusVoteImpl extends NetworkStatusImpl
         case "contact":
           this.parseContactLine(line, parts);
           break;
+        case "shared-rand-participate":
+          this.parseSharedRandParticipateLine(line, parts);
+          break;
+        case "shared-rand-commit":
+          this.parseSharedRandCommitLine(line, parts);
+          break;
+        case "shared-rand-previous-value":
+          this.parseSharedRandPreviousValueLine(line, parts);
+          break;
+        case "shared-rand-current-value":
+          this.parseSharedRandCurrentValueLine(line, parts);
+          break;
         case "dir-key-certificate-version":
           this.parseDirKeyCertificateVersionLine(line, parts);
           break;
@@ -452,6 +465,53 @@ public class RelayNetworkStatusVoteImpl extends NetworkStatusImpl
     }
   }
 
+  private void parseSharedRandParticipateLine(String line, String[] parts)
+      throws DescriptorParseException {
+    if (parts.length != 1) {
+      throw new DescriptorParseException("Illegal line '" + line
+          + "' in vote.");
+    }
+    this.sharedRandParticipate = true;
+  }
+
+  private void parseSharedRandCommitLine(String line, String[] parts)
+      throws DescriptorParseException {
+    if (this.sharedRandCommitLines == null) {
+      this.sharedRandCommitLines = new ArrayList<>();
+    }
+    this.sharedRandCommitLines.add(line);
+  }
+
+  private void parseSharedRandPreviousValueLine(String line, String[] parts)
+      throws DescriptorParseException {
+    if (parts.length != 3) {
+      throw new DescriptorParseException("Illegal line '" + line
+          + "' in vote.");
+    }
+    try {
+      this.sharedRandPreviousNumReveals = Integer.parseInt(parts[1]);
+    } catch (NumberFormatException e) {
+      throw new DescriptorParseException("Illegal line '" + line
+          + "' in vote.");
+    }
+    this.sharedRandPreviousValue = parts[2];
+  }
+
+  private void parseSharedRandCurrentValueLine(String line, String[] parts)
+      throws DescriptorParseException {
+    if (parts.length != 3) {
+      throw new DescriptorParseException("Illegal line '" + line
+          + "' in vote.");
+    }
+    try {
+      this.sharedRandCurrentNumReveals = Integer.parseInt(parts[1]);
+    } catch (NumberFormatException e) {
+      throw new DescriptorParseException("Illegal line '" + line
+          + "' in vote.");
+    }
+    this.sharedRandCurrentValue = parts[2];
+  }
+
   private void parseDirKeyCertificateVersionLine(String line,
       String[] parts) throws DescriptorParseException {
     if (parts.length != 2) {
@@ -604,6 +664,48 @@ public class RelayNetworkStatusVoteImpl extends NetworkStatusImpl
     return this.contactLine;
   }
 
+  private boolean sharedRandParticipate = false;
+
+  @Override
+  public boolean isSharedRandParticipate() {
+    return this.sharedRandParticipate;
+  }
+
+  private List<String> sharedRandCommitLines = null;
+
+  @Override
+  public List<String> getSharedRandCommitLines() {
+    return this.sharedRandCommitLines;
+  }
+
+  private int sharedRandPreviousNumReveals = -1;
+
+  @Override
+  public int getSharedRandPreviousNumReveals() {
+    return this.sharedRandPreviousNumReveals;
+  }
+
+  private String sharedRandPreviousValue = null;
+
+  @Override
+  public String getSharedRandPreviousValue() {
+    return this.sharedRandPreviousValue;
+  }
+
+  private int sharedRandCurrentNumReveals = -1;
+
+  @Override
+  public int getSharedRandCurrentNumReveals() {
+    return this.sharedRandCurrentNumReveals;
+  }
+
+  private String sharedRandCurrentValue = null;
+
+  @Override
+  public String getSharedRandCurrentValue() {
+    return this.sharedRandCurrentValue;
+  }
+
   private int dirKeyCertificateVersion;
 
   @Override
diff --git a/src/test/java/org/torproject/descriptor/impl/ConsensusBuilder.java b/src/test/java/org/torproject/descriptor/impl/ConsensusBuilder.java
index 24d5a02..d1cacc0 100644
--- a/src/test/java/org/torproject/descriptor/impl/ConsensusBuilder.java
+++ b/src/test/java/org/torproject/descriptor/impl/ConsensusBuilder.java
@@ -188,6 +188,30 @@ public class ConsensusBuilder {
     return new RelayNetworkStatusConsensusImpl(cb.buildConsensus(), true);
   }
 
+  private String sharedRandPreviousValueLine =
+      "shared-rand-previous-value 8 "
+      + "grwbnD6I40odtsdtWYxqs0DvPweCur6qG2Fo5p5ivS4=";
+
+  protected static RelayNetworkStatusConsensus
+      createWithSharedRandPreviousValueLine(String line)
+      throws DescriptorParseException {
+    ConsensusBuilder cb = new ConsensusBuilder();
+    cb.sharedRandPreviousValueLine = line;
+    return new RelayNetworkStatusConsensusImpl(cb.buildConsensus(), true);
+  }
+
+  private String sharedRandCurrentValueLine =
+      "shared-rand-current-value 8 "
+      + "D88plxd8YeLfCIVAR9gjiFlWB1WqpC53kWr350o1pzw=";
+
+  protected static RelayNetworkStatusConsensus
+      createWithSharedRandCurrentValueLine(String line)
+      throws DescriptorParseException {
+    ConsensusBuilder cb = new ConsensusBuilder();
+    cb.sharedRandCurrentValueLine = line;
+    return new RelayNetworkStatusConsensusImpl(cb.buildConsensus(), true);
+  }
+
   List<String> dirSources = new ArrayList<>();
 
   List<String> statusEntries = new ArrayList<>();
@@ -385,6 +409,12 @@ public class ConsensusBuilder {
     if (this.paramsLine != null) {
       sb.append(this.paramsLine).append("\n");
     }
+    if (this.sharedRandPreviousValueLine != null) {
+      sb.append(this.sharedRandPreviousValueLine).append("\n");
+    }
+    if (this.sharedRandCurrentValueLine != null) {
+      sb.append(this.sharedRandCurrentValueLine).append("\n");
+    }
     if (this.unrecognizedHeaderLine != null) {
       sb.append(this.unrecognizedHeaderLine).append("\n");
     }
diff --git a/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java b/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java
index 786ae54..b150a6a 100644
--- a/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java
@@ -855,6 +855,21 @@ public class RelayNetworkStatusConsensusImplTest {
     ConsensusBuilder.createWithParamsLine("params max=2147483648");
   }
 
+  @Test(expected = DescriptorParseException.class)
+  public void testSharedRandPreviousNumRevealsOnly()
+      throws DescriptorParseException {
+    ConsensusBuilder.createWithSharedRandPreviousValueLine(
+        "shared-rand-previous-value 8");
+  }
+
+  @Test(expected = DescriptorParseException.class)
+  public void testSharedRandPreviousExtraArg()
+      throws DescriptorParseException {
+    ConsensusBuilder.createWithSharedRandCurrentValueLine(
+        "shared-rand-current-value 8 "
+            + "D88plxd8YeLfCIVAR9gjiFlWB1WqpC53kWr350o1pzw= -1.0");
+  }
+
   @Test()
   public void testDirSourceLegacyNickname()
       throws DescriptorParseException {
diff --git a/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImplTest.java b/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImplTest.java
index ea7b927..727d707 100644
--- a/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImplTest.java
@@ -252,6 +252,52 @@ public class RelayNetworkStatusVoteImplTest {
       return new RelayNetworkStatusVoteImpl(vb.buildVote(), true);
     }
 
+    private String sharedRandParticipateLine = "shared-rand-participate";
+
+    private static RelayNetworkStatusVote createWithSharedRandParticipateLine(
+        String line) throws DescriptorParseException {
+      VoteBuilder vb = new VoteBuilder();
+      vb.sharedRandParticipateLine = line;
+      return new RelayNetworkStatusVoteImpl(vb.buildVote(), true);
+    }
+
+    private List<String> sharedRandCommitLines = Arrays.asList(new String[] {
+        "shared-rand-commit 1 sha3-256 "
+        + "0232AF901C31A04EE9848595AF9BB7620D4C5B2E "
+        + "AAAAAFieVABh3Aauk2h31FVKaW0xIm28T7VPDkzP5nHwoMItxp7iQg==",
+        "shared-rand-commit 1 sha3-256 "
+        + "14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 "
+        + "AAAAAFieVAA26LuAu9z2UhalmV7zuczWauSkqp1c/bsPA3AkH85iGw==" });
+
+    private static RelayNetworkStatusVote createWithSharedRandCommitLines(
+        List<String> lines) throws DescriptorParseException {
+      VoteBuilder vb = new VoteBuilder();
+      vb.sharedRandCommitLines = lines;
+      return new RelayNetworkStatusVoteImpl(vb.buildVote(), true);
+    }
+
+    private String sharedRandPreviousValueLine =
+        "shared-rand-previous-value 8 "
+        + "grwbnD6I40odtsdtWYxqs0DvPweCur6qG2Fo5p5ivS4=";
+
+    private static RelayNetworkStatusVote createWithSharedRandPreviousValueLine(
+        String line) throws DescriptorParseException {
+      VoteBuilder vb = new VoteBuilder();
+      vb.sharedRandPreviousValueLine = line;
+      return new RelayNetworkStatusVoteImpl(vb.buildVote(), true);
+    }
+
+    private String sharedRandCurrentValueLine =
+        "shared-rand-current-value 8 "
+        + "D88plxd8YeLfCIVAR9gjiFlWB1WqpC53kWr350o1pzw=";
+
+    private static RelayNetworkStatusVote createWithSharedRandCurrentValueLine(
+        String line) throws DescriptorParseException {
+      VoteBuilder vb = new VoteBuilder();
+      vb.sharedRandCurrentValueLine = line;
+      return new RelayNetworkStatusVoteImpl(vb.buildVote(), true);
+    }
+
     private String legacyDirKeyLine = null;
 
     private static RelayNetworkStatusVote
@@ -572,6 +618,20 @@ public class RelayNetworkStatusVoteImplTest {
       if (this.contactLine != null) {
         sb.append(this.contactLine).append("\n");
       }
+      if (this.sharedRandParticipateLine != null) {
+        sb.append(this.sharedRandParticipateLine).append("\n");
+      }
+      if (this.sharedRandCommitLines != null) {
+        for (String line : this.sharedRandCommitLines) {
+          sb.append(line).append("\n");
+        }
+      }
+      if (this.sharedRandPreviousValueLine != null) {
+        sb.append(this.sharedRandPreviousValueLine).append("\n");
+      }
+      if (this.sharedRandCurrentValueLine != null) {
+        sb.append(this.sharedRandCurrentValueLine).append("\n");
+      }
       if (this.legacyDirKeyLine != null) {
         sb.append(this.legacyDirKeyLine).append("\n");
       }
@@ -1252,6 +1312,43 @@ public class RelayNetworkStatusVoteImplTest {
         + "Appelbaum <jacob at appelbaum.net>");
   }
 
+  @Test(expected = DescriptorParseException.class)
+  public void testSharedRandParticipateLineDuplicate()
+      throws DescriptorParseException {
+    VoteBuilder.createWithSharedRandParticipateLine("shared-rand-participate\n"
+        + "shared-rand-participate");
+  }
+
+  @Test(expected = DescriptorParseException.class)
+  public void testSharedRandParticipateLineArg()
+      throws DescriptorParseException {
+    VoteBuilder.createWithSharedRandParticipateLine(
+        "shared-rand-participate 1");
+  }
+
+  @Test()
+  public void testSharedRandCommitLinesEmpty() throws DescriptorParseException {
+    RelayNetworkStatusVote vote =
+        VoteBuilder.createWithSharedRandCommitLines(null);
+    assertNull(vote.getSharedRandCommitLines());
+  }
+
+  @Test(expected = DescriptorParseException.class)
+  public void testSharedRandPreviousValueBeforeNumReveals()
+      throws DescriptorParseException {
+    VoteBuilder.createWithSharedRandPreviousValueLine(
+        "shared-rand-previous-value "
+        + "grwbnD6I40odtsdtWYxqs0DvPweCur6qG2Fo5p5ivS4= 8");
+  }
+
+  @Test(expected = DescriptorParseException.class)
+  public void testSharedRandCurrentNoNumReveals()
+      throws DescriptorParseException {
+    VoteBuilder.createWithSharedRandCurrentValueLine(
+        "shared-rand-current-value "
+            + "D88plxd8YeLfCIVAR9gjiFlWB1WqpC53kWr350o1pzw=");
+  }
+
   @Test()
   public void testLegacyDirKeyLine() throws DescriptorParseException {
     RelayNetworkStatusVote vote = VoteBuilder.createWithLegacyDirKeyLine(



More information about the tor-commits mailing list