[tor-commits] [metrics-lib/release] Parse "shared-rand-.*" lines in consensuses and votes.
karsten at torproject.org
karsten at torproject.org
Fri Feb 17 15:44:44 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