[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [metrics-web/release] Add graph with total cw across bwauths.
commit 285be4447deb0bd35e28dd9aab74567c1c6541b8
Author: Karsten Loesing <karsten.loesing@xxxxxxx>
Date: Wed Oct 10 15:48:12 2018 +0200
Add graph with total cw across bwauths.
Implements #25459.
---
CHANGELOG.md | 7 +
build.xml | 11 +
src/main/R/rserver/graphs.R | 32 +++
.../metrics/stats/collectdescs/Main.java | 1 +
.../metrics/stats/totalcw/Configuration.java | 18 ++
.../torproject/metrics/stats/totalcw/Database.java | 184 ++++++++++++++++
.../org/torproject/metrics/stats/totalcw/Main.java | 79 +++++++
.../metrics/stats/totalcw/OutputLine.java | 41 ++++
.../torproject/metrics/stats/totalcw/Parser.java | 62 ++++++
.../totalcw/TotalcwRelayNetworkStatusVote.java | 50 +++++
.../torproject/metrics/stats/totalcw/Writer.java | 36 +++
src/main/resources/web.xml | 4 +
src/main/resources/web/json/categories.json | 1 +
src/main/resources/web/json/metrics.json | 11 +
.../resources/web/jsps/reproducible-metrics.jsp | 36 ++-
src/main/resources/web/jsps/stats.jsp | 20 ++
src/main/sql/totalcw/init-totalcw.sql | 74 +++++++
.../totalcw/TotalcwRelayNetworkStatusVoteTest.java | 126 +++++++++++
...E-55A38ED50848BE1F13C6A35C3CA637B0D962C2EF.part | 239 ++++++++++++++++++++
...1-049AB3179B12DACC391F06A10C2A8904E4339D33.part | 239 ++++++++++++++++++++
...6-2669AD153408F88E416CE6206D1A75EC3324A2F4.part | 241 +++++++++++++++++++++
...7-38C6A19F78948B689345EE41D7119D76246C4D3E.part | 239 ++++++++++++++++++++
22 files changed, 1747 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7890d2d..f604ff9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+# Changes in version 1.3.0 - 2018-??-??
+
+ * Medium changes
+ - Start downloading and processing votes.
+ - Add Apache Commons Math 3.6.1 as dependency.
+
+
# Changes in version 1.2.0 - 2018-08-25
* Medium changes
diff --git a/build.xml b/build.xml
index e5a9794..3614d78 100644
--- a/build.xml
+++ b/build.xml
@@ -45,6 +45,7 @@
<patternset id="common" >
<include name="commons-codec-1.10.jar"/>
<include name="commons-lang3-3.5.jar"/>
+ <include name="commons-math3-3.6.1.jar"/>
<include name="jackson-annotations-2.8.6.jar"/>
<include name="jackson-core-2.8.6.jar"/>
<include name="jackson-databind-2.8.6.jar"/>
@@ -319,6 +320,7 @@
<antcall target="clients" />
<antcall target="ipv6servers" />
<antcall target="webstats" />
+ <antcall target="totalcw" />
<antcall target="make-data-available" />
</target>
@@ -470,6 +472,14 @@
</antcall>
</target>
+ <target name="totalcw" >
+ <property name="module.name" value="totalcw" />
+ <antcall target="run-java" >
+ <param name="module.main"
+ value="org.torproject.metrics.stats.totalcw.Main" />
+ </antcall>
+ </target>
+
<!--
The run-rserver target documents a working option of
configuring an R server for running metrics-web.
@@ -506,6 +516,7 @@
includes="clients*.csv userstats-combined.csv" />
<fileset dir="${modulebase}/ipv6servers/stats" includes="ipv6servers.csv" />
<fileset dir="${modulebase}/webstats/stats" includes="webstats.csv" />
+ <fileset dir="${modulebase}/totalcw/stats" includes="totalcw.csv" />
</copy>
<copy todir="${rdatadir}" >
<fileset dir="${modulebase}/clients/RData" includes="*.RData" />
diff --git a/src/main/R/rserver/graphs.R b/src/main/R/rserver/graphs.R
index 66a1414..12915fa 100644
--- a/src/main/R/rserver/graphs.R
+++ b/src/main/R/rserver/graphs.R
@@ -1572,3 +1572,35 @@ write_advbw_ipv6 <- function(start_p = NULL, end_p = NULL, path_p) {
write.csv(path_p, quote = FALSE, row.names = FALSE, na = "")
}
+prepare_totalcw <- function(start_p, end_p) {
+ read.csv(paste(stats_dir, "totalcw.csv", sep = ""),
+ colClasses = c("valid_after_date" = "Date")) %>%
+ filter(if (!is.null(start_p))
+ valid_after_date >= as.Date(start_p) else TRUE) %>%
+ filter(if (!is.null(end_p))
+ valid_after_date <= as.Date(end_p) else TRUE)
+}
+
+plot_totalcw <- function(start_p, end_p, path_p) {
+ prepare_totalcw(start_p, end_p) %>%
+ complete(valid_after_date = full_seq(valid_after_date, period = 1),
+ nesting(nickname)) %>%
+ ggplot(aes(x = valid_after_date, y = measured_sum_avg,
+ colour = nickname)) +
+ geom_line(na.rm = TRUE) +
+ scale_x_date(name = "", breaks = custom_breaks,
+ labels = custom_labels, minor_breaks = custom_minor_breaks) +
+ scale_y_continuous(name = "", labels = formatter, limits = c(0, NA)) +
+ scale_colour_hue(name = "") +
+ ggtitle("Total consensus weights across bandwidth authorities") +
+ labs(caption = copyright_notice)
+ ggsave(filename = path_p, width = 8, height = 5, dpi = 150)
+}
+
+write_totalcw <- function(start_p = NULL, end_p = NULL, path_p) {
+ prepare_totalcw(start_p, end_p) %>%
+ rename(date = valid_after_date, totalcw = measured_sum_avg) %>%
+ arrange(date, nickname) %>%
+ write.csv(path_p, quote = FALSE, row.names = FALSE, na = "")
+}
+
diff --git a/src/main/java/org/torproject/metrics/stats/collectdescs/Main.java b/src/main/java/org/torproject/metrics/stats/collectdescs/Main.java
index 4c64425..a9620f5 100644
--- a/src/main/java/org/torproject/metrics/stats/collectdescs/Main.java
+++ b/src/main/java/org/torproject/metrics/stats/collectdescs/Main.java
@@ -24,6 +24,7 @@ public class Main {
"/recent/relay-descriptors/consensuses/",
"/recent/relay-descriptors/extra-infos/",
"/recent/relay-descriptors/server-descriptors/",
+ "/recent/relay-descriptors/votes/",
"/recent/torperf/",
"/recent/webstats/"
}, 0L, new File("../../shared/in"), true);
diff --git a/src/main/java/org/torproject/metrics/stats/totalcw/Configuration.java b/src/main/java/org/torproject/metrics/stats/totalcw/Configuration.java
new file mode 100644
index 0000000..a424f84
--- /dev/null
+++ b/src/main/java/org/torproject/metrics/stats/totalcw/Configuration.java
@@ -0,0 +1,18 @@
+/* Copyright 2018 The Tor Project
+ * See LICENSE for licensing information */
+
+package org.torproject.metrics.stats.totalcw;
+
+/** Configuration options parsed from Java properties with reasonable hard-coded
+ * defaults. */
+class Configuration {
+ static String descriptors = System.getProperty("totalcw.descriptors",
+ "../../shared/in/");
+ static String database = System.getProperty("totalcw.database",
+ "jdbc:postgresql:totalcw");
+ static String history = System.getProperty("totalcw.history",
+ "status/read-descriptors");
+ static String output = System.getProperty("totalcw.output",
+ "stats/totalcw.csv");
+}
+
diff --git a/src/main/java/org/torproject/metrics/stats/totalcw/Database.java b/src/main/java/org/torproject/metrics/stats/totalcw/Database.java
new file mode 100644
index 0000000..be4cad3
--- /dev/null
+++ b/src/main/java/org/torproject/metrics/stats/totalcw/Database.java
@@ -0,0 +1,184 @@
+/* Copyright 2018 The Tor Project
+ * See LICENSE for licensing information */
+
+package org.torproject.metrics.stats.totalcw;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Timestamp;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
+
+/** Database wrapper to connect to the database, insert data, run the stored
+ * procedure for aggregating data, and query aggregated data as output. */
+class Database implements AutoCloseable {
+
+ /** Database connection string. */
+ private String jdbcString;
+
+ /** Connection object for all interactions with the database. */
+ private Connection connection;
+
+ /** Prepared statement for finding out whether a given authority is already
+ * contained in the authority table. */
+ private PreparedStatement psAuthoritySelect;
+
+ /** Prepared statement for inserting an authority into the authority table. */
+ private PreparedStatement psAuthorityInsert;
+
+ /** Prepared statement for checking whether a vote has been inserted into the
+ * vote table before. */
+ private PreparedStatement psVoteSelect;
+
+ /** Prepared statement for inserting a vote into the vote table. */
+ private PreparedStatement psVoteInsert;
+
+ /** Create a new Database instance and prepare for inserting or querying
+ * data. */
+ Database(String jdbcString) throws SQLException {
+ this.jdbcString = jdbcString;
+ this.connect();
+ this.prepareStatements();
+ }
+
+ private void connect() throws SQLException {
+ this.connection = DriverManager.getConnection(this.jdbcString);
+ this.connection.setAutoCommit(false);
+ }
+
+ private void prepareStatements() throws SQLException {
+ this.psAuthoritySelect = this.connection.prepareStatement(
+ "SELECT authority_id FROM authority "
+ + "WHERE nickname = ? AND identity_hex = ?");
+ this.psAuthorityInsert = this.connection.prepareStatement(
+ "INSERT INTO authority (nickname, identity_hex) VALUES (?, ?)",
+ Statement.RETURN_GENERATED_KEYS);
+ this.psVoteSelect = this.connection.prepareStatement(
+ "SELECT EXISTS (SELECT 1 FROM vote "
+ + "WHERE valid_after = ? AND authority_id = ?)");
+ this.psVoteInsert = this.connection.prepareStatement(
+ "INSERT INTO vote (valid_after, authority_id, measured_count, "
+ + "measured_sum, measured_mean, measured_min, measured_q1, "
+ + "measured_median, measured_q3, measured_max) "
+ + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ Statement.RETURN_GENERATED_KEYS);
+ }
+
+ /** Insert a parsed vote into the vote table. */
+ void insertVote(TotalcwRelayNetworkStatusVote vote) throws SQLException {
+ if (null == vote) {
+ /* Nothing to insert. */
+ return;
+ }
+ int authorityId = -1;
+ this.psAuthoritySelect.clearParameters();
+ this.psAuthoritySelect.setString(1, vote.nickname);
+ this.psAuthoritySelect.setString(2, vote.identityHex);
+ try (ResultSet rs = this.psAuthoritySelect.executeQuery()) {
+ if (rs.next()) {
+ authorityId = rs.getInt(1);
+ }
+ }
+ if (authorityId < 0) {
+ this.psAuthorityInsert.clearParameters();
+ this.psAuthorityInsert.setString(1, vote.nickname);
+ this.psAuthorityInsert.setString(2, vote.identityHex);
+ this.psAuthorityInsert.execute();
+ try (ResultSet rs = this.psAuthorityInsert.getGeneratedKeys()) {
+ if (rs.next()) {
+ authorityId = rs.getInt(1);
+ }
+ }
+ if (authorityId < 0) {
+ throw new SQLException("Could not retrieve auto-generated key for new "
+ + "authority entry.");
+ }
+ }
+ Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"),
+ Locale.US);
+ this.psVoteSelect.clearParameters();
+ this.psVoteSelect.setTimestamp(1,
+ Timestamp.from(ZonedDateTime.of(vote.validAfter,
+ ZoneId.of("UTC")).toInstant()), calendar);
+ this.psVoteSelect.setInt(2, authorityId);
+ try (ResultSet rs = this.psVoteSelect.executeQuery()) {
+ if (rs.next()) {
+ if (rs.getBoolean(1)) {
+ /* Vote is already contained. */
+ return;
+ }
+ }
+ }
+ int voteId = -1;
+ this.psVoteInsert.clearParameters();
+ this.psVoteInsert.setTimestamp(1,
+ Timestamp.from(ZonedDateTime.of(vote.validAfter,
+ ZoneId.of("UTC")).toInstant()), calendar);
+ this.psVoteInsert.setInt(2, authorityId);
+ this.psVoteInsert.setLong(3, vote.measuredCount);
+ this.psVoteInsert.setLong(4, vote.measuredSum);
+ this.psVoteInsert.setLong(5, vote.measuredMean);
+ this.psVoteInsert.setLong(6, vote.measuredMin);
+ this.psVoteInsert.setLong(7, vote.measuredQ1);
+ this.psVoteInsert.setLong(8, vote.measuredMedian);
+ this.psVoteInsert.setLong(9, vote.measuredQ3);
+ this.psVoteInsert.setLong(10, vote.measuredMax);
+ this.psVoteInsert.execute();
+ try (ResultSet rs = this.psVoteInsert.getGeneratedKeys()) {
+ if (rs.next()) {
+ voteId = rs.getInt(1);
+ }
+ }
+ if (voteId < 0) {
+ throw new SQLException("Could not retrieve auto-generated key for new "
+ + "vote entry.");
+ }
+ }
+
+ /** Roll back any changes made in this execution. */
+ void rollback() throws SQLException {
+ this.connection.rollback();
+ }
+
+ /** Commit all changes made in this execution. */
+ void commit() throws SQLException {
+ this.connection.commit();
+ }
+
+ /** Query the totalcw view to obtain aggregated statistics. */
+ Iterable<OutputLine> queryTotalcw() throws SQLException {
+ List<OutputLine> statistics = new ArrayList<>();
+ Statement st = this.connection.createStatement();
+ Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"),
+ Locale.US);
+ String queryString = "SELECT " + OutputLine.columnHeadersDelimitedBy(", ")
+ + " FROM totalcw";
+ try (ResultSet rs = st.executeQuery(queryString)) {
+ while (rs.next()) {
+ OutputLine outputLine = new OutputLine();
+ outputLine.validAfterDate = rs.getDate(
+ OutputLine.Column.VALID_AFTER_DATE.name(), calendar).toLocalDate();
+ outputLine.nickname = rs.getString(OutputLine.Column.NICKNAME.name());
+ outputLine.measuredSumAvg = rs.getLong(
+ OutputLine.Column.MEASURED_SUM_AVG.name());
+ statistics.add(outputLine);
+ }
+ }
+ return statistics;
+ }
+
+ /** Release database connection. */
+ public void close() throws SQLException {
+ this.connection.close();
+ }
+}
+
diff --git a/src/main/java/org/torproject/metrics/stats/totalcw/Main.java b/src/main/java/org/torproject/metrics/stats/totalcw/Main.java
new file mode 100644
index 0000000..7c77160
--- /dev/null
+++ b/src/main/java/org/torproject/metrics/stats/totalcw/Main.java
@@ -0,0 +1,79 @@
+/* Copyright 2018 The Tor Project
+ * See LICENSE for licensing information */
+
+package org.torproject.metrics.stats.totalcw;
+
+import org.torproject.descriptor.Descriptor;
+import org.torproject.descriptor.DescriptorReader;
+import org.torproject.descriptor.DescriptorSourceFactory;
+import org.torproject.descriptor.RelayNetworkStatusVote;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.nio.file.Paths;
+import java.sql.SQLException;
+import java.util.Arrays;
+
+/** Main class of the totalcw module that imports bandwidth measurement
+ * statistics from votes into a database and exports aggregate statistics to a
+ * CSV file. */
+public class Main {
+
+ private static Logger log = LoggerFactory.getLogger(Main.class);
+
+ private static String[][] paths = {
+ {"recent", "relay-descriptors", "votes"},
+ {"archive", "relay-descriptors", "votes"}};
+
+ /** Run the module. */
+ public static void main(String[] args) throws Exception {
+
+ log.info("Starting totalcw module.");
+
+ log.info("Reading votes and inserting relevant parts into the database.");
+ DescriptorReader reader = DescriptorSourceFactory.createDescriptorReader();
+ File historyFile = new File(Configuration.history);
+ reader.setHistoryFile(historyFile);
+ Parser parser = new Parser();
+ try (Database database = new Database(Configuration.database)) {
+ try {
+ for (Descriptor descriptor : reader.readDescriptors(
+ Arrays.stream(paths).map((String[] path)
+ -> Paths.get(Configuration.descriptors, path).toFile())
+ .toArray(File[]::new))) {
+ if (descriptor instanceof RelayNetworkStatusVote) {
+ database.insertVote(parser.parseRelayNetworkStatusVote(
+ (RelayNetworkStatusVote) descriptor));
+ } else {
+ log.debug("Skipping unknown descriptor of type {}.",
+ descriptor.getClass());
+ }
+ }
+
+ log.info("Committing all updated parts in the database.");
+ database.commit();
+ } catch (SQLException sqle) {
+ log.error("Cannot recover from SQL exception while inserting data. "
+ + "Rolling back and exiting.", sqle);
+ database.rollback();
+ return;
+ }
+ reader.saveHistoryFile(historyFile);
+
+ log.info("Querying aggregated statistics from the database.");
+ Iterable<OutputLine> output = database.queryTotalcw();
+ log.info("Writing aggregated statistics to {}.", Configuration.output);
+ if (null != output) {
+ new Writer().write(Paths.get(Configuration.output), output);
+ }
+
+ log.info("Terminating totalcw module.");
+ } catch (SQLException sqle) {
+ log.error("Cannot recover from SQL exception while querying. Not writing "
+ + "output file.", sqle);
+ }
+ }
+}
+
diff --git a/src/main/java/org/torproject/metrics/stats/totalcw/OutputLine.java b/src/main/java/org/torproject/metrics/stats/totalcw/OutputLine.java
new file mode 100644
index 0000000..450dbac
--- /dev/null
+++ b/src/main/java/org/torproject/metrics/stats/totalcw/OutputLine.java
@@ -0,0 +1,41 @@
+/* Copyright 2018 The Tor Project
+ * See LICENSE for licensing information */
+
+package org.torproject.metrics.stats.totalcw;
+
+import java.time.LocalDate;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+/** Data object holding all parts of an output line. */
+class OutputLine {
+
+ /** Column names used in the database and in the first line of the output
+ * file. */
+ enum Column {
+ VALID_AFTER_DATE, NICKNAME, MEASURED_SUM_AVG
+ }
+
+ /** Column headers joined together with the given delimiter. */
+ static String columnHeadersDelimitedBy(String delimiter) {
+ return Arrays.stream(Column.values()).map(c -> c.toString().toLowerCase())
+ .collect(Collectors.joining(delimiter));
+ }
+
+ /** Date. */
+ LocalDate validAfterDate;
+
+ /** Server type, which can be "relay" or "bridge". */
+ String nickname;
+
+ /** Mean value of total measured bandwidths of all relays over the day. */
+ Long measuredSumAvg;
+
+ /** Format all fields in a single output line for inclusion in a CSV
+ * file. */
+ @Override
+ public String toString() {
+ return String.format("%s,%s,%d", validAfterDate, nickname, measuredSumAvg);
+ }
+}
+
diff --git a/src/main/java/org/torproject/metrics/stats/totalcw/Parser.java b/src/main/java/org/torproject/metrics/stats/totalcw/Parser.java
new file mode 100644
index 0000000..155b6b0
--- /dev/null
+++ b/src/main/java/org/torproject/metrics/stats/totalcw/Parser.java
@@ -0,0 +1,62 @@
+/* Copyright 2018 The Tor Project
+ * See LICENSE for licensing information */
+
+package org.torproject.metrics.stats.totalcw;
+
+import org.apache.commons.math3.stat.descriptive.rank.Percentile;
+import org.torproject.descriptor.NetworkStatusEntry;
+import org.torproject.descriptor.RelayNetworkStatusVote;
+
+import java.time.Instant;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/** Parser that extracts bandwidth measurement statistics from votes and creates
+ * data objects for them. */
+class Parser {
+
+ /** Parse and return a vote, but return <code>null</code> if the vote did not
+ * contain any bandwidth measurements. */
+ TotalcwRelayNetworkStatusVote parseRelayNetworkStatusVote(
+ RelayNetworkStatusVote vote) {
+ List<Long> measuredBandwidths = new ArrayList<>();
+ for (NetworkStatusEntry entry : vote.getStatusEntries().values()) {
+ if (entry.getMeasured() >= 0L) {
+ measuredBandwidths.add(entry.getMeasured());
+ }
+ }
+ if (measuredBandwidths.isEmpty()) {
+ /* Return null, because we wouldn't want to add this vote to the database
+ * anyway. */
+ return null;
+ }
+ TotalcwRelayNetworkStatusVote parsedVote
+ = new TotalcwRelayNetworkStatusVote();
+ parsedVote.validAfter = Instant.ofEpochMilli(vote.getValidAfterMillis())
+ .atZone(ZoneId.of("UTC")).toLocalDateTime();
+ parsedVote.identityHex = vote.getIdentity();
+ parsedVote.nickname = vote.getNickname();
+ Collections.sort(measuredBandwidths);
+ long totalValue = 0L;
+ double[] values = new double[measuredBandwidths.size()];
+ for (int i = 0; i < measuredBandwidths.size(); i++) {
+ values[i] = (double) measuredBandwidths.get(i);
+ totalValue += measuredBandwidths.get(i);
+ }
+ parsedVote.measuredCount = values.length;
+ parsedVote.measuredSum = totalValue;
+ parsedVote.measuredMean = totalValue / values.length;
+ parsedVote.measuredMin = (long) Math.floor(values[0]);
+ parsedVote.measuredMax = (long) Math.floor(values[values.length - 1]);
+ Percentile percentile = new Percentile().withEstimationType(
+ Percentile.EstimationType.R_7);
+ percentile.setData(values);
+ parsedVote.measuredQ1 = (long) Math.floor(percentile.evaluate(25.0));
+ parsedVote.measuredMedian = (long) Math.floor(percentile.evaluate(50.0));
+ parsedVote.measuredQ3 = (long) Math.floor(percentile.evaluate(75.0));
+ return parsedVote;
+ }
+}
+
diff --git a/src/main/java/org/torproject/metrics/stats/totalcw/TotalcwRelayNetworkStatusVote.java b/src/main/java/org/torproject/metrics/stats/totalcw/TotalcwRelayNetworkStatusVote.java
new file mode 100644
index 0000000..c139cdc
--- /dev/null
+++ b/src/main/java/org/torproject/metrics/stats/totalcw/TotalcwRelayNetworkStatusVote.java
@@ -0,0 +1,50 @@
+/* Copyright 2018 The Tor Project
+ * See LICENSE for licensing information */
+
+package org.torproject.metrics.stats.totalcw;
+
+import java.time.LocalDateTime;
+
+/** Data object holding all relevant parts parsed from a vote. */
+class TotalcwRelayNetworkStatusVote {
+
+ /** Valid-after time of the vote. */
+ LocalDateTime validAfter;
+
+ /** The 1 to 19 character long alphanumeric nickname assigned to the authority
+ * by its operator. */
+ String nickname;
+
+ /** Uppercase hex fingerprint of the authority's (v3 authority) identity
+ * key. */
+ String identityHex;
+
+ /** Count of status entries containing bandwidth measurements. */
+ long measuredCount;
+
+ /** Sum of bandwidth measurements of all contained status entries. */
+ long measuredSum;
+
+ /** Mean value of bandwidth measurements of all contained status entries. */
+ long measuredMean;
+
+ /** Minimum value of bandwidth measurements of all contained status
+ * entries. */
+ long measuredMin;
+
+ /** First quartile value of bandwidth measurements of all contained status
+ * entries. */
+ long measuredQ1;
+
+ /** Median value of bandwidth measurements of all contained status entries. */
+ long measuredMedian;
+
+ /** Third quartile value of bandwidth measurements of all contained status
+ * entries. */
+ long measuredQ3;
+
+ /** Maximum value of bandwidth measurements of all contained status
+ * entries. */
+ long measuredMax;
+}
+
diff --git a/src/main/java/org/torproject/metrics/stats/totalcw/Writer.java b/src/main/java/org/torproject/metrics/stats/totalcw/Writer.java
new file mode 100644
index 0000000..6688eae
--- /dev/null
+++ b/src/main/java/org/torproject/metrics/stats/totalcw/Writer.java
@@ -0,0 +1,36 @@
+/* Copyright 2018 The Tor Project
+ * See LICENSE for licensing information */
+
+package org.torproject.metrics.stats.totalcw;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+/** Writer that takes output line objects and writes them to a file, preceded
+ * by a column header line. */
+class Writer {
+
+ /** Write output lines to the given file. */
+ void write(Path filePath, Iterable<OutputLine> outputLines)
+ throws IOException {
+ File parentFile = filePath.toFile().getParentFile();
+ if (null != parentFile && !parentFile.exists()) {
+ if (!parentFile.mkdirs()) {
+ throw new IOException("Unable to create parent directory of output "
+ + "file. Not writing this file.");
+ }
+ }
+ List<String> formattedOutputLines = new ArrayList<>();
+ formattedOutputLines.add(OutputLine.columnHeadersDelimitedBy(","));
+ for (OutputLine line : outputLines) {
+ formattedOutputLines.add(line.toString());
+ }
+ Files.write(filePath, formattedOutputLines, StandardCharsets.UTF_8);
+ }
+}
+
diff --git a/src/main/resources/web.xml b/src/main/resources/web.xml
index 0c79916..6ff82ad 100644
--- a/src/main/resources/web.xml
+++ b/src/main/resources/web.xml
@@ -55,6 +55,7 @@
<url-pattern>/relays-ipv6.html</url-pattern>
<url-pattern>/bridges-ipv6.html</url-pattern>
<url-pattern>/advbw-ipv6.html</url-pattern>
+ <url-pattern>/totalcw.html</url-pattern>
</servlet-mapping>
<servlet>
@@ -193,6 +194,9 @@
<url-pattern>/advbw-ipv6.png</url-pattern>
<url-pattern>/advbw-ipv6.pdf</url-pattern>
<url-pattern>/advbw-ipv6.csv</url-pattern>
+ <url-pattern>/totalcw.png</url-pattern>
+ <url-pattern>/totalcw.pdf</url-pattern>
+ <url-pattern>/totalcw.csv</url-pattern>
</servlet-mapping>
<servlet>
diff --git a/src/main/resources/web/json/categories.json b/src/main/resources/web/json/categories.json
index af05085..73d2f01 100644
--- a/src/main/resources/web/json/categories.json
+++ b/src/main/resources/web/json/categories.json
@@ -30,6 +30,7 @@
"platforms",
"relays-ipv6",
"bridges-ipv6",
+ "totalcw",
"uptimes",
"networkchurn",
"bubbles"
diff --git a/src/main/resources/web/json/metrics.json b/src/main/resources/web/json/metrics.json
index ab5d98d..ed74959 100644
--- a/src/main/resources/web/json/metrics.json
+++ b/src/main/resources/web/json/metrics.json
@@ -427,5 +427,16 @@
"start",
"end"
]
+ },
+ {
+ "id": "totalcw",
+ "title": "Total consensus weights across bandwidth authorities",
+ "type": "Graph",
+ "description": "<p>This graph shows total consensus weights across bandwidth authorities. This graph may be useful for comparing bandwidth authority implementations by comparing their total bandwidth weights.</p>",
+ "function": "totalcw",
+ "parameters": [
+ "start",
+ "end"
+ ]
}
]
diff --git a/src/main/resources/web/jsps/reproducible-metrics.jsp b/src/main/resources/web/jsps/reproducible-metrics.jsp
index c590142..4bed5cc 100644
--- a/src/main/resources/web/jsps/reproducible-metrics.jsp
+++ b/src/main/resources/web/jsps/reproducible-metrics.jsp
@@ -242,11 +242,9 @@ We therefore refer to Step 4 of the <a href="#relay-users">Relay users</a> descr
<h2><i class="fa fa-server fa-fw" aria-hidden="true"></i>
Servers <a href="#servers" name="servers" class="anchor">#</a></h2>
-<p>The following description applies to the following graphs and table:</p>
-
<p>Statistics on the number of servers—<a href="/glossary.html#relay">relays</a> and <a href="/glossary.html#bridge">bridges</a>—were among the first to appear on Tor Metrics.
-These statistics have one thing in common: they use the number of running servers as their metric.
-Possible alternatives would be to use <a href="/glossary.html#consensus-weight">consensus weight</a> fractions or guard/middle/exit probabilities as metrics, but we're not doing that yet.
+Most of these statistics have one thing in common: they use the number of running servers as their metric.
+Possible alternatives are to use <a href="/glossary.html#consensus-weight">consensus weight</a> totals/fractions or guard/middle/exit probabilities as metrics, but we only recently started doing that.
In the following, we describe how exactly we count servers.</p>
<h3 id="running-relays" class="hover">Running relays
@@ -394,6 +392,36 @@ However, a small number of missing server descriptors per status is acceptable a
For the <a href="/bridges-ipv6.html">Bridges by IP version</a> graph we further skip days for which fewer than 12 statuses are known.
The goal is to avoid over-representing a few statuses during periods when the bridge directory authority had trouble producing a status for at least half of the day.</p>
+<h3 id="consensus-weight" class="hover">Consensus weight
+<a href="#consensus-weight" class="anchor">#</a>
+</h3>
+
+<p>The following statistic uses measured bandwidth, also known as <a href="/glossary.html#consensus-weight">consensus weight</a>, as metric for relay statistics, rather than absolute relay counts.</p>
+
+<p>The following description applies to the following graph:</p>
+
+<ul>
+<li>Total consensus weights across bandwidth authorities <a href="/totalcw.html" class="btn btn-primary btn-xs"><i class="fa fa-chevron-right" aria-hidden="true"></i> graph</a></li>
+</ul>
+
+<h4>Step 1: Parse votes.</h4>
+
+<p>Obtain votes from <a href="/collector.html#type-network-status-vote-3">CollecTor</a>.
+Refer to the <a href="https://gitweb.torproject.org/torspec.git/tree/dir-spec.txt">Tor directory protocol, version 3</a> for details on the descriptor format.</p>
+
+<p>Parse and memorize the <code>"valid-after"</code> time from the vote header. We use this UTC timestamp to aggregate by the UTC date.</p>
+
+<p>Also parse the <code>"nickname"</code> and <code>"identity"</code> fields from the <code>"dir-source"</code> line. We use the identity to aggregate by authority and the nickname for display purposes.</p>
+
+<p>Parse the (optional) <code>"w"</code> lines of all status entries and compute the total of all measured bandwidth values denoted by the <code>"Measured="</code> keyword. If an entry does not contain such a value, skip the entry. If a vote does not contain a single measured bandwidth value, skip the vote.</code>
+
+<h4>Step 2: Compute daily averages</h4>
+
+<p>Go through all previously processed votes by valid-after UTC date and authority.
+If an authority published less than 12 votes on a given UTC date, skip this date and authority.
+Also skip the last date of the results, because those averages may still change throughout the day.
+For all remaining combinations of date and authority, compute the arithmetic mean of total measured bandwidth, rounded down to the next-smaller integer number.</p>
+
</div>
<div class="container">
diff --git a/src/main/resources/web/jsps/stats.jsp b/src/main/resources/web/jsps/stats.jsp
index bb038e4..c6da19f 100644
--- a/src/main/resources/web/jsps/stats.jsp
+++ b/src/main/resources/web/jsps/stats.jsp
@@ -304,6 +304,26 @@ Servers <a href="#servers" name="servers" class="anchor">#</a></h2>
<li><b>total:</b> Average number of bridges.</li>
</ul>
+<h3>Total consensus weights across bandwidth authorities
+<a href="/totalcw.html" class="btn btn-primary btn-xs"><i class="fa fa-chevron-right" aria-hidden="true"></i> graph</a>
+<a href="/totalcw.csv" class="btn btn-primary btn-xs"><i class="fa fa-chevron-right" aria-hidden="true"></i> data</a>
+<a href="#totalcw" name="totalcw" class="anchor">#</a></h3>
+
+<h4>Parameters</h4>
+
+<ul>
+<li><b>start:</b> First UTC date (YYYY-MM-DD) to include in the file.</li>
+<li><b>end:</b> Last UTC date (YYYY-MM-DD) to include in the file.</li>
+</ul>
+
+<h4>Columns</h4>
+
+<ul>
+<li><b>date:</b> UTC date (YYYY-MM-DD) when bridges have been listed as running.</li>
+<li><b>nickname:</b> Bandwidth authority nickname.</li>
+<li><b>totalcw:</b> Total consensus weight of all relays measured by the bandwidth authority.</li>
+</ul>
+
</div>
<div class="container">
diff --git a/src/main/sql/totalcw/init-totalcw.sql b/src/main/sql/totalcw/init-totalcw.sql
new file mode 100644
index 0000000..bbb6cac
--- /dev/null
+++ b/src/main/sql/totalcw/init-totalcw.sql
@@ -0,0 +1,74 @@
+-- Copyright 2018 The Tor Project
+-- See LICENSE for licensing information
+
+-- Table of v3 authorities that stores nicknames and identity fingerprints and
+-- assigns much shorter numeric identifiers for internal-only use.
+CREATE TABLE authority (
+
+ -- The auto-incremented numeric identifier for an authority.
+ authority_id SERIAL PRIMARY KEY,
+
+ -- The 1 to 19 character long alphanumeric nickname assigned to the authority by
+ -- its operator.
+ nickname CHARACTER VARYING(19) NOT NULL,
+
+ -- Uppercase hex fingerprint of the authority's (v3 authority) identity key.
+ identity_hex CHARACTER(40) NOT NULL,
+
+ UNIQUE (nickname, identity_hex)
+);
+
+-- Table of all votes with statistics on contained bandwidth measurements. Only
+-- contains votes containing bandwidth measurements.
+CREATE TABLE vote (
+
+ -- The auto-incremented numeric identifier for a vote.
+ vote_id SERIAL PRIMARY KEY,
+
+ -- Timestamp at which the consensus is supposed to become valid.
+ valid_after TIMESTAMP WITHOUT TIME ZONE NOT NULL,
+
+ -- Numeric identifier uniquely identifying the authority generating this vote.
+ authority_id INTEGER REFERENCES authority (authority_id),
+
+ -- Count of status entries containing bandwidth measurements.
+ measured_count BIGINT NOT NULL,
+
+ -- Sum of bandwidth measurements of all contained status entries.
+ measured_sum BIGINT NOT NULL,
+
+ -- Mean value of bandwidth measurements of all contained status entries.
+ measured_mean BIGINT NOT NULL,
+
+ -- Minimum value of bandwidth measurements of all contained status entries.
+ measured_min BIGINT NOT NULL,
+
+ -- First quartile value of bandwidth measurements of all contained status
+ -- entries.
+ measured_q1 BIGINT NOT NULL,
+
+ -- Median value of bandwidth measurements of all contained status entries.
+ measured_median BIGINT NOT NULL,
+
+ -- Third quartile value of bandwidth measurements of all contained status
+ -- entries.
+ measured_q3 BIGINT NOT NULL,
+
+ -- Maximum value of bandwidth measurements of all contained status entries.
+ measured_max BIGINT NOT NULL,
+
+ UNIQUE (valid_after, authority_id)
+);
+
+-- View on aggregated total consensus weight statistics in a format that is
+-- compatible for writing to an output CSV file. Votes are only included in the
+-- output if at least 12 votes are known for a given authority and day.
+CREATE OR REPLACE VIEW totalcw AS
+SELECT DATE(valid_after) AS valid_after_date, nickname,
+ FLOOR(AVG(measured_sum)) AS measured_sum_avg
+FROM vote NATURAL JOIN authority
+GROUP BY DATE(valid_after), nickname
+HAVING COUNT(vote_id) >= 12
+ AND DATE(valid_after) < (SELECT MAX(DATE(valid_after)) FROM vote)
+ORDER BY DATE(valid_after), nickname;
+
diff --git a/src/test/java/org/torproject/metrics/stats/totalcw/TotalcwRelayNetworkStatusVoteTest.java b/src/test/java/org/torproject/metrics/stats/totalcw/TotalcwRelayNetworkStatusVoteTest.java
new file mode 100644
index 0000000..085a976
--- /dev/null
+++ b/src/test/java/org/torproject/metrics/stats/totalcw/TotalcwRelayNetworkStatusVoteTest.java
@@ -0,0 +1,126 @@
+/* Copyright 2018 The Tor Project
+ * See LICENSE for licensing information */
+
+package org.torproject.metrics.stats.totalcw;
+
+import static junit.framework.TestCase.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.torproject.descriptor.Descriptor;
+import org.torproject.descriptor.DescriptorSourceFactory;
+import org.torproject.descriptor.RelayNetworkStatusVote;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.time.LocalDateTime;
+import java.time.ZonedDateTime;
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+public class TotalcwRelayNetworkStatusVoteTest {
+
+ @Parameters
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][] {
+ { "2018-10-15-00-00-00-vote-0232AF901C31A04EE9848595AF9BB7620D4C5B2E-"
+ + "55A38ED50848BE1F13C6A35C3CA637B0D962C2EF.part",
+ ZonedDateTime.parse("2018-10-15T00:00:00Z").toLocalDateTime(),
+ "dannenberg", "0232AF901C31A04EE9848595AF9BB7620D4C5B2E",
+ 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L },
+ { "2018-10-15-00-00-00-vote-27102BC123E7AF1D4741AE047E160C91ADC76B21-"
+ + "049AB3179B12DACC391F06A10C2A8904E4339D33.part",
+ ZonedDateTime.parse("2018-10-15T00:00:00Z").toLocalDateTime(),
+ "bastet", "27102BC123E7AF1D4741AE047E160C91ADC76B21",
+ 20L, 138803L, 6940L, 5L, 76L, 2490L, 9732L, 34800L },
+ { "2018-10-15-00-00-00-vote-ED03BB616EB2F60BEC80151114BB25CEF515B226-"
+ + "2669AD153408F88E416CE6206D1A75EC3324A2F4.part",
+ ZonedDateTime.parse("2018-10-15T00:00:00Z").toLocalDateTime(),
+ "gabelmoo", "ED03BB616EB2F60BEC80151114BB25CEF515B226",
+ 19, 133441L, 7023L, 2L, 153L, 3920L, 11030L, 31600L },
+ { "2018-10-15-00-00-00-vote-EFCBE720AB3A82B99F9E953CD5BF50F7EEFC7B97-"
+ + "38C6A19F78948B689345EE41D7119D76246C4D3E.part",
+ ZonedDateTime.parse("2018-10-15T00:00:00Z").toLocalDateTime(),
+ "Faravahar", "EFCBE720AB3A82B99F9E953CD5BF50F7EEFC7B97",
+ 20, 158534L, 7926L, 6L, 109L, 3215L, 9582L, 40700L }
+ });
+ }
+
+ @Parameter
+ public String fileName;
+
+ @Parameter(1)
+ public LocalDateTime expectedValidAfter;
+
+ @Parameter(2)
+ public String expectedNickname;
+
+ @Parameter(3)
+ public String expectedIdentityHex;
+
+ @Parameter(4)
+ public long expectedMeasuredCount;
+
+ @Parameter(5)
+ public long expectedMeasuredSum;
+
+ @Parameter(6)
+ public long expectedMeasuredMean;
+
+ @Parameter(7)
+ public long expectedMeasuredMin;
+
+ @Parameter(8)
+ public long expectedMeasuredQ1;
+
+ @Parameter(9)
+ public long expectedMeasuredMedian;
+
+ @Parameter(10)
+ public long expectedMeasuredQ3;
+
+ @Parameter(11)
+ public long expectedMeasuredMax;
+
+ @Test
+ public void testParseVote() throws Exception {
+ InputStream is = getClass().getClassLoader().getResourceAsStream(
+ "totalcw/" + this.fileName);
+ StringBuilder sb = new StringBuilder();
+ BufferedReader br = new BufferedReader(new InputStreamReader(is));
+ String line = br.readLine();
+ while (null != line) {
+ sb.append(line).append('\n');
+ line = br.readLine();
+ }
+ for (Descriptor descriptor
+ : DescriptorSourceFactory.createDescriptorParser().parseDescriptors(
+ sb.toString().getBytes(), new File(this.fileName), this.fileName)) {
+ TotalcwRelayNetworkStatusVote parsedVote = new Parser()
+ .parseRelayNetworkStatusVote((RelayNetworkStatusVote) descriptor);
+ if (0L == expectedMeasuredCount) {
+ assertNull(parsedVote);
+ } else {
+ assertEquals(this.expectedValidAfter, parsedVote.validAfter);
+ assertEquals(this.expectedNickname, parsedVote.nickname);
+ assertEquals(this.expectedIdentityHex, parsedVote.identityHex);
+ assertEquals(this.expectedMeasuredCount, parsedVote.measuredCount);
+ assertEquals(this.expectedMeasuredSum, parsedVote.measuredSum);
+ assertEquals(this.expectedMeasuredMean, parsedVote.measuredMean);
+ assertEquals(this.expectedMeasuredMin, parsedVote.measuredMin);
+ assertEquals(this.expectedMeasuredQ1, parsedVote.measuredQ1);
+ assertEquals(this.expectedMeasuredMedian, parsedVote.measuredMedian);
+ assertEquals(this.expectedMeasuredQ3, parsedVote.measuredQ3);
+ assertEquals(this.expectedMeasuredMax, parsedVote.measuredMax);
+ }
+ }
+ }
+}
diff --git a/src/test/resources/totalcw/2018-10-15-00-00-00-vote-0232AF901C31A04EE9848595AF9BB7620D4C5B2E-55A38ED50848BE1F13C6A35C3CA637B0D962C2EF.part b/src/test/resources/totalcw/2018-10-15-00-00-00-vote-0232AF901C31A04EE9848595AF9BB7620D4C5B2E-55A38ED50848BE1F13C6A35C3CA637B0D962C2EF.part
new file mode 100644
index 0000000..827fcfd
--- /dev/null
+++ b/src/test/resources/totalcw/2018-10-15-00-00-00-vote-0232AF901C31A04EE9848595AF9BB7620D4C5B2E-55A38ED50848BE1F13C6A35C3CA637B0D962C2EF.part
@@ -0,0 +1,239 @@
+@type network-status-vote-3 1.0
+network-status-version 3
+vote-status vote
+consensus-methods 25 26 27 28
+published 2018-10-14 23:50:00
+valid-after 2018-10-15 00:00:00
+fresh-until 2018-10-15 01:00:00
+valid-until 2018-10-15 03:00:00
+voting-delay 300 300
+recommended-relay-protocols Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=4 Microdesc=1-2 Relay=2
+recommended-client-protocols Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=4 Microdesc=1-2 Relay=2
+required-relay-protocols Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=3-4 Microdesc=1 Relay=1-2
+required-client-protocols Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=4 Microdesc=1-2 Relay=2
+known-flags Authority Exit Fast Guard HSDir Running Stable V2Dir Valid
+flag-thresholds stable-uptime=1216200 stable-mtbf=3386731 fast-speed=102000 guard-wfu=98.000% guard-tk=691200 guard-bw-inc-exits=7752000 guard-bw-exc-exits=6436000 enough-mtbf=1 ignoring-advertised-bws=0
+params CircuitPriorityHalflifeMsec=30000 DoSCircuitCreationEnabled=1 DoSConnectionEnabled=1 DoSConnectionMaxConcurrentCount=50 DoSRefuseSingleHopClientRendezvous=1 NumDirectoryGuards=3 NumEntryGuards=1 NumNTorsPerTAP=100 Support022HiddenServices=0 UseNTorHandshake=1 UseOptimisticData=1 bwauthpid=1 cbttestfreq=10 hs_service_max_rdv_failures=1 hsdir_spread_store=4 pb_disablepct=0 usecreatefast=0
+dir-source dannenberg 0232AF901C31A04EE9848595AF9BB7620D4C5B2E dannenberg.torauth.de 193.23.244.244 80 443
+contact Andreas Lehner
+shared-rand-participate
+shared-rand-commit 1 sha3-256 0232AF901C31A04EE9848595AF9BB7620D4C5B2E AAAAAFvD2IC9EM7ZZhuBysL9TCuY3vE/XuQsscEXKDtk9ATYpyGJSA==
+shared-rand-previous-value 9 Vd2znClwwth89jp91diG/Bs1AH+0ExSgRFmyVOMJwwE=
+shared-rand-current-value 9 oiXRUZGkT26O9aQmu/A52utoBF3gp27h0TvJ4gkDHkw=
+dir-key-certificate-version 3
+fingerprint 0232AF901C31A04EE9848595AF9BB7620D4C5B2E
+dir-key-published 2018-06-05 08:39:04
+dir-key-expires 2018-12-05 08:39:04
+dir-identity-key
+-----BEGIN RSA PUBLIC KEY-----
+MIIBigKCAYEAu9O0Pueesn0+29BlxZs60mBqehjdQtgSnKOm9QZxbQ0xrMQgbFnR
+hWbKD8erenyeFk2SF6AJkbyzgYC89hyPW+8GBDmg5bE8fRKjgV/nI3tY2m4rkY3u
+zSmYIdwqHUUc98Xzt9PaQ8IJAlDBY4XLKrWmJMxSyhBlVEept7+9Tj23qowW44Mz
+xPJZ1aFkB1FpkD6qmoCzVZbhXy3cGt1nDwdJK7KqlaXziz9pFiw8PzTVU2xFgJNy
++nEcT72DBtk3G5K2Riu/aXY/D541Cioj9KMV4Nv4g8aBKx58Xq2tq1pFkc1Bqj1y
+2MomVR3iskFzlqC8yKWGVe4OP2IaOhtcQJYp5GR9q+dWnr53WWNVxNu3sA9iMal3
+PJUk5pIYrsmArGew5gmlCe+Al46nPINxc7ouztmStAV+2F6SpZlKOcstnT+KJ52O
+1xnOSaj/WnzG2o4KZ9UrFQoUNOLQJcelPcC+vrinMk9BQPcB072l9NjpUBC9brsW
+qTCMStn1jfDDAgMBAAE=
+-----END RSA PUBLIC KEY-----
+dir-signing-key
+-----BEGIN RSA PUBLIC KEY-----
+MIIBCgKCAQEAy5TDIInDMMHEMdDoEgpmqGJDZ2EwtLjOeUxQD7TEy4uYd5XcsJP0
+cjkJDm1FAWU02AJFMtoT+Pg7Ge4+30jRytySp+mibQLs6s8O2xLV7mwH8if9oHZ5
+xl8aPcx7mOG6J9Ak3k610bMDkEDrxmNqg0pl+krtpWrxuh6GcA5bbfPqf0ZPyUaE
+MKKcFp/XxhLjvCOnryrQbeDYZySy2GkIx28A+u15prQnKm+6KskMC6SQIbo5QcBq
+R0bumjdl7OcuTvQsP5h/7jHovFHhA/j/5b2osbHWbG9kqn3fN50anJBNaGHnYbFQ
+gFSLZHfm8vSb5HnfzmsaDxYO/4xtfEi85wIDAQAB
+-----END RSA PUBLIC KEY-----
+dir-key-crosscert
+-----BEGIN ID SIGNATURE-----
+a0fX/ln8gMXpNGpC9ZXujMZep616AKu5DuECcKoqtAeoUeIIaAMdvMS/5RWUKDl7
+L8LeTjkUdhUpbodOtaRS+IGy9dXjSMOGUOgyLlvUSZ29jIAcTa5xBcBNgpUPkC6Y
+AbdTmNjvaq+oAkWooPnER58/iivSRrBbh8G9Cqe22AKlQUTRH87L/b5tpKDaxg3W
+89CmcsUulUVNt+Sj++kS2PqXMIySRwCv3xXQ/OLAsKJZvqByBBIY7y7TLkewiHcq
+8KdpxmvFdE/bjPnErzd3Dcdv6FW+QIgt+3XEqamXD06lTw6xUsKlX2IP+3Cei00r
+mQnm434h3FaGocvXuijjXw==
+-----END ID SIGNATURE-----
+dir-key-certification
+-----BEGIN SIGNATURE-----
+OyofWQWvPhRHhaMck1a8msuFf3AmZfLWBc/GOp8sxOvRU08pk+4hvjGGE8OpBqyF
+Lps5387U6bfqlppCvC/qvManCuViyEYqCpn1iiClq+VmcgfL9GgvjsAc8V0G6INy
+I8N19D3r/Htg44HNdW9yNgAeyv7PHzbQ9P6RyxXLawjFu4Mlho+a1IABeeFjE2f/
+PC6bDA5ix5K11AcVWAJKuTRAhQ0zOyLqnwD5UvjmqvO9jQrtK3kgrqvQ6ZJEakc9
+wDOB7+1I14gee2rvSD8rpyrPi3ystat1I4Tt2WlUGz9GX32Q7Mngq4muMVAY6bPS
+6ujDrCgTKP+bF0+WhlVO9v71NMpi+uNEwnd4FO2Tt06XM2GKbEzty5yjMPhy9b12
+GR9BaI2wMnwQ7m0Y/57Nh1w90u+GbjgBYgRVEldk7WDB5wxjBVxcfKFDzU18kLcf
+t94cSxk6CFPAPAr/LhCop7fU+4fkH0bveFm3dj0z8t6KMf5fMQvWVu5VFyUetSlV
+-----END SIGNATURE-----
+r seele AAoQ1DAR6kkoo19hBAX5K0QztNw xlbC5aW8ovDVh2t6VcKF/phheSg 2018-10-14 21:41:22 67.174.243.193 9001 0
+s 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=60
+p reject 1-65535
+id ed25519 ZtzhbIWHJpGQG+5N7hbRTtenyzq2RNJrx0QegtoY+bY
+m 25,26,27,28 sha256=4l7u4Oy1sCG/08MtsHimtWtaC1ydC/GOtCqRD/5ewgs
+r PutoElQueLee293884 AAwffNL+oHO5EdyUoWAOwvEX3ws Ay3cnaaHjnolSRe3ZjKcGlY17Q8 2018-10-14 08:06:47 174.127.217.73 55554 0
+s Fast Guard Running Stable V2Dir Valid
+v Tor 0.3.3.9
+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=4950
+p reject 1-65535
+id ed25519 /58lPWzxxQfwoxed8I9l+D3+hTdOQ6RpgVgM9FCxil4
+m 25,26,27,28 sha256=0/b37HV9enGTzbwrxxg/0R5PfwRtRosXgtU5+vi/gBk
+r CalyxInstitute14 ABG9JIWtRdmE7EFZyI/AZuXjMA4 +8xNQyAVPkKgtLH0AISVZFNuAq0 2018-10-14 11:10:20 162.247.74.201 443 80
+s Exit Fast Guard HSDir Running Stable V2Dir Valid
+v Tor 0.3.3.7
+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=10000
+p accept 20-23,43,53,79-81,88,110,143,194,220,389,443,464,531,543-544,554,563,636,706,749,873,902-904,981,989-995,1194,1220,1293,1500,1533,1677,1723,1755,1863,2082-2083,2086-2087,2095-2096,2102-2104,3128,3389,3690,4321,4643,5050,5190,5222-5223,5228,5900,6660-6669,6679,6697,8000,8008,8074,8080,8087-8088,8332-8333,8443,8888,9418,9999-10000,11371,12350,19294,19638,23456,33033,64738
+id ed25519 /AcSvVFxaIBxaB5I/7mwdVbMdP6JjDsEPVLU6Hj22a0
+m 25,26,27,28 sha256=7nBT4mYr4H5Jj71Qq7Nan7R7KqWPTRG89Oq1/5m4c1M
+r Neldoreth ABUk3UA9cp8I9+XXeBPvEnVs+o0 nms8ZM18C/K5XzLmgO5fHchjhFc 2018-10-14 19:09:56 185.13.39.197 443 80
+s Fast Guard 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=5242
+p reject 1-65535
+id ed25519 eZ49J/mRCMtMbD2GDZsjZm/gqqG9z5S6M5GykZmd2ro
+m 25,26,27,28 sha256=IxCWEdRM6Hqk1fiYx+DK9ufUPI49SE6Z4C8onbsBVXo
+r UbuntuCore246 ACenhGJF+i26Aj46wfqAaI8dc7s EmwRg8iMnKJc8GEusZxhsVf9PJI 2018-10-14 23:13:35 212.199.61.38 43511 0
+s Fast V2Dir Valid
+v Tor 0.3.3.10
+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=121
+p reject 1-65535
+id ed25519 crWebog3RcKMV49zyu6pF5A/MxQM89x2cKNRK1wbTjM
+m 25,26,27,28 sha256=98nmfhxVBZqk7VUfyXQWpJmLAfWloZtMXu5H9FVt+p8
+r rotor25 ADQsDhVdRULlU5F4iy13nxRXjes m/3hkTP+ETmoYWZ3JrniJAeRHho 2018-10-14 17:19:08 188.24.22.193 9001 9030
+s Fast Running 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=3987
+p reject 1-65535
+id ed25519 8ybCWdul+E3HdzEb1YR3Fbp6EIwnGGPsUhsSh7FUnfs
+m 25,26,27,28 sha256=ZeMCL1T4SogPYK0iyuzYZoyFx+mp9/Ng8vGmE8wI9rU
+r torbogen AEHgFQsKMHUGwoY+/J8rfjpSOzY DXa3G+iPbGQo4AK2iazVY6R4eKs 2018-10-14 20:19:33 178.142.72.49 9001 9030
+s Fast Running V2Dir Valid
+v Tor 0.3.3.9
+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=1275
+p reject 1-65535
+id ed25519 NzIv9KWavK4f+6426ctrr9UnsFl/Yt8ixEAP6OO/kVo
+m 25,26,27,28 sha256=lFXLHMP6Map0qD298F+eeybL4pqtXDRG7a7r4R7knlw
+r nicolass67atoll AES/YhfxWxj3ZvK1O85bPg4BV+k iK+QhopNtEipMSL+EeI6b/DitVc 2018-10-14 15:48:15 163.172.10.89 9001 0
+s Fast Running Stable V2Dir Valid
+v Tor 0.2.9.16
+pr Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1-2 Link=1-4 LinkAuth=1 Microdesc=1-2 Relay=1-2
+w Bandwidth=1048
+p reject 1-65535
+id ed25519 ++ezzEs6r+0m0YDwFAjwpIIbNKtzMbKB13osAAoGQ/c
+m 25,26,27,28 sha256=kGlToMt+rD0tL3N+5Plqj8Nav1FVQMiSYpz0adtzs0I
+r zzzzzzzzzzzzzzzzzzz AEVz/pNLpV0H2ucjF3k69OQbdbY 1FUGYNQtQo1MgV4jRP2XJapWemI 2018-10-14 23:43:10 77.12.174.141 9002 9031
+s Fast Running V2Dir Valid
+v Tor 0.3.2.10
+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=565
+p reject 1-65535
+id ed25519 QnM3RTCh53wbKiC6N6IsCQHs3pj9J547xUNtrk5FnYE
+m 25,26,27,28 sha256=+1jqHQZNEebT5DFJHZIPE35at9TzFCB5hzqDWAxrXGk
+r helga AFnZKULbO4TlLrTYfp97GVz00AU ngp++P8hEV+Pj/j9OvvDCyuDqKA 2018-10-14 17:09:42 88.99.216.194 9001 9030
+s Fast 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=409
+p reject 1-65535
+id ed25519 M1nVVuHebCChHayS1hsajAkzpe4c8bEFKP499V3yBG4
+m 25,26,27,28 sha256=//iWXvWzIkvqFqwTf367uZJ2UoNwcrCrLcOs7DY5xvE
+r Torpi AHJ/OiwdDxcxqRJnxBFQecFrILQ bLi/i6JuuPmoWm1aGd73dy2tYlA 2018-10-14 15:51:48 110.146.4.151 9001 9030
+s Running Stable V2Dir Valid
+v Tor 0.2.4.29
+pr Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=1-4 LinkAuth=1 Microdesc=1 Relay=1-2
+w Bandwidth=92
+p reject 1-65535
+id ed25519 none
+m 25,26,27,28 sha256=TiQfeDGlZq6VrCEKFDCA0uvS6hiv8CVMdkLyRxuRZpU
+r VeespRU2 AHTsqCvVi4uxkJycTyN/2XebI/w r3AsIyXKvSFzC+5eDuiUgPTmG9g 2018-10-14 09:25:26 185.22.172.237 443 80
+s Fast Guard HSDir Running Stable V2Dir Valid
+v Tor 0.3.3.7
+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=10000
+p reject 1-65535
+id ed25519 obR35oXyInFbtgitDsbasslq2SNFSTZeI1+2bJfK6HE
+m 25,26,27,28 sha256=+tNKyFkcOSA/CufXMtSfprtve7qkoDx4yjGG/XdH6Ec
+r Quintex13 AHe8unJE2z5qXtJ0boYXAGZoSIc GwoBS5ddT7ktxwqHjHYNc2u53xU 2018-10-14 07:38:44 199.249.223.62 443 80
+s Exit Fast 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=9426
+p accept 20-23,43,53,79-81,88,110,143,194,220,389,443,464-465,531,543-544,554,563,587,636,706,749,873,902-904,981,989-995,1194,1220,1293,1500,1533,1677,1723,1755,1863,2082-2083,2086-2087,2095-2096,2102-2104,3128,3389,3690,4321,4643,5050,5190,5222-5223,5228,5900,6660-6669,6679,6697,8000,8008,8074,8080,8082,8087-8088,8232-8233,8332-8333,8443,8888,9418,9999-10000,11371,19294,19638,50002,64738
+id ed25519 cHUct3VAkb+T4KQQQg9fLuH5feoGyjxang+Jihs0E80
+m 25,26,27,28 sha256=/JQIKi/L0aSZ8uMKc0DsHBeH2OmsvAj9GbXq8i8QQcE
+r UbuntuCore246 AH4Yastcf3fGnzddzt9ZT/1r9pk 9kJql4jbylNMYXhvn4OasP55fck 2018-10-14 11:03:40 77.146.180.194 40523 0
+s Fast V2Dir Valid
+v Tor 0.3.3.10
+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=382
+p reject 1-65535
+id ed25519 rSPYL+kdnVmyJ9/Ni96SNABxuvE4DDLwO9l9tqeicoA
+m 25,26,27,28 sha256=hGcbcAmK7x/tNRe7iBBqNlj6sZByhmhTSwWw/wYZo3s
+r torrelay04 AH/ZCOnPz1nmT7pCt1cdLPQBvF0 n5XUymNehFnO8hTftwd4NIozrjQ 2018-10-14 18:52:54 159.69.153.73 9000 0
+a [2a01:4f8:1c1c:5cec::1]:9000
+s Fast Running Stable 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=8030
+p reject 1-65535
+id ed25519 OJfT1k1R4UB3eNZ7+Mx9MCh9a5RBXqCcqtDfqQw4UvA
+m 25,26,27 sha256=R60ONtNwXwpVOajWfWlH4yQ7a6rBYwgLJ87p5wH55fk
+m 28 sha256=8oP/xai6UYcjJY5gx9fgrLTYY66vgdAr4y2F+R7tqUQ
+r bigamy AH/cDMglli4ShKYaaMk4pmr75XA dMrr7wRTfKoVfCRHLuR0IZFSWsI 2018-10-14 13:28:57 185.24.218.171 9001 8080
+s Exit Fast 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=10000
+p accept 20-21,23,43,53,79-81,88,110,143,194,220,389,443,464-465,531,543-544,554,563,587,636,706,749,853,873,902-904,981,989-995,1220,1293,1500,1533,1677,1723,1755,1863,2082-2087,2095-2096,2102-2104,2374-2382,3128,3389,3690,4321,4643,5050,5190,5222-5223,5228,5900,6660-6669,6679,6697,8000-8100,8232-8233,8332-8333,8443,8888,9418,9999-10000,11371,19294,19638,50002,64738
+id ed25519 fTOvB48qkzbEyLpBemkuyBv9UieAUeM8RNfCypusrs0
+m 25,26,27,28 sha256=GpLj/6GejSGtvDxUAUrZgarLCVjbcZVDduWCqvShOBk
+r zech1989 AI57cMO0p1ILW+q4Bnq83I5j8f0 boK7UYxCaZy4lpe8irfYPFsX6SY 2018-10-14 21:18:08 185.243.53.99 9001 9030
+s 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=9726
+p reject 1-65535
+id ed25519 wPhoSjgH8xrZ/K2wKhYKd2IR6iQ2/pO4V9rIObVIZ30
+m 25,26,27,28 sha256=hx94DElvCTLaJLuCbKr5rShGxcpKpz8f5eZdYhXwfEQ
+r paris AJf70aisEQPfmPHoXdUsUPAdOtY 9x4Jiv45IDG4EDSSXfOd+Ss9qtc 2018-10-14 22:06:20 178.19.111.147 9001 8000
+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=10000
+p accept 20-21,23,43,53,79-81,88,110,143,194,220,389,443,464-465,531,543-544,554,563,587,636,706,749,853,873,902-904,981,989-995,1220,1293,1500,1533,1677,1723,1755,1863,2082-2087,2095-2096,2102-2104,2374-2382,3128,3389,3690,4321,4643,5050,5190,5222-5223,5228,5900,6660-6669,6679,6697,8000-8100,8232-8233,8332-8333,8443,8888,9418,9999-10000,11371,19294,19638,50002,64738
+id ed25519 s49ps0kX/BuncEzm6dG6ZmLs7DCanj/WcXlPVt0D7Tw
+m 25,26,27,28 sha256=L9vWM3tYYI2RLlnofu1m9nMTckLVSKMXftVTDUwidhw
+r jactr AJhR35M3VLAN3odvzkCIzhtJQME RLckbaDnNUH4qGCkOmDo20UwE28 2018-10-14 23:26:36 84.40.112.70 9001 9030
+s Fast HSDir Running Stable V2Dir Valid
+v Tor 0.2.9.15
+pr Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1-2 Link=1-4 LinkAuth=1 Microdesc=1-2 Relay=1-2
+w Bandwidth=131
+p reject 1-65535
+id ed25519 +Jc2Ppp+/hmdtaE8T2uxkZIhOD5/kCEfz8gyDCMiDpg
+m 25,26,27,28 sha256=tD+2RMOICoOQRFeZH6D4Kx8mRN4JzhfrtcQs8q78hPA
+r IsThisAGoodIdea AJ2M8WzPcSMatc5VyCoDRG2j+Us Gce3qKSpkK8w2D+9k75V7vNdWzI 2018-10-14 16:51:45 220.233.27.93 9001 0
+s Running Valid
+v Tor 0.3.3.9
+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=80
+p reject 1-65535
+id ed25519 peXjh3W6mWzg9iZALqNEDyP3ONQO7Vp9uSzqSszVHOA
+m 25,26,27,28 sha256=1jmLpMLTUMJr2IoHyDpGCrc/ZuBakhVUWivZ7NKwAz4
+directory-footer
+directory-signature 0232AF901C31A04EE9848595AF9BB7620D4C5B2E CD1FD971855430880D3C31E0331C5C55800C2F79
+-----BEGIN SIGNATURE-----
+CS6wJMEd74jA1bBTBt0CFPZXivvrvB9c8jf80z2TgHPo9WgUByCMx1+Gp5dHEKqy
+r3C2fgqF+1v8cMDy6vGGEkHTGWiyYt1Ge0mztr/tUcR7+sqqZychdUcVA9+abJ8P
+iI5whpWDieH+njn1BvphBVo2Hpzd/wCIqDanwaz6xHPxToINdGnA830SHGbs1b8H
+lLXWHuUjVSbkjHgN3NLd8nPjw1uOVIZBsWJa2dT6SCDkQCgbj5+g73kyk+OKJw4r
+ue8POxm8SOQT4BHTUfQH4Cgrje33nDJibTSymBOPAYkF6tIZsK7ujWEhnXbyciTQ
+dYM8WH+IZ9Iu31hyg277bQ==
+-----END SIGNATURE-----
diff --git a/src/test/resources/totalcw/2018-10-15-00-00-00-vote-27102BC123E7AF1D4741AE047E160C91ADC76B21-049AB3179B12DACC391F06A10C2A8904E4339D33.part b/src/test/resources/totalcw/2018-10-15-00-00-00-vote-27102BC123E7AF1D4741AE047E160C91ADC76B21-049AB3179B12DACC391F06A10C2A8904E4339D33.part
new file mode 100644
index 0000000..c73c6f5
--- /dev/null
+++ b/src/test/resources/totalcw/2018-10-15-00-00-00-vote-27102BC123E7AF1D4741AE047E160C91ADC76B21-049AB3179B12DACC391F06A10C2A8904E4339D33.part
@@ -0,0 +1,239 @@
+@type network-status-vote-3 1.0
+network-status-version 3
+vote-status vote
+consensus-methods 25 26 27 28
+published 2018-10-14 23:50:00
+valid-after 2018-10-15 00:00:00
+fresh-until 2018-10-15 01:00:00
+valid-until 2018-10-15 03:00:00
+voting-delay 300 300
+recommended-relay-protocols Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=4 Microdesc=1-2 Relay=2
+recommended-client-protocols Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=4 Microdesc=1-2 Relay=2
+required-relay-protocols Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=3-4 Microdesc=1 Relay=1-2
+required-client-protocols Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=4 Microdesc=1-2 Relay=2
+known-flags Authority Exit Fast Guard HSDir Running Stable V2Dir Valid
+flag-thresholds stable-uptime=1219572 stable-mtbf=3460952 fast-speed=90000 guard-wfu=98.000% guard-tk=691200 guard-bw-inc-exits=10400000 guard-bw-exc-exits=8880000 enough-mtbf=1 ignoring-advertised-bws=1
+params CircuitPriorityHalflifeMsec=30000 DoSCircuitCreationEnabled=1 DoSConnectionEnabled=1 DoSConnectionMaxConcurrentCount=50 DoSRefuseSingleHopClientRendezvous=1 NumDirectoryGuards=3 NumEntryGuards=1 NumNTorsPerTAP=100 Support022HiddenServices=0 UseNTorHandshake=1 UseOptimisticData=1 bwauthpid=1 cbttestfreq=10 hs_service_max_rdv_failures=1 hsdir_spread_store=4 pb_disablepct=0 usecreatefast=0
+dir-source bastet 27102BC123E7AF1D4741AE047E160C91ADC76B21 204.13.164.118 204.13.164.118 80 443
+contact stefani <nocat at readthefinemanual dot net>
+shared-rand-participate
+shared-rand-commit 1 sha3-256 27102BC123E7AF1D4741AE047E160C91ADC76B21 AAAAAFvD2IDJPppI/HhEtjCnUnd+nCJlpUZYS1f6jHZvFxFgnFtQXQ==
+shared-rand-previous-value 9 Vd2znClwwth89jp91diG/Bs1AH+0ExSgRFmyVOMJwwE=
+shared-rand-current-value 9 oiXRUZGkT26O9aQmu/A52utoBF3gp27h0TvJ4gkDHkw=
+dir-key-certificate-version 3
+fingerprint 27102BC123E7AF1D4741AE047E160C91ADC76B21
+dir-key-published 2018-10-10 00:02:19
+dir-key-expires 2019-10-10 00:02:19
+dir-identity-key
+-----BEGIN RSA PUBLIC KEY-----
+MIIBigKCAYEAuxgnMVH4vwBjMeGvrEODOYcjbCS4N+Wt0SZ6XA5I08HyMf5AbaaF
+MDscJBRIUOp7DyLmUwK+jp+QI8pUjjKsB8S0ctb/J3Im2T6CXnP2KgEfVmpNVQmV
+XdMm8cRZl1uIZDDBAXizSQ51f9A17TJh7pF/5khYp/SAzl6aO5ETn7ry0ITiJnNa
+6cY+400F7ZBA8NuXnCHVGfmpFFsiJKFrS1Kve629eeaNEd3mynRviBXJy5a4NEGf
+y42Ev8on6SxEnF9OG0NMJ081/+mP+j8Dsl3+Uehzr9B42MQQfDo4RdYGrt9XolBm
+L4eay1ieZEsFeDy0TMfiGGbr90wo1fgGLHIRSfTNLhhPJ/f9cTZPe98rhSgGWiAd
+RvK5SljoIOR4qdS9/aiZkj1P+etvh1rIQUcG4/xCOBnouEBK+DDHZFqyMtpMPtV0
+Bxi20DVaMJcyhdfjVqcRSyuR8tlOnTid6QwBj6kgIIfMaC+4Ht6yO/SYquCWlaZl
+y7Pu7li8WyW9AgMBAAE=
+-----END RSA PUBLIC KEY-----
+dir-signing-key
+-----BEGIN RSA PUBLIC KEY-----
+MIIBCgKCAQEAp/+6CgR/ptxWIt6uLCLt0t4e+yCq9i7MOcmcZlWHzIsP+sJxsPJO
+jqg5MycQsWt4wMUGCWj5ag+cozTGClfZ7dSxEzee5DoLa65RFK9ymFAnhUNs97sx
+F5CionrnUdjMO4MShALJgr7tXZ7I2/mwAG8foszEcl+dWhcaQio3WaT5rK/hLpiT
+URgYmieXaZWm1kLraI5DWnRY7GdFyWdBJKboStYpoJuYexUL7lbG7u7wqEG25N4+
+yFt8fiS7yjdlCf0WJRZlwmTLz87nn4Sqb/nYeqXKmT88LBs9D1csd8KgwOgyTkfb
+e7v+dTZSkqZYd0QXsqqxynZVKk63vWSXHwIDAQAB
+-----END RSA PUBLIC KEY-----
+dir-key-crosscert
+-----BEGIN ID SIGNATURE-----
+BNgMpEDYtEohkX1c0imNg4ATBxwPFeO01t1mgEQqyRZkihcfFi6Eb9stAqXto7Xs
+03QxovdfUP3kQvsidBBpt2WHBpW8CpARhwK8LvIPzu3q7SkLcW0d82qY29cRadfx
+yX2jBJVV4faH41IY5rt/EN6BAATFSnJ+IORFAX8A/75ZQ2H9EIOhdufkmA4zMGUx
+qKzU/L5LDyfTwWUJmsDYb492d1luws3EBkD5cDFyo5ab1rV7NwJw0al1m0pUF4Dm
+GSNtWlY1Lr/IUnPBksxY98TCkapgHKyq2FsnPJeSiTAHDIo1gpl2oJ0Lg5y2SBxZ
+FMmLq/Wt9rqbS216qVxX7w==
+-----END ID SIGNATURE-----
+dir-key-certification
+-----BEGIN SIGNATURE-----
+VEmK8S0LdEXDEGuF4QxLNQBtkQYEAParbBNLDT83XsLhXUfHja1MmkWJUemMpO0n
+R5eOVuHEegIbZzaIztYhgc0+4PKovx7q79rmPADwPACQxdB9dbzGhfgnxV1gfvQC
+CM6gfkruUDUqLoAtjeM++CMd8LgIOZBKmq4T4cQSUH2Mx7r+HYt/h2oqpWLGVufv
+wlE388tksfTdK9gVVht0MFBSTYjB5XEVLfF0LdxuOkHaiFJTUgJdGSecl8rtRSbq
+npy+Ex8Mjzsm//6asIdl2pWqkkmYNyqNeLxUl1r9xn1EOg8ZEWZ/L9L5EHkZvH1j
+YUS3ucYipsaT5QYOCmniLjLtQ6rkDABwn8F5co0RdIIrlIYjKMPGNUmwWz9rcYnC
+6L1DBttnMeLFC8zrn6OD3nI7Q7vrxj73Yl+gZhx2PIriHO01supq3+NGk743lHQu
+jF33Pili9eZU0J4bJzE/LLeVcEnlZPV3CRRvPuG/PTl/O2OCCyI2pM1IHVmp06SQ
+-----END SIGNATURE-----
+r seele AAoQ1DAR6kkoo19hBAX5K0QztNw xlbC5aW8ovDVh2t6VcKF/phheSg 2018-10-14 21:41:22 67.174.243.193 9001 0
+s 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=60 Measured=23
+p reject 1-65535
+id ed25519 ZtzhbIWHJpGQG+5N7hbRTtenyzq2RNJrx0QegtoY+bY
+m 25,26,27,28 sha256=4l7u4Oy1sCG/08MtsHimtWtaC1ydC/GOtCqRD/5ewgs
+r PutoElQueLee293884 AAwffNL+oHO5EdyUoWAOwvEX3ws Ay3cnaaHjnolSRe3ZjKcGlY17Q8 2018-10-14 08:06:47 174.127.217.73 55554 0
+s Fast Guard Running Stable V2Dir Valid
+v Tor 0.3.3.9
+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=4950 Measured=5620
+p reject 1-65535
+id ed25519 /58lPWzxxQfwoxed8I9l+D3+hTdOQ6RpgVgM9FCxil4
+m 25,26,27,28 sha256=0/b37HV9enGTzbwrxxg/0R5PfwRtRosXgtU5+vi/gBk
+r CalyxInstitute14 ABG9JIWtRdmE7EFZyI/AZuXjMA4 +8xNQyAVPkKgtLH0AISVZFNuAq0 2018-10-14 11:10:20 162.247.74.201 443 80
+s Exit Fast Guard HSDir Running Stable V2Dir Valid
+v Tor 0.3.3.7
+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=10000 Measured=25900
+p accept 20-23,43,53,79-81,88,110,143,194,220,389,443,464,531,543-544,554,563,636,706,749,873,902-904,981,989-995,1194,1220,1293,1500,1533,1677,1723,1755,1863,2082-2083,2086-2087,2095-2096,2102-2104,3128,3389,3690,4321,4643,5050,5190,5222-5223,5228,5900,6660-6669,6679,6697,8000,8008,8074,8080,8087-8088,8332-8333,8443,8888,9418,9999-10000,11371,12350,19294,19638,23456,33033,64738
+id ed25519 /AcSvVFxaIBxaB5I/7mwdVbMdP6JjDsEPVLU6Hj22a0
+m 25,26,27,28 sha256=7nBT4mYr4H5Jj71Qq7Nan7R7KqWPTRG89Oq1/5m4c1M
+r Neldoreth ABUk3UA9cp8I9+XXeBPvEnVs+o0 nms8ZM18C/K5XzLmgO5fHchjhFc 2018-10-14 19:09:56 185.13.39.197 443 80
+s Fast Guard 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=5242 Measured=10400
+p reject 1-65535
+id ed25519 eZ49J/mRCMtMbD2GDZsjZm/gqqG9z5S6M5GykZmd2ro
+m 25,26,27,28 sha256=IxCWEdRM6Hqk1fiYx+DK9ufUPI49SE6Z4C8onbsBVXo
+r UbuntuCore246 ACenhGJF+i26Aj46wfqAaI8dc7s EmwRg8iMnKJc8GEusZxhsVf9PJI 2018-10-14 23:13:35 212.199.61.38 43511 0
+s V2Dir Valid
+v Tor 0.3.3.10
+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=121 Measured=80
+p reject 1-65535
+id ed25519 crWebog3RcKMV49zyu6pF5A/MxQM89x2cKNRK1wbTjM
+m 25,26,27,28 sha256=98nmfhxVBZqk7VUfyXQWpJmLAfWloZtMXu5H9FVt+p8
+r rotor25 ADQsDhVdRULlU5F4iy13nxRXjes m/3hkTP+ETmoYWZ3JrniJAeRHho 2018-10-14 17:19:08 188.24.22.193 9001 9030
+s Fast Running 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=3987 Measured=3910
+p reject 1-65535
+id ed25519 8ybCWdul+E3HdzEb1YR3Fbp6EIwnGGPsUhsSh7FUnfs
+m 25,26,27,28 sha256=ZeMCL1T4SogPYK0iyuzYZoyFx+mp9/Ng8vGmE8wI9rU
+r torbogen AEHgFQsKMHUGwoY+/J8rfjpSOzY DXa3G+iPbGQo4AK2iazVY6R4eKs 2018-10-14 20:19:33 178.142.72.49 9001 9030
+s Fast Running V2Dir Valid
+v Tor 0.3.3.9
+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=1275 Measured=1070
+p reject 1-65535
+id ed25519 NzIv9KWavK4f+6426ctrr9UnsFl/Yt8ixEAP6OO/kVo
+m 25,26,27,28 sha256=lFXLHMP6Map0qD298F+eeybL4pqtXDRG7a7r4R7knlw
+r nicolass67atoll AES/YhfxWxj3ZvK1O85bPg4BV+k iK+QhopNtEipMSL+EeI6b/DitVc 2018-10-14 15:48:15 163.172.10.89 9001 0
+s Fast Running Stable V2Dir Valid
+v Tor 0.2.9.16
+pr Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1-2 Link=1-4 LinkAuth=1 Microdesc=1-2 Relay=1-2
+w Bandwidth=1048 Measured=320
+p reject 1-65535
+id ed25519 ++ezzEs6r+0m0YDwFAjwpIIbNKtzMbKB13osAAoGQ/c
+m 25,26,27,28 sha256=kGlToMt+rD0tL3N+5Plqj8Nav1FVQMiSYpz0adtzs0I
+r zzzzzzzzzzzzzzzzzzz AEVz/pNLpV0H2ucjF3k69OQbdbY 1FUGYNQtQo1MgV4jRP2XJapWemI 2018-10-14 23:43:10 77.12.174.141 9002 9031
+s Fast Running V2Dir Valid
+v Tor 0.3.2.10
+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=565 Measured=163
+p reject 1-65535
+id ed25519 QnM3RTCh53wbKiC6N6IsCQHs3pj9J547xUNtrk5FnYE
+m 25,26,27,28 sha256=+1jqHQZNEebT5DFJHZIPE35at9TzFCB5hzqDWAxrXGk
+r helga AFnZKULbO4TlLrTYfp97GVz00AU ngp++P8hEV+Pj/j9OvvDCyuDqKA 2018-10-14 17:09:42 88.99.216.194 9001 9030
+s Fast 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=409 Measured=245
+p reject 1-65535
+id ed25519 M1nVVuHebCChHayS1hsajAkzpe4c8bEFKP499V3yBG4
+m 25,26,27,28 sha256=//iWXvWzIkvqFqwTf367uZJ2UoNwcrCrLcOs7DY5xvE
+r Torpi AHJ/OiwdDxcxqRJnxBFQecFrILQ bLi/i6JuuPmoWm1aGd73dy2tYlA 2018-10-14 15:51:48 110.146.4.151 9001 9030
+s Running Stable V2Dir Valid
+v Tor 0.2.4.29
+pr Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=1-4 LinkAuth=1 Microdesc=1 Relay=1-2
+w Bandwidth=92 Measured=18
+p reject 1-65535
+id ed25519 none
+m 25,26,27,28 sha256=TiQfeDGlZq6VrCEKFDCA0uvS6hiv8CVMdkLyRxuRZpU
+r VeespRU2 AHTsqCvVi4uxkJycTyN/2XebI/w r3AsIyXKvSFzC+5eDuiUgPTmG9g 2018-10-14 09:25:26 185.22.172.237 443 80
+s Fast Guard HSDir Running Stable V2Dir Valid
+v Tor 0.3.3.7
+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=10000 Measured=20500
+p reject 1-65535
+id ed25519 obR35oXyInFbtgitDsbasslq2SNFSTZeI1+2bJfK6HE
+m 25,26,27,28 sha256=+tNKyFkcOSA/CufXMtSfprtve7qkoDx4yjGG/XdH6Ec
+r Quintex13 AHe8unJE2z5qXtJ0boYXAGZoSIc GwoBS5ddT7ktxwqHjHYNc2u53xU 2018-10-14 07:38:44 199.249.223.62 443 80
+s Exit Fast 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=9426 Measured=7570
+p accept 20-23,43,53,79-81,88,110,143,194,220,389,443,464-465,531,543-544,554,563,587,636,706,749,873,902-904,981,989-995,1194,1220,1293,1500,1533,1677,1723,1755,1863,2082-2083,2086-2087,2095-2096,2102-2104,3128,3389,3690,4321,4643,5050,5190,5222-5223,5228,5900,6660-6669,6679,6697,8000,8008,8074,8080,8082,8087-8088,8232-8233,8332-8333,8443,8888,9418,9999-10000,11371,19294,19638,50002,64738
+id ed25519 cHUct3VAkb+T4KQQQg9fLuH5feoGyjxang+Jihs0E80
+m 25,26,27,28 sha256=/JQIKi/L0aSZ8uMKc0DsHBeH2OmsvAj9GbXq8i8QQcE
+r UbuntuCore246 AH4Yastcf3fGnzddzt9ZT/1r9pk 9kJql4jbylNMYXhvn4OasP55fck 2018-10-14 11:03:40 77.146.180.194 40523 0
+s V2Dir Valid
+v Tor 0.3.3.10
+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=382 Measured=23
+p reject 1-65535
+id ed25519 rSPYL+kdnVmyJ9/Ni96SNABxuvE4DDLwO9l9tqeicoA
+m 25,26,27,28 sha256=hGcbcAmK7x/tNRe7iBBqNlj6sZByhmhTSwWw/wYZo3s
+r torrelay04 AH/ZCOnPz1nmT7pCt1cdLPQBvF0 n5XUymNehFnO8hTftwd4NIozrjQ 2018-10-14 18:52:54 159.69.153.73 9000 0
+a [2a01:4f8:1c1c:5cec::1]:9000
+s Fast Running Stable 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=8030 Measured=7880
+p reject 1-65535
+id ed25519 OJfT1k1R4UB3eNZ7+Mx9MCh9a5RBXqCcqtDfqQw4UvA
+m 25,26,27 sha256=R60ONtNwXwpVOajWfWlH4yQ7a6rBYwgLJ87p5wH55fk
+m 28 sha256=8oP/xai6UYcjJY5gx9fgrLTYY66vgdAr4y2F+R7tqUQ
+r bigamy AH/cDMglli4ShKYaaMk4pmr75XA dMrr7wRTfKoVfCRHLuR0IZFSWsI 2018-10-14 13:28:57 185.24.218.171 9001 8080
+s Exit Fast 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=10000 Measured=9510
+p accept 20-21,23,43,53,79-81,88,110,143,194,220,389,443,464-465,531,543-544,554,563,587,636,706,749,853,873,902-904,981,989-995,1220,1293,1500,1533,1677,1723,1755,1863,2082-2087,2095-2096,2102-2104,2374-2382,3128,3389,3690,4321,4643,5050,5190,5222-5223,5228,5900,6660-6669,6679,6697,8000-8100,8232-8233,8332-8333,8443,8888,9418,9999-10000,11371,19294,19638,50002,64738
+id ed25519 fTOvB48qkzbEyLpBemkuyBv9UieAUeM8RNfCypusrs0
+m 25,26,27,28 sha256=GpLj/6GejSGtvDxUAUrZgarLCVjbcZVDduWCqvShOBk
+r zech1989 AI57cMO0p1ILW+q4Bnq83I5j8f0 boK7UYxCaZy4lpe8irfYPFsX6SY 2018-10-14 21:18:08 185.243.53.99 9001 9030
+s 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=9726 Measured=10700
+p reject 1-65535
+id ed25519 wPhoSjgH8xrZ/K2wKhYKd2IR6iQ2/pO4V9rIObVIZ30
+m 25,26,27,28 sha256=hx94DElvCTLaJLuCbKr5rShGxcpKpz8f5eZdYhXwfEQ
+r paris AJf70aisEQPfmPHoXdUsUPAdOtY 9x4Jiv45IDG4EDSSXfOd+Ss9qtc 2018-10-14 22:06:20 178.19.111.147 9001 8000
+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=10000 Measured=34800
+p accept 20-21,23,43,53,79-81,88,110,143,194,220,389,443,464-465,531,543-544,554,563,587,636,706,749,853,873,902-904,981,989-995,1220,1293,1500,1533,1677,1723,1755,1863,2082-2087,2095-2096,2102-2104,2374-2382,3128,3389,3690,4321,4643,5050,5190,5222-5223,5228,5900,6660-6669,6679,6697,8000-8100,8232-8233,8332-8333,8443,8888,9418,9999-10000,11371,19294,19638,50002,64738
+id ed25519 s49ps0kX/BuncEzm6dG6ZmLs7DCanj/WcXlPVt0D7Tw
+m 25,26,27,28 sha256=L9vWM3tYYI2RLlnofu1m9nMTckLVSKMXftVTDUwidhw
+r jactr AJhR35M3VLAN3odvzkCIzhtJQME RLckbaDnNUH4qGCkOmDo20UwE28 2018-10-14 23:26:36 84.40.112.70 9001 9030
+s Running Stable V2Dir Valid
+v Tor 0.2.9.15
+pr Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1-2 Link=1-4 LinkAuth=1 Microdesc=1-2 Relay=1-2
+w Bandwidth=131 Measured=66
+p reject 1-65535
+id ed25519 +Jc2Ppp+/hmdtaE8T2uxkZIhOD5/kCEfz8gyDCMiDpg
+m 25,26,27,28 sha256=tD+2RMOICoOQRFeZH6D4Kx8mRN4JzhfrtcQs8q78hPA
+r IsThisAGoodIdea AJ2M8WzPcSMatc5VyCoDRG2j+Us Gce3qKSpkK8w2D+9k75V7vNdWzI 2018-10-14 16:51:45 220.233.27.93 9001 0
+s Running Valid
+v Tor 0.3.3.9
+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=80 Measured=5
+p reject 1-65535
+id ed25519 peXjh3W6mWzg9iZALqNEDyP3ONQO7Vp9uSzqSszVHOA
+m 25,26,27,28 sha256=1jmLpMLTUMJr2IoHyDpGCrc/ZuBakhVUWivZ7NKwAz4
+directory-footer
+directory-signature 27102BC123E7AF1D4741AE047E160C91ADC76B21 6FF3CD454038B7FDD7862B2DD778E4F702C31419
+-----BEGIN SIGNATURE-----
+ICRgDdm/BcGDGUaofpzbAwYibBsX9o88sIZ8Wec0w+LD8RBQT0G6/9S+joAJECZv
+WkJk+IqLhcipWAsTdts3ckCgPfP8x8DNmfdk0RhXf4otaYPs3wn5LD6hXnoXh+OU
+QJ7DQbM+Hw5+K3F5gd8s2AW3GgL1g6REBC3kfZwijI8ovG8SIbr7+npVTGHRwm11
+F0IiEGRMnhedDRAdhhEVnVgyRWjfJEdFe8VzUzFAF7yjCNgVzVE++e+g2afrMXaJ
+GYiWsJcKsgwbEUcFI6nvyPnbBGm8bTBnhhZFf60Ao5b0gNXpdGQVwAAHTwncLMCZ
+/faPhIKZreAjmt5vtvPsXg==
+-----END SIGNATURE-----
diff --git a/src/test/resources/totalcw/2018-10-15-00-00-00-vote-ED03BB616EB2F60BEC80151114BB25CEF515B226-2669AD153408F88E416CE6206D1A75EC3324A2F4.part b/src/test/resources/totalcw/2018-10-15-00-00-00-vote-ED03BB616EB2F60BEC80151114BB25CEF515B226-2669AD153408F88E416CE6206D1A75EC3324A2F4.part
new file mode 100644
index 0000000..13c618f
--- /dev/null
+++ b/src/test/resources/totalcw/2018-10-15-00-00-00-vote-ED03BB616EB2F60BEC80151114BB25CEF515B226-2669AD153408F88E416CE6206D1A75EC3324A2F4.part
@@ -0,0 +1,241 @@
+@type network-status-vote-3 1.0
+network-status-version 3
+vote-status vote
+consensus-methods 25 26 27 28
+published 2018-10-14 23:50:00
+valid-after 2018-10-15 00:00:00
+fresh-until 2018-10-15 01:00:00
+valid-until 2018-10-15 03:00:00
+voting-delay 300 300
+client-versions 0.2.9.14,0.2.9.15,0.2.9.16,0.2.9.17,0.3.2.6-alpha,0.3.2.7-rc,0.3.2.8-rc,0.3.2.9,0.3.2.10,0.3.2.11,0.3.2.12,0.3.3.1-alpha,0.3.3.2-alpha,0.3.3.3-alpha,0.3.3.4-alpha,0.3.3.5-rc,0.3.3.6,0.3.3.7,0.3.3.8,0.3.3.9,0.3.3.10,0.3.4.1-alpha,0.3.4.2-alpha,0.3.4.3-alpha,0.3.4.4-rc,0.3.4.5-rc,0.3.4.6-rc,0.3.4.7-rc,0.3.4.8,0.3.5.1-alpha,0.3.5.2-alpha,0.3.5.3-alpha
+server-versions 0.2.9.14,0.2.9.15,0.2.9.16,0.2.9.17,0.3.2.10,0.3.2.11,0.3.2.12,0.3.3.2-alpha,0.3.3.3-alpha,0.3.3.4-alpha,0.3.3.5-rc,0.3.3.6,0.3.3.7,0.3.3.8,0.3.3.9,0.3.3.10,0.3.4.1-alpha,0.3.4.2-alpha,0.3.4.3-alpha,0.3.4.4-rc,0.3.4.5-rc,0.3.4.6-rc,0.3.4.7-rc,0.3.4.8,0.3.5.1-alpha,0.3.5.2-alpha,0.3.5.3-alpha
+recommended-relay-protocols Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=4 Microdesc=1-2 Relay=2
+recommended-client-protocols Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=4 Microdesc=1-2 Relay=2
+required-relay-protocols Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=3-4 Microdesc=1 Relay=1-2
+required-client-protocols Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=4 Microdesc=1-2 Relay=2
+known-flags Authority BadExit Exit Fast Guard HSDir Running Stable V2Dir Valid
+flag-thresholds stable-uptime=1260391 stable-mtbf=3650978 fast-speed=53000 guard-wfu=98.000% guard-tk=691200 guard-bw-inc-exits=11000000 guard-bw-exc-exits=9050000 enough-mtbf=1 ignoring-advertised-bws=1
+params CircuitPriorityHalflifeMsec=30000 DoSCircuitCreationEnabled=1 DoSConnectionEnabled=1 DoSConnectionMaxConcurrentCount=50 DoSRefuseSingleHopClientRendezvous=1 NumDirectoryGuards=3 NumEntryGuards=1 NumNTorsPerTAP=100 Support022HiddenServices=0 UseNTorHandshake=1 UseOptimisticData=1 bwauthpid=1 cbttestfreq=10 hs_service_max_rdv_failures=1 hsdir_spread_store=4 pb_disablepct=0 usecreatefast=0
+dir-source gabelmoo ED03BB616EB2F60BEC80151114BB25CEF515B226 131.188.40.189 131.188.40.189 80 443
+contact 4096R/261C5FBE77285F88FB0C343266C8C2D7C5AA446D Sebastian Hahn <tor@xxxxxxxxxxxxxxxxx> - 12NbRAjAG5U3LLWETSF7fSTcdaz32Mu5CN
+shared-rand-participate
+shared-rand-commit 1 sha3-256 ED03BB616EB2F60BEC80151114BB25CEF515B226 AAAAAFvD2ID7sH6uVUd8dxs2u8VPr+JTJ14S6SLVjh69b5m7hTQEJA==
+shared-rand-previous-value 9 Vd2znClwwth89jp91diG/Bs1AH+0ExSgRFmyVOMJwwE=
+shared-rand-current-value 9 oiXRUZGkT26O9aQmu/A52utoBF3gp27h0TvJ4gkDHkw=
+dir-key-certificate-version 3
+fingerprint ED03BB616EB2F60BEC80151114BB25CEF515B226
+dir-key-published 2018-08-19 12:38:04
+dir-key-expires 2019-08-19 12:38:04
+dir-identity-key
+-----BEGIN RSA PUBLIC KEY-----
+MIIBigKCAYEA1d6uTRiqdMp4BHBYIHKR6NB599Z1Bqw4TbOVkM2N1aSA4V/L/hKI
+nl6m/2LL/UAS+E3NCFX0dhw2+D7r7BTJyfGwz0H2MR6Py5/rCMAnPl20wCjXk2qY
+ACQa0rJvIqXobwGnDlvxn4ezsj0IEY/FEb61zHnnPHf6d3uyFR1QT06qEOQyYzML
+76f/Lud8MUt+8KzsdnadAPL8okNvcS/nqa2bWbbGhC8S8rtDpPg5BhX2ikXa88RM
+QdrrackdppB2ttHlq9+iH3c8Wyp7bvdH8uhv410W7RnIE4P+KIxt3L0gqkxCjjyh
+mn9ONcdgNOKe31q2cdW5LOPSIK+I5/VTjYjICza7Euyg03drpoBMGLuuJZY6FXEV
+auIBncWe+So8FMxqU/fwo5xm6x085U1MwXUmi4XDYpr/kau6ytPnzzw9J++4W9iC
+em5Jp0vaxrDnPdphqT0FWsBAwsZFL7nZRnmUlTgGsXUa0oSM9/MErDwzELh/NwG4
+DNyyzRG8iP61AgMBAAE=
+-----END RSA PUBLIC KEY-----
+dir-signing-key
+-----BEGIN RSA PUBLIC KEY-----
+MIIBCgKCAQEAxtiD0MuGDfRBqibc06jZXSPoF5s0ToVSrVfNO75dYvfM9zabW+1q
+EP18KUFxeShMqd2mmj685XbGnGX49I5gjzezjaIMcszpiPHQNmr9McnX97yR62YJ
+XKy0i6lvKXLUb5y8V5HmdqKQ8HyCqsRcYFTFrHNCWC+oIhRrqpeQ5kSIdWiO2HCt
+rzx9mAgGLRNFTy+EsxAFzuHaJVV5U7g/G4RMYXMP514aSpJVNgd2kdkXWsSIQ4HX
+a/vRNECuBQyJ1YpHySqqpdOogJxFot8oW/WkmFTGh/amJjMrTUNGgDMD5mpwMCRV
+ifA4hQzvJljkmfGMwgU8kYraMLDHvKzu4wIDAQAB
+-----END RSA PUBLIC KEY-----
+dir-key-crosscert
+-----BEGIN ID SIGNATURE-----
+ruE2woKIct6glnXsJOjnj0thwiv2KYTr/vVMcX5I4OBgzNj9jQPuXe84fUvFNsyQ
+DVf0p6xrjnSmDjdsEpmZUtN16So9m/Zw7Xmn7v7Ktq8TS4jguA1xfhvPxlk7KTz4
+Fxkg3si4qWs00PZxiLERBK3bqMSChPOrzO9AZTjCAngeMIc8+TkXX8EowfqJDO92
+uGCtZReWfFMPObr0Ki4UDOzlTsx4zriRvMNjNqKC43tj2l0jj8RpSDmsWG0QeS+A
+983kODQiVx5URr0O4eev1l0+pI+i8o2+05ZRci32cqvtlonKEtREbgUXzlMHU/ps
+V3kONRvhP+0ABHL/JCVTzg==
+-----END ID SIGNATURE-----
+dir-key-certification
+-----BEGIN SIGNATURE-----
+MYFZL03QkjZKPN8uckION+Yzb3icKjxnzUqtgmTeBaxrjLCsxAXhKFgzgDZkDzun
+REk+fSc9yG2YpxxUgE/l2ya36gr695q0EyJjnbQoNNgBX8YbeN0WaJER/jQtd5tY
+3hEPnSqz33jUGf/BmBqO+ZHOrSKY7CLhMrSxY+NgjcdGWwI0eDrnAklGfgG6xVFe
+YcXjj9aPB4+CtGJ0pgGM9SCZxETtCyBsJNYuYzowA/tz7VnymD8o3/CnW7bAlkGa
+6YsMibhAKxKl/lBcBDcRz8HPVdj4txME9d5YAmejIDIIRscEQ56LqDBrwvHJ6Gkl
+KQJXUwEiMAjM/wVLxd7zvgHOrR/hipCPe9vnVpYaSO446Z5d85p39BXR2x+vDfiT
+nOsiF+J+Sk13KTt+45gp26lMzY5E03BxKXY3izs7zEl6BZHM+95dC211C6xlojuP
+c8WkUcJuyb0xFS3nUy+dhLBzdW8nKlu/7Hn7uzugUUN4AWX/34+2qTqhNy0d2+Et
+-----END SIGNATURE-----
+r seele AAoQ1DAR6kkoo19hBAX5K0QztNw xlbC5aW8ovDVh2t6VcKF/phheSg 2018-10-14 21:41:22 67.174.243.193 9001 0
+s 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=60 Measured=4
+p reject 1-65535
+id ed25519 ZtzhbIWHJpGQG+5N7hbRTtenyzq2RNJrx0QegtoY+bY
+m 25,26,27,28 sha256=4l7u4Oy1sCG/08MtsHimtWtaC1ydC/GOtCqRD/5ewgs
+r PutoElQueLee293884 AAwffNL+oHO5EdyUoWAOwvEX3ws Ay3cnaaHjnolSRe3ZjKcGlY17Q8 2018-10-14 08:06:47 174.127.217.73 55554 0
+s Fast Guard Running Stable V2Dir Valid
+v Tor 0.3.3.9
+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=4950 Measured=4380
+p reject 1-65535
+id ed25519 /58lPWzxxQfwoxed8I9l+D3+hTdOQ6RpgVgM9FCxil4
+m 25,26,27,28 sha256=0/b37HV9enGTzbwrxxg/0R5PfwRtRosXgtU5+vi/gBk
+r CalyxInstitute14 ABG9JIWtRdmE7EFZyI/AZuXjMA4 +8xNQyAVPkKgtLH0AISVZFNuAq0 2018-10-14 11:10:20 162.247.74.201 443 80
+s Exit Fast Guard HSDir Running Stable V2Dir Valid
+v Tor 0.3.3.7
+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=10000 Measured=14400
+p accept 20-23,43,53,79-81,88,110,143,194,220,389,443,464,531,543-544,554,563,636,706,749,873,902-904,981,989-995,1194,1220,1293,1500,1533,1677,1723,1755,1863,2082-2083,2086-2087,2095-2096,2102-2104,3128,3389,3690,4321,4643,5050,5190,5222-5223,5228,5900,6660-6669,6679,6697,8000,8008,8074,8080,8087-8088,8332-8333,8443,8888,9418,9999-10000,11371,12350,19294,19638,23456,33033,64738
+id ed25519 /AcSvVFxaIBxaB5I/7mwdVbMdP6JjDsEPVLU6Hj22a0
+m 25,26,27,28 sha256=7nBT4mYr4H5Jj71Qq7Nan7R7KqWPTRG89Oq1/5m4c1M
+r Neldoreth ABUk3UA9cp8I9+XXeBPvEnVs+o0 nms8ZM18C/K5XzLmgO5fHchjhFc 2018-10-14 19:09:56 185.13.39.197 443 80
+s Fast Guard 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=5242 Measured=13600
+p reject 1-65535
+id ed25519 eZ49J/mRCMtMbD2GDZsjZm/gqqG9z5S6M5GykZmd2ro
+m 25,26,27,28 sha256=IxCWEdRM6Hqk1fiYx+DK9ufUPI49SE6Z4C8onbsBVXo
+r UbuntuCore246 ACenhGJF+i26Aj46wfqAaI8dc7s EmwRg8iMnKJc8GEusZxhsVf9PJI 2018-10-14 23:13:35 212.199.61.38 43511 0
+s Fast V2Dir Valid
+v Tor 0.3.3.10
+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=121 Measured=71
+p reject 1-65535
+id ed25519 crWebog3RcKMV49zyu6pF5A/MxQM89x2cKNRK1wbTjM
+m 25,26,27,28 sha256=98nmfhxVBZqk7VUfyXQWpJmLAfWloZtMXu5H9FVt+p8
+r rotor25 ADQsDhVdRULlU5F4iy13nxRXjes m/3hkTP+ETmoYWZ3JrniJAeRHho 2018-10-14 17:19:08 188.24.22.193 9001 9030
+s Fast Running 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=3987 Measured=6730
+p reject 1-65535
+id ed25519 8ybCWdul+E3HdzEb1YR3Fbp6EIwnGGPsUhsSh7FUnfs
+m 25,26,27,28 sha256=ZeMCL1T4SogPYK0iyuzYZoyFx+mp9/Ng8vGmE8wI9rU
+r torbogen AEHgFQsKMHUGwoY+/J8rfjpSOzY DXa3G+iPbGQo4AK2iazVY6R4eKs 2018-10-14 20:19:33 178.142.72.49 9001 9030
+s Fast Running V2Dir Valid
+v Tor 0.3.3.9
+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=1275 Measured=1030
+p reject 1-65535
+id ed25519 NzIv9KWavK4f+6426ctrr9UnsFl/Yt8ixEAP6OO/kVo
+m 25,26,27,28 sha256=lFXLHMP6Map0qD298F+eeybL4pqtXDRG7a7r4R7knlw
+r nicolass67atoll AES/YhfxWxj3ZvK1O85bPg4BV+k iK+QhopNtEipMSL+EeI6b/DitVc 2018-10-14 15:48:15 163.172.10.89 9001 0
+s Fast Running Stable V2Dir Valid
+v Tor 0.2.9.16
+pr Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1-2 Link=1-4 LinkAuth=1 Microdesc=1-2 Relay=1-2
+w Bandwidth=1048 Measured=1180
+p reject 1-65535
+id ed25519 ++ezzEs6r+0m0YDwFAjwpIIbNKtzMbKB13osAAoGQ/c
+m 25,26,27,28 sha256=kGlToMt+rD0tL3N+5Plqj8Nav1FVQMiSYpz0adtzs0I
+r zzzzzzzzzzzzzzzzzzz AEVz/pNLpV0H2ucjF3k69OQbdbY 1FUGYNQtQo1MgV4jRP2XJapWemI 2018-10-14 23:43:10 77.12.174.141 9002 9031
+s Fast Running V2Dir Valid
+v Tor 0.3.2.10
+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=565 Measured=235
+p reject 1-65535
+id ed25519 QnM3RTCh53wbKiC6N6IsCQHs3pj9J547xUNtrk5FnYE
+m 25,26,27,28 sha256=+1jqHQZNEebT5DFJHZIPE35at9TzFCB5hzqDWAxrXGk
+r helga AFnZKULbO4TlLrTYfp97GVz00AU ngp++P8hEV+Pj/j9OvvDCyuDqKA 2018-10-14 17:09:42 88.99.216.194 9001 9030
+s Fast 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=409 Measured=328
+p reject 1-65535
+id ed25519 M1nVVuHebCChHayS1hsajAkzpe4c8bEFKP499V3yBG4
+m 25,26,27,28 sha256=//iWXvWzIkvqFqwTf367uZJ2UoNwcrCrLcOs7DY5xvE
+r Torpi AHJ/OiwdDxcxqRJnxBFQecFrILQ bLi/i6JuuPmoWm1aGd73dy2tYlA 2018-10-14 15:51:48 110.146.4.151 9001 9030
+s Running Stable V2Dir Valid
+v Tor 0.2.4.29
+pr Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=1-4 LinkAuth=1 Microdesc=1 Relay=1-2
+w Bandwidth=92 Measured=14
+p reject 1-65535
+id ed25519 none
+m 25,26,27,28 sha256=TiQfeDGlZq6VrCEKFDCA0uvS6hiv8CVMdkLyRxuRZpU
+r VeespRU2 AHTsqCvVi4uxkJycTyN/2XebI/w r3AsIyXKvSFzC+5eDuiUgPTmG9g 2018-10-14 09:25:26 185.22.172.237 443 80
+s Fast Guard HSDir Running Stable V2Dir Valid
+v Tor 0.3.3.7
+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=10000 Measured=21300
+p reject 1-65535
+id ed25519 obR35oXyInFbtgitDsbasslq2SNFSTZeI1+2bJfK6HE
+m 25,26,27,28 sha256=+tNKyFkcOSA/CufXMtSfprtve7qkoDx4yjGG/XdH6Ec
+r Quintex13 AHe8unJE2z5qXtJ0boYXAGZoSIc GwoBS5ddT7ktxwqHjHYNc2u53xU 2018-10-14 07:38:44 199.249.223.62 443 80
+s Exit Fast 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=9426 Measured=4550
+p accept 20-23,43,53,79-81,88,110,143,194,220,389,443,464-465,531,543-544,554,563,587,636,706,749,873,902-904,981,989-995,1194,1220,1293,1500,1533,1677,1723,1755,1863,2082-2083,2086-2087,2095-2096,2102-2104,3128,3389,3690,4321,4643,5050,5190,5222-5223,5228,5900,6660-6669,6679,6697,8000,8008,8074,8080,8082,8087-8088,8232-8233,8332-8333,8443,8888,9418,9999-10000,11371,19294,19638,50002,64738
+id ed25519 cHUct3VAkb+T4KQQQg9fLuH5feoGyjxang+Jihs0E80
+m 25,26,27,28 sha256=/JQIKi/L0aSZ8uMKc0DsHBeH2OmsvAj9GbXq8i8QQcE
+r UbuntuCore246 AH4Yastcf3fGnzddzt9ZT/1r9pk 9kJql4jbylNMYXhvn4OasP55fck 2018-10-14 11:03:40 77.146.180.194 40523 0
+s V2Dir Valid
+v Tor 0.3.3.10
+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=382
+p reject 1-65535
+id ed25519 rSPYL+kdnVmyJ9/Ni96SNABxuvE4DDLwO9l9tqeicoA
+m 25,26,27,28 sha256=hGcbcAmK7x/tNRe7iBBqNlj6sZByhmhTSwWw/wYZo3s
+r torrelay04 AH/ZCOnPz1nmT7pCt1cdLPQBvF0 n5XUymNehFnO8hTftwd4NIozrjQ 2018-10-14 18:52:54 159.69.153.73 9000 0
+a [2a01:4f8:1c1c:5cec::1]:9000
+s Fast Running Stable 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=8030 Measured=8460
+p reject 1-65535
+id ed25519 OJfT1k1R4UB3eNZ7+Mx9MCh9a5RBXqCcqtDfqQw4UvA
+m 25,26,27 sha256=R60ONtNwXwpVOajWfWlH4yQ7a6rBYwgLJ87p5wH55fk
+m 28 sha256=8oP/xai6UYcjJY5gx9fgrLTYY66vgdAr4y2F+R7tqUQ
+r bigamy AH/cDMglli4ShKYaaMk4pmr75XA dMrr7wRTfKoVfCRHLuR0IZFSWsI 2018-10-14 13:28:57 185.24.218.171 9001 8080
+s Exit Fast 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=10000 Measured=21600
+p accept 20-21,23,43,53,79-81,88,110,143,194,220,389,443,464-465,531,543-544,554,563,587,636,706,749,853,873,902-904,981,989-995,1220,1293,1500,1533,1677,1723,1755,1863,2082-2087,2095-2096,2102-2104,2374-2382,3128,3389,3690,4321,4643,5050,5190,5222-5223,5228,5900,6660-6669,6679,6697,8000-8100,8232-8233,8332-8333,8443,8888,9418,9999-10000,11371,19294,19638,50002,64738
+id ed25519 fTOvB48qkzbEyLpBemkuyBv9UieAUeM8RNfCypusrs0
+m 25,26,27,28 sha256=GpLj/6GejSGtvDxUAUrZgarLCVjbcZVDduWCqvShOBk
+r zech1989 AI57cMO0p1ILW+q4Bnq83I5j8f0 boK7UYxCaZy4lpe8irfYPFsX6SY 2018-10-14 21:18:08 185.243.53.99 9001 9030
+s 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=9726 Measured=3920
+p reject 1-65535
+id ed25519 wPhoSjgH8xrZ/K2wKhYKd2IR6iQ2/pO4V9rIObVIZ30
+m 25,26,27,28 sha256=hx94DElvCTLaJLuCbKr5rShGxcpKpz8f5eZdYhXwfEQ
+r paris AJf70aisEQPfmPHoXdUsUPAdOtY 9x4Jiv45IDG4EDSSXfOd+Ss9qtc 2018-10-14 22:06:20 178.19.111.147 9001 8000
+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=10000 Measured=31600
+p accept 20-21,23,43,53,79-81,88,110,143,194,220,389,443,464-465,531,543-544,554,563,587,636,706,749,853,873,902-904,981,989-995,1220,1293,1500,1533,1677,1723,1755,1863,2082-2087,2095-2096,2102-2104,2374-2382,3128,3389,3690,4321,4643,5050,5190,5222-5223,5228,5900,6660-6669,6679,6697,8000-8100,8232-8233,8332-8333,8443,8888,9418,9999-10000,11371,19294,19638,50002,64738
+id ed25519 s49ps0kX/BuncEzm6dG6ZmLs7DCanj/WcXlPVt0D7Tw
+m 25,26,27,28 sha256=L9vWM3tYYI2RLlnofu1m9nMTckLVSKMXftVTDUwidhw
+r jactr AJhR35M3VLAN3odvzkCIzhtJQME RLckbaDnNUH4qGCkOmDo20UwE28 2018-10-14 23:26:36 84.40.112.70 9001 9030
+s Running Stable V2Dir Valid
+v Tor 0.2.9.15
+pr Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1-2 Link=1-4 LinkAuth=1 Microdesc=1-2 Relay=1-2
+w Bandwidth=131 Measured=37
+p reject 1-65535
+id ed25519 +Jc2Ppp+/hmdtaE8T2uxkZIhOD5/kCEfz8gyDCMiDpg
+m 25,26,27,28 sha256=tD+2RMOICoOQRFeZH6D4Kx8mRN4JzhfrtcQs8q78hPA
+r IsThisAGoodIdea AJ2M8WzPcSMatc5VyCoDRG2j+Us Gce3qKSpkK8w2D+9k75V7vNdWzI 2018-10-14 16:51:45 220.233.27.93 9001 0
+s Running Valid
+v Tor 0.3.3.9
+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=80 Measured=2
+p reject 1-65535
+id ed25519 peXjh3W6mWzg9iZALqNEDyP3ONQO7Vp9uSzqSszVHOA
+m 25,26,27,28 sha256=1jmLpMLTUMJr2IoHyDpGCrc/ZuBakhVUWivZ7NKwAz4
+directory-footer
+directory-signature ED03BB616EB2F60BEC80151114BB25CEF515B226 E1249D5F87EAD43CD4A48DF9CFCFE810BEEE5287
+-----BEGIN SIGNATURE-----
+sj0ppS2fGOktEGRBXEQJ7KjG+rjBUWNlTUGa9XDbUEbrSDGsKC7ik2r/k0nTCmYI
+FFDmaOhIgpEoz8548RkA0ZdKt8SQQHGHQ82zeDQ8IxLP2bsZj+Jmn/NHN3KwUnpc
+tc+/olUskXOVpKZaoZDXXTzOSypOhV6MHJFQ6AjkGj6BO6VnTVfmdDNf/McEPQvw
+4y6KF3NDjgXoea7sDy6IswuZK+Neia0GPTQVOIit1F06ka2cvOk2gOVEIXqHyGQi
+erJUZfMCbKUIX3IFlhuOgnx9x0Wp/U+Jx8JO+i7NxIyUhR56EY1Go6+mxxRR2wTB
+p1+T39J1+80MEXuRaguLCg==
+-----END SIGNATURE-----
diff --git a/src/test/resources/totalcw/2018-10-15-00-00-00-vote-EFCBE720AB3A82B99F9E953CD5BF50F7EEFC7B97-38C6A19F78948B689345EE41D7119D76246C4D3E.part b/src/test/resources/totalcw/2018-10-15-00-00-00-vote-EFCBE720AB3A82B99F9E953CD5BF50F7EEFC7B97-38C6A19F78948B689345EE41D7119D76246C4D3E.part
new file mode 100644
index 0000000..c7ffb53
--- /dev/null
+++ b/src/test/resources/totalcw/2018-10-15-00-00-00-vote-EFCBE720AB3A82B99F9E953CD5BF50F7EEFC7B97-38C6A19F78948B689345EE41D7119D76246C4D3E.part
@@ -0,0 +1,239 @@
+@type network-status-vote-3 1.0
+network-status-version 3
+vote-status vote
+consensus-methods 25 26 27 28
+published 2018-10-14 23:50:00
+valid-after 2018-10-15 00:00:00
+fresh-until 2018-10-15 01:00:00
+valid-until 2018-10-15 03:00:00
+voting-delay 300 300
+recommended-relay-protocols Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=4 Microdesc=1-2 Relay=2
+recommended-client-protocols Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=4 Microdesc=1-2 Relay=2
+required-relay-protocols Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=3-4 Microdesc=1 Relay=1-2
+required-client-protocols Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=4 Microdesc=1-2 Relay=2
+known-flags Authority BadExit Exit Fast Guard HSDir Running Stable V2Dir Valid
+flag-thresholds stable-uptime=1224875 stable-mtbf=2831347 fast-speed=96000 guard-wfu=98.000% guard-tk=691200 guard-bw-inc-exits=9950000 guard-bw-exc-exits=8290000 enough-mtbf=1 ignoring-advertised-bws=1
+params CircuitPriorityHalflifeMsec=30000 DoSCircuitCreationEnabled=1 DoSConnectionEnabled=1 DoSConnectionMaxConcurrentCount=50 DoSRefuseSingleHopClientRendezvous=1 NumDirectoryGuards=3 NumEntryGuards=1 NumNTorsPerTAP=100 Support022HiddenServices=0 UseNTorHandshake=1 UseOptimisticData=1 bwauthpid=1 cbttestfreq=10 hs_service_max_rdv_failures=1 hsdir_spread_store=4 pb_disablepct=0 usecreatefast=0
+dir-source Faravahar EFCBE720AB3A82B99F9E953CD5BF50F7EEFC7B97 154.35.175.225 154.35.175.225 80 443
+contact 0x0B47D56D Sina Rabbani (inf0) <sina redteam net>
+shared-rand-participate
+shared-rand-commit 1 sha3-256 EFCBE720AB3A82B99F9E953CD5BF50F7EEFC7B97 AAAAAFvD2IDD8w9Bf35KfCrPuE49LIm5bKHISapdb3PoYLGv5ZOo6w==
+shared-rand-previous-value 9 Vd2znClwwth89jp91diG/Bs1AH+0ExSgRFmyVOMJwwE=
+shared-rand-current-value 9 oiXRUZGkT26O9aQmu/A52utoBF3gp27h0TvJ4gkDHkw=
+dir-key-certificate-version 3
+fingerprint EFCBE720AB3A82B99F9E953CD5BF50F7EEFC7B97
+dir-key-published 2018-06-30 16:50:42
+dir-key-expires 2019-06-30 16:50:42
+dir-identity-key
+-----BEGIN RSA PUBLIC KEY-----
+MIIBigKCAYEAwBmqdD+G0q3smN5OBFHCcK5pQH5G1GIpFJ1JxCVEp92tTK4ZHnot
+9RzMfag6zQFqwLaJ+yEb1DOjTdTMfcUTsj5f3GUqPB+U7shSMAvvAAM+Bx/4m1AU
+u6sk4XmPB1bCBfcRl4zhnY6XFIbj0ktuBDblcxHz3lDgHFpBoci9sF59mM14MZ09
+EdwgeckcU5oeq6ApuSlUVaOT8xsKV/yeK4SKaFfDclwPAJuitQ5CpqctP7ExmlrY
+sboTDtz7/Xa6OccaGDEUf7TRlipvUX6rvlmvHm3qjdixVfExpa8E5QG79GZTL82p
+1zBd3iqc6QEnRDTiW9cMUeQt4EvrwOUVVYPWo3hp1C/iiNzWraDays2xuhaSB0gj
+fPatu2CFW5XB2vd9IvIiWeklSFqnF8DL38jDL7DbFiETJreGsDMR03yHWVd0MbPz
+OrvAxG4tJn+JtnwhzlbRjnfk53jOTbiM0vMV8h/ztapCiJeT/6i7nVQ1xL2boeYw
+5RDUlwZaQiaXAgMBAAE=
+-----END RSA PUBLIC KEY-----
+dir-signing-key
+-----BEGIN RSA PUBLIC KEY-----
+MIIBCgKCAQEA5KK/zS8zPPinA7QGbcPEPH90hoagF9EmvvgYjQ8m2L2g15/3WrdQ
+J8Ue0n0JaOb2crZEJ+d1IwbvX9mFpFx4xNsGA3CPg1/RAHwvmB7HctGOO39Y+I4h
+KLyV4AWVPXb7uvWr8Stec9sW6QLwkz2bhW61DvBlCapBzQPPqm2R+dNCUXE6ATQv
+se8jzggu1YHKk5GSLrXUvuWKbZFBb5WKaZjRXAXt3I9jSS61SG6rxJmM7uujfrkF
+UOmb5T83oWCU1zgjyz5bs0j39A7K+FxQPlMUYUe8eyo0dNu6bwSwnm0C6JGmEZXn
+ee+KeQd6Kai8++uOiPWxfqIpSD8XkF0PkwIDAQAB
+-----END RSA PUBLIC KEY-----
+dir-key-crosscert
+-----BEGIN ID SIGNATURE-----
+gVMfY1HWevSFyr5COCTcd3Y7MdSF1WnaSNUQ1YjGrM1TC4leTRAuJ1ds1uQ/jt4w
+0vbM+1X0PRuOeb7o3+Cdn2DAgjeZE5R2BCk/qowXwxHpGwCjsjkCAhHWoiXtNprj
+hUveHhMgESRK5e7l/bXC/EIFnwvmw1caQZdfwMsxzJMU8is3XJGZIEtHgAvk5AzV
+SUL+CamS/S22FdHKzvsxtLM54lWu2IQZh3QYKQnST3kdDg2fVO8eDSn5iROS58oU
+FRB8duf4knv2PGPaCB9SVfM4XouXePZZkC73VEvqnjQSxjYK3yP/msL/bbqwIgu9
+6DE1Rfqw3bfT3/yObotAYg==
+-----END ID SIGNATURE-----
+dir-key-certification
+-----BEGIN SIGNATURE-----
+ZfZ6bRHneOwthgn3/yKeLTixlaj/xVBEtFGrB5sISPAOS3XddBPMR1w2eGMZ5Dlm
+DT6Gd+C4jTOt3KjMo0NiJVpWJBNqb9sBUR0Qkc23urjgvWvy8e9AmaIKFuTrtNCX
+4qHFs3ZDElNwyIQEhLsLTtbKd1/EO0rDUlhKOT1U4rJAc+Vc51FqlFPHON8d34GK
+Qsmj+njIsMV06K1XO9TF4ERtbglzFAw+QjrzEsUSa3EIzmeYAxekiWI/KfG38WuL
+zW+11z0aJbGRtbfQbTbOuq02R3VlpkyxKDwOn0lOCXdUUpN2BK5+noAxyZeESjuN
++1rzNl5QdHgOddQA8rwUeeLYpCublWiDpm231K4q/CrT0+PJTjApfyGY5OK9HSUB
+pF/wudq+aeGT94w6A27YAQufzRYZssJZx/XOD+ptY22ddJMF8d5vvL4ZqAkd6HI6
+V55pW4NgCu6pAliAarFo3y0SUXQaiDSOzJiB9Sm6NyPpVvmVywfUvD7380u6YHf/
+-----END SIGNATURE-----
+r seele AAoQ1DAR6kkoo19hBAX5K0QztNw xlbC5aW8ovDVh2t6VcKF/phheSg 2018-10-14 21:41:22 67.174.243.193 9001 0
+s 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=60 Measured=15
+p reject 1-65535
+id ed25519 ZtzhbIWHJpGQG+5N7hbRTtenyzq2RNJrx0QegtoY+bY
+m 25,26,27,28 sha256=4l7u4Oy1sCG/08MtsHimtWtaC1ydC/GOtCqRD/5ewgs
+r PutoElQueLee293884 AAwffNL+oHO5EdyUoWAOwvEX3ws Ay3cnaaHjnolSRe3ZjKcGlY17Q8 2018-10-14 08:06:47 174.127.217.73 55554 0
+s Fast Guard Running Stable V2Dir Valid
+v Tor 0.3.3.9
+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=4950 Measured=5550
+p reject 1-65535
+id ed25519 /58lPWzxxQfwoxed8I9l+D3+hTdOQ6RpgVgM9FCxil4
+m 25,26,27,28 sha256=0/b37HV9enGTzbwrxxg/0R5PfwRtRosXgtU5+vi/gBk
+r CalyxInstitute14 ABG9JIWtRdmE7EFZyI/AZuXjMA4 +8xNQyAVPkKgtLH0AISVZFNuAq0 2018-10-14 11:10:20 162.247.74.201 443 80
+s Exit Fast Guard HSDir Running Stable V2Dir Valid
+v Tor 0.3.3.7
+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=10000 Measured=12900
+p accept 20-23,43,53,79-81,88,110,143,194,220,389,443,464,531,543-544,554,563,636,706,749,873,902-904,981,989-995,1194,1220,1293,1500,1533,1677,1723,1755,1863,2082-2083,2086-2087,2095-2096,2102-2104,3128,3389,3690,4321,4643,5050,5190,5222-5223,5228,5900,6660-6669,6679,6697,8000,8008,8074,8080,8087-8088,8332-8333,8443,8888,9418,9999-10000,11371,12350,19294,19638,23456,33033,64738
+id ed25519 /AcSvVFxaIBxaB5I/7mwdVbMdP6JjDsEPVLU6Hj22a0
+m 25,26,27,28 sha256=7nBT4mYr4H5Jj71Qq7Nan7R7KqWPTRG89Oq1/5m4c1M
+r Neldoreth ABUk3UA9cp8I9+XXeBPvEnVs+o0 nms8ZM18C/K5XzLmgO5fHchjhFc 2018-10-14 19:09:56 185.13.39.197 443 80
+s Fast Guard 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=5242 Measured=8480
+p reject 1-65535
+id ed25519 eZ49J/mRCMtMbD2GDZsjZm/gqqG9z5S6M5GykZmd2ro
+m 25,26,27,28 sha256=IxCWEdRM6Hqk1fiYx+DK9ufUPI49SE6Z4C8onbsBVXo
+r UbuntuCore246 ACenhGJF+i26Aj46wfqAaI8dc7s EmwRg8iMnKJc8GEusZxhsVf9PJI 2018-10-14 23:13:35 212.199.61.38 43511 0
+s Fast V2Dir Valid
+v Tor 0.3.3.10
+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=121 Measured=120
+p reject 1-65535
+id ed25519 crWebog3RcKMV49zyu6pF5A/MxQM89x2cKNRK1wbTjM
+m 25,26,27,28 sha256=98nmfhxVBZqk7VUfyXQWpJmLAfWloZtMXu5H9FVt+p8
+r rotor25 ADQsDhVdRULlU5F4iy13nxRXjes m/3hkTP+ETmoYWZ3JrniJAeRHho 2018-10-14 17:19:08 188.24.22.193 9001 9030
+s Fast Running 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=3987 Measured=5580
+p reject 1-65535
+id ed25519 8ybCWdul+E3HdzEb1YR3Fbp6EIwnGGPsUhsSh7FUnfs
+m 25,26,27,28 sha256=ZeMCL1T4SogPYK0iyuzYZoyFx+mp9/Ng8vGmE8wI9rU
+r torbogen AEHgFQsKMHUGwoY+/J8rfjpSOzY DXa3G+iPbGQo4AK2iazVY6R4eKs 2018-10-14 20:19:33 178.142.72.49 9001 9030
+s Fast Running V2Dir Valid
+v Tor 0.3.3.9
+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=1275 Measured=1430
+p reject 1-65535
+id ed25519 NzIv9KWavK4f+6426ctrr9UnsFl/Yt8ixEAP6OO/kVo
+m 25,26,27,28 sha256=lFXLHMP6Map0qD298F+eeybL4pqtXDRG7a7r4R7knlw
+r nicolass67atoll AES/YhfxWxj3ZvK1O85bPg4BV+k iK+QhopNtEipMSL+EeI6b/DitVc 2018-10-14 15:48:15 163.172.10.89 9001 0
+s Fast Running Stable V2Dir Valid
+v Tor 0.2.9.16
+pr Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1-2 Link=1-4 LinkAuth=1 Microdesc=1-2 Relay=1-2
+w Bandwidth=1048 Measured=773
+p reject 1-65535
+id ed25519 ++ezzEs6r+0m0YDwFAjwpIIbNKtzMbKB13osAAoGQ/c
+m 25,26,27,28 sha256=kGlToMt+rD0tL3N+5Plqj8Nav1FVQMiSYpz0adtzs0I
+r zzzzzzzzzzzzzzzzzzz AEVz/pNLpV0H2ucjF3k69OQbdbY 1FUGYNQtQo1MgV4jRP2XJapWemI 2018-10-14 23:43:10 77.12.174.141 9002 9031
+s Fast Running V2Dir Valid
+v Tor 0.3.2.10
+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=565 Measured=189
+p reject 1-65535
+id ed25519 QnM3RTCh53wbKiC6N6IsCQHs3pj9J547xUNtrk5FnYE
+m 25,26,27,28 sha256=+1jqHQZNEebT5DFJHZIPE35at9TzFCB5hzqDWAxrXGk
+r helga AFnZKULbO4TlLrTYfp97GVz00AU ngp++P8hEV+Pj/j9OvvDCyuDqKA 2018-10-14 17:09:42 88.99.216.194 9001 9030
+s Fast 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=409 Measured=254
+p reject 1-65535
+id ed25519 M1nVVuHebCChHayS1hsajAkzpe4c8bEFKP499V3yBG4
+m 25,26,27,28 sha256=//iWXvWzIkvqFqwTf367uZJ2UoNwcrCrLcOs7DY5xvE
+r Torpi AHJ/OiwdDxcxqRJnxBFQecFrILQ bLi/i6JuuPmoWm1aGd73dy2tYlA 2018-10-14 15:51:48 110.146.4.151 9001 9030
+s Running Stable V2Dir Valid
+v Tor 0.2.4.29
+pr Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=1-4 LinkAuth=1 Microdesc=1 Relay=1-2
+w Bandwidth=92 Measured=31
+p reject 1-65535
+id ed25519 none
+m 25,26,27,28 sha256=TiQfeDGlZq6VrCEKFDCA0uvS6hiv8CVMdkLyRxuRZpU
+r VeespRU2 AHTsqCvVi4uxkJycTyN/2XebI/w r3AsIyXKvSFzC+5eDuiUgPTmG9g 2018-10-14 09:25:26 185.22.172.237 443 80
+s Fast Guard HSDir Running Stable V2Dir Valid
+v Tor 0.3.3.7
+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=10000 Measured=26700
+p reject 1-65535
+id ed25519 obR35oXyInFbtgitDsbasslq2SNFSTZeI1+2bJfK6HE
+m 25,26,27,28 sha256=+tNKyFkcOSA/CufXMtSfprtve7qkoDx4yjGG/XdH6Ec
+r Quintex13 AHe8unJE2z5qXtJ0boYXAGZoSIc GwoBS5ddT7ktxwqHjHYNc2u53xU 2018-10-14 07:38:44 199.249.223.62 443 80
+s Exit Fast 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=9426 Measured=5000
+p accept 20-23,43,53,79-81,88,110,143,194,220,389,443,464-465,531,543-544,554,563,587,636,706,749,873,902-904,981,989-995,1194,1220,1293,1500,1533,1677,1723,1755,1863,2082-2083,2086-2087,2095-2096,2102-2104,3128,3389,3690,4321,4643,5050,5190,5222-5223,5228,5900,6660-6669,6679,6697,8000,8008,8074,8080,8082,8087-8088,8232-8233,8332-8333,8443,8888,9418,9999-10000,11371,19294,19638,50002,64738
+id ed25519 cHUct3VAkb+T4KQQQg9fLuH5feoGyjxang+Jihs0E80
+m 25,26,27,28 sha256=/JQIKi/L0aSZ8uMKc0DsHBeH2OmsvAj9GbXq8i8QQcE
+r UbuntuCore246 AH4Yastcf3fGnzddzt9ZT/1r9pk 9kJql4jbylNMYXhvn4OasP55fck 2018-10-14 11:03:40 77.146.180.194 40523 0
+s V2Dir Valid
+v Tor 0.3.3.10
+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=382 Measured=19
+p reject 1-65535
+id ed25519 rSPYL+kdnVmyJ9/Ni96SNABxuvE4DDLwO9l9tqeicoA
+m 25,26,27,28 sha256=hGcbcAmK7x/tNRe7iBBqNlj6sZByhmhTSwWw/wYZo3s
+r torrelay04 AH/ZCOnPz1nmT7pCt1cdLPQBvF0 n5XUymNehFnO8hTftwd4NIozrjQ 2018-10-14 18:52:54 159.69.153.73 9000 0
+a [2a01:4f8:1c1c:5cec::1]:9000
+s Fast Running Stable 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=8030 Measured=9010
+p reject 1-65535
+id ed25519 OJfT1k1R4UB3eNZ7+Mx9MCh9a5RBXqCcqtDfqQw4UvA
+m 25,26,27 sha256=R60ONtNwXwpVOajWfWlH4yQ7a6rBYwgLJ87p5wH55fk
+m 28 sha256=8oP/xai6UYcjJY5gx9fgrLTYY66vgdAr4y2F+R7tqUQ
+r bigamy AH/cDMglli4ShKYaaMk4pmr75XA dMrr7wRTfKoVfCRHLuR0IZFSWsI 2018-10-14 13:28:57 185.24.218.171 9001 8080
+s Exit Fast 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=10000 Measured=30400
+p accept 20-21,23,43,53,79-81,88,110,143,194,220,389,443,464-465,531,543-544,554,563,587,636,706,749,853,873,902-904,981,989-995,1220,1293,1500,1533,1677,1723,1755,1863,2082-2087,2095-2096,2102-2104,2374-2382,3128,3389,3690,4321,4643,5050,5190,5222-5223,5228,5900,6660-6669,6679,6697,8000-8100,8232-8233,8332-8333,8443,8888,9418,9999-10000,11371,19294,19638,50002,64738
+id ed25519 fTOvB48qkzbEyLpBemkuyBv9UieAUeM8RNfCypusrs0
+m 25,26,27,28 sha256=GpLj/6GejSGtvDxUAUrZgarLCVjbcZVDduWCqvShOBk
+r zech1989 AI57cMO0p1ILW+q4Bnq83I5j8f0 boK7UYxCaZy4lpe8irfYPFsX6SY 2018-10-14 21:18:08 185.243.53.99 9001 9030
+s 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=9726 Measured=11300
+p reject 1-65535
+id ed25519 wPhoSjgH8xrZ/K2wKhYKd2IR6iQ2/pO4V9rIObVIZ30
+m 25,26,27,28 sha256=hx94DElvCTLaJLuCbKr5rShGxcpKpz8f5eZdYhXwfEQ
+r paris AJf70aisEQPfmPHoXdUsUPAdOtY 9x4Jiv45IDG4EDSSXfOd+Ss9qtc 2018-10-14 22:06:20 178.19.111.147 9001 8000
+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=10000 Measured=40700
+p accept 20-21,23,43,53,79-81,88,110,143,194,220,389,443,464-465,531,543-544,554,563,587,636,706,749,853,873,902-904,981,989-995,1220,1293,1500,1533,1677,1723,1755,1863,2082-2087,2095-2096,2102-2104,2374-2382,3128,3389,3690,4321,4643,5050,5190,5222-5223,5228,5900,6660-6669,6679,6697,8000-8100,8232-8233,8332-8333,8443,8888,9418,9999-10000,11371,19294,19638,50002,64738
+id ed25519 s49ps0kX/BuncEzm6dG6ZmLs7DCanj/WcXlPVt0D7Tw
+m 25,26,27,28 sha256=L9vWM3tYYI2RLlnofu1m9nMTckLVSKMXftVTDUwidhw
+r jactr AJhR35M3VLAN3odvzkCIzhtJQME RLckbaDnNUH4qGCkOmDo20UwE28 2018-10-14 23:26:36 84.40.112.70 9001 9030
+s Running Stable V2Dir Valid
+v Tor 0.2.9.15
+pr Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1-2 Link=1-4 LinkAuth=1 Microdesc=1-2 Relay=1-2
+w Bandwidth=131 Measured=77
+p reject 1-65535
+id ed25519 +Jc2Ppp+/hmdtaE8T2uxkZIhOD5/kCEfz8gyDCMiDpg
+m 25,26,27,28 sha256=tD+2RMOICoOQRFeZH6D4Kx8mRN4JzhfrtcQs8q78hPA
+r IsThisAGoodIdea AJ2M8WzPcSMatc5VyCoDRG2j+Us Gce3qKSpkK8w2D+9k75V7vNdWzI 2018-10-14 16:51:45 220.233.27.93 9001 0
+s Running Valid
+v Tor 0.3.3.9
+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=80 Measured=6
+p reject 1-65535
+id ed25519 peXjh3W6mWzg9iZALqNEDyP3ONQO7Vp9uSzqSszVHOA
+m 25,26,27,28 sha256=1jmLpMLTUMJr2IoHyDpGCrc/ZuBakhVUWivZ7NKwAz4
+directory-footer
+directory-signature EFCBE720AB3A82B99F9E953CD5BF50F7EEFC7B97 517095062288D1B5C7BD6517A677C586D996818B
+-----BEGIN SIGNATURE-----
+RdWrXeRxh4lZB1oTsOTy+AcYFruKg6Xzfl/D/srqmSfihcLoBIwWXePe2aLDycTj
+fcLPRt3HUnHzII61reqsVKzDXGAybMdYpPE9kygA60INsyAYFAdigMEDwY0C2qIZ
+MMJrSyORovHh4YOQHoesZPDgCUuYkuAjheKwwxdJ4O6mcYJyusm9OWVy8Iej4lKW
+ySFXC6sQt3L81MVAE24eBA1eTmUUf3fWpK/UbD0GjHYD8J+qgxm8hDwrYwVUQKmU
+u3RuRcuPYfC0tPgKLNB8sHP2o292q026M8RbcE0GnvPBQS6r2uIDfBfQLETwg0do
+h7HVCq11GZIdYe4eCZu8rQ==
+-----END SIGNATURE-----
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits