| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 | # This network generates a random mix of tor versions each time it is run# You'll need at least 8 runs to cover all possibilitiesimport randomrng = random.SystemRandom()# We have to use the same tags for old and new versions, otherwise switching# between them at random does not workOLD_TOR="tor-stable"# By default, Authorities are not configured as exitsAuthority = Node(tag="a", authority=1, relay=1, torrc="authority.tmpl")OldAuthority = Node(tag="a", authority=1, relay=1, torrc="authority.tmpl",                    tor=OLD_TOR)NonExitRelay = Node(tag="r", relay=1, torrc="relay-non-exit.tmpl")OldNonExitRelay = Node(tag="r", relay=1, torrc="relay-non-exit.tmpl",                       tor=OLD_TOR)Client = Node(tag="c", client=1, torrc="client.tmpl")OldClient = Node(tag="c", client=1, torrc="client.tmpl", tor=OLD_TOR)HS = Node(tag="h", hs=1, torrc="hs.tmpl")OldHS = Node(tag="h", hs=1, torrc="hs.tmpl", tor=OLD_TOR)# Choose old or new Relay, Client, and HS at randomOldNewNonExitRelay = rng.choice([OldNonExitRelay, NonExitRelay])OldNewClient = rng.choice([OldClient, Client])OldNewHS = rng.choice([OldHS, HS])def version(node):  if node._env["tor"] == Authority._env["tor"]:    return "new"  elif node._env["tor"] == OldAuthority._env["tor"]:    return "old"  else:    return "unk"# Every time chutney takes an action, it will pick versions at random# It will likely choose different versions for each action# This could be confusing, so log a message each timeprint(("Chose 1 %s authority, 1 %s authority, %d %s non-exit relay, " +       "%d %s non-exit relay, 1 %s client and 1 %s hidden service")      % (version(Authority),         version(OldAuthority),         2 if OldNewNonExitRelay == NonExitRelay else 1,	 version(NonExitRelay),         2 if OldNewNonExitRelay == OldNonExitRelay else 1,	 version(OldNonExitRelay),	 version(OldNewClient),         version(OldNewHS)))# A hidden service needs 5 authorities/relays to ensure it can build HS# connections:# a minimum path length of 3, plus the client-nominated rendezvous point,# plus a seperate introduction pointNODES = Authority.getN(1) + OldAuthority.getN(1) + NonExitRelay.getN(1) + \        OldNonExitRelay.getN(1) + OldNewNonExitRelay.getN(1) + \        OldNewClient.getN(1) + OldNewHS.getN(1)ConfigureNodes(NODES)
 |