Saving and Loading a Tor Consensus¶
Reading and writing a Tor consensus to disk is similar to other descriptor types with one small difference.
Most descriptors are just about a single relay. Server descriptors and microdescriptors, for instance, can be concatenated together and dumped to a file because they’re each independent of each other.
The Tor consensus, however, is a larger document containing information about the Tor network in addition to a little data on each of the relays.
In Stem the overall document is a
NetworkStatusDocumentV3
, and the
information on individual relays are
RouterStatusEntryV3
instances.
Why does this matter? By default when you read a consensus Stem provides you
just the RouterStatusEntryV3
.
This is for performance reasons, and because usually that’s what developers
want. But for writing the conssensus to disk we’ll want the whole document
instead.
So how do we get it? Just tell Stem that’s what you want. The
DocumentHandler
tells Stem how to read the
consensus. For example, to write the consensus simply do the following…
from stem.descriptor import DocumentHandler
from stem.descriptor.remote import DescriptorDownloader
downloader = DescriptorDownloader()
consensus = downloader.get_consensus(document_handler = DocumentHandler.DOCUMENT).run()[0]
with open('/tmp/descriptor_dump', 'w') as descriptor_file:
descriptor_file.write(str(consensus))
Our consensus here is the current
NetworkStatusDocumentV3
. The
descriptor_dump file now looks like…
network-status-version 3
vote-status consensus
consensus-method 18
valid-after 2014-11-17 23:00:00
fresh-until 2014-11-18 00:00:00
valid-until 2014-11-18 02:00:00
voting-delay 300 300
... etc...
You can then read it back with parse_file()
…
from stem.descriptor import DocumentHandler, parse_file
consensus = next(parse_file(
'/tmp/descriptor_dump',
descriptor_type = 'network-status-consensus-3 1.0',
document_handler = DocumentHandler.DOCUMENT,
))
for fingerprint, relay in consensus.routers.items():
print("%s: %s" % (fingerprint, relay.nickname))