Skip to content
  1. Jun 19, 2023
  2. May 31, 2023
  3. Jan 26, 2023
  4. Apr 23, 2022
  5. Mar 29, 2022
  6. Dec 31, 2021
  7. Nov 18, 2021
    • Damian Johnson's avatar
      Skip internal circuits in exit_used.py example · 57364fae
      Damian Johnson authored
      pragma31 made the good point that exit_used.py confusingly presents the
      internal 1-hop circuits for fetching descriptors. Filtering those out.
      
        https://github.com/torproject/stem/pull/111
      57364fae
    • Damian Johnson's avatar
      Make exit_used.py compatible with asyncio · 7e9ea4db
      Damian Johnson authored
      Honestly this is probably somewhat a step backward because if I return to Stem
      I plan to substantially revert the asyncio migration, but for now simply fixing
      the script. With the current codebase it fails with...
      
        % python exit_used.py
        Tracking requests for tor exits. Press 'enter' to end.
      
        stem/stem/control.py:4004: RuntimeWarning: coroutine 'Controller.get_circuit' was never awaited
          log.warn('Event listener raised an uncaught exception (%s): %s' % (exc, event))
      7e9ea4db
  8. Nov 09, 2021
    • NilacTheGrim's avatar
      Fixup for Python 3.10 · 36bcb170
      NilacTheGrim authored
      Closes issue #109.  Long story short: a few names from collection are
      now moved to collection.abc exclusively starting in Python 3.10. The
      only name this app uses from there that was moved is
      `collections.Iterable`.  Python versions starting from 3.3 support both
      `collections.Iterable` and `collections.abc.Iterable` as the way to refer to
      this class, which Python 3.10 being the first one to drop
      `collections.Iterable`.  So.. we just work around this API quirk
      and always refer ot it as `collections.abc.Iterable`.
      36bcb170
  9. Oct 27, 2021
  10. Oct 22, 2021
  11. Jun 12, 2021
  12. May 05, 2021
  13. Feb 10, 2021
    • Damian Johnson's avatar
      Adjust extended v3 HS address validation · 63a47605
      Damian Johnson authored
      Mostly minor stylistic adjustments. The only functional bit is correcting a
      unit test failure...
      
      	======================================================================
      	FAIL: test_identity_key_from_address
      	----------------------------------------------------------------------
      	ValueError: '55555555555555555555555555555555555555555555555555555555.onion' isn't a valid hidden service v3 address
      
      	During handling of the above exception, another exception occurred:
      
      	Traceback (most recent call last):
        	File "/home/atagar/Desktop/stem/test/unit/descriptor/hidden_service_v3.py", line 220, in test_identity_key_from_address
          	self.assertRaisesWith(ValueError, 'Bad checksum (expected def7 but was 842e)', HiddenServiceDescriptorV3.identity_key_from_address, '5' * 56)
        	File "/home/atagar/Desktop/stem/stem/util/test_tools.py", line 249, in assertRaisesWith
          	return self.assertRaisesRegexp(exc_type, '^%s$' % re.escape(exc_msg), *args, **kwargs)
      	AssertionError: "^Bad\ checksum\ \(expected\ def7\ but\ was\ 842e\)$" does not match "'55555555555555555555555555555555555555555555555555555555.onion' isn't a valid hidden service v3 address"
      
      ----------------------------------------------------------------------
      63a47605
  14. Feb 09, 2021
  15. Dec 08, 2020
  16. Nov 08, 2020
  17. Nov 06, 2020
  18. Nov 01, 2020
    • Damian Johnson's avatar
      Cache parsed descriptors within Query · 6a7ebd9f
      Damian Johnson authored
      Our Query class cached the bytes we download rather than parsed descriptors.
      This could be advantagous if a user downloads descriptors without caring
      about the results (unlikely), but otherwise it's all downside...
      
        * Slower: The Query class downloads asynchronously so we can parallelize.
          By parsing when the results are requested we serialize that part of the
          runtime.
      
        * Memory: Caching bytes reduced the upfront memory usage, but multiplies
          it upon retrieving the results because we create fresh Descriptor
          objects upon each invocation.
      
        * Duplication: Each invocation of our run method re-parsed the descriptors.
          For larger documents like the consensus this duplicates a lot of work.
      
        * Complexity: Caching bytes needlessly complicated the run method.
      6a7ebd9f
  19. Oct 31, 2020
    • Damian Johnson's avatar
      Make Query.start() synchronous · 09dcc95f
      Damian Johnson authored
      This class method initializes an asynchronous process. There's no benefit in
      this method itself being asynchronous. This only was to ensure there's a loop
      available, but our Synchronous parent provides that.
      09dcc95f
    • Damian Johnson's avatar
      Test that the Query class' 'start' argument works · bb0d68be
      Damian Johnson authored
      Reading our Query class I became worried that our 'start' argument fails to get
      honored because the start() method is asynchronous (so its invocation returns a
      coroutine rather than running it).
      
      I was wrong. It works because as a Synchronous subclass our metaprogramming
      converts the call. That said, this is none the less a good thing to check.
      bb0d68be
  20. Oct 30, 2020
  21. Oct 28, 2020
    • Damian Johnson's avatar
      Permit float in label functions · 84602486
      Damian Johnson authored
      Oops. Actually, our last release allowed floats (and our 'decimal' argument
      doesn't make terribly much sense otherwise). We *did* have a bug in that
      remainder values that are less than 1 crashed us (corrected by commit c90e87ca),
      but we shouldn't have addressed that by integer normalization.
      
      Regression caught thanks to Nyx's tests...
      
        ======================================================================
        FAIL: test_draw_line (panel.connection.TestConnectionPanel)
        ----------------------------------------------------------------------
        Traceback (most recent call last):
          File "/home/atagar/Desktop/nyx/test/__init__.py", line 59, in wrapped
            return func(self, *args, **kwargs)
          File "/usr/lib/python3.8/unittest/mock.py", line 1325, in patched
            return func(*newargs, **newkeywargs)
          File "/home/atagar/Desktop/nyx/test/panel/connection.py", line 228, in test_draw_line
            self.assertEqual(expected, rendered.content)
        AssertionError: ' 75.119.206.243:22 (de)      -->  82.121.9.9:3531              15.4s (INBOUND)' != ' 75.119.206.243:22 (de)      -->  82.121.9.9:3531              14.9s (INBOUND)'
        -  75.119.206.243:22 (de)      -->  82.121.9.9:3531              15.4s (INBOUND)
        ?                                                                 ^ ^
        +  75.119.206.243:22 (de)      -->  82.121.9.9:3531              14.9s (INBOUND)
        ?                                                                 ^ ^
      84602486
  22. Oct 24, 2020
    • Damian Johnson's avatar
      Error when reading CollecTor file twice · 78ad7080
      Damian Johnson authored
      When a CollecTor file is already within our cache we validate its hash against
      CollecTor's index. However, files we wrote to disk are decompressed by default
      so the hash naturally mismatches.
      
        https://github.com/torproject/stem/issues/76
      
      Reproduced this issue with the following script...
      
        import stem.descriptor.collector
      
        collector = stem.descriptor.collector.get_instance()
        desc_file = collector.files(descriptor_type = 'server-descriptor')[0]  # pick any arbitrary file
      
        print('Number of descriptors (first read): %s' % len(list(desc_file.read(directory = '/tmp/collector_cache'))))
        print('Number of descriptors (second read): %s' % len(list(desc_file.read(directory = '/tmp/collector_cache'))))
      
      Before...
      
        % python demo.py
        Number of descriptors (first read): 3112
        Traceback (most recent call last):
          File "scrap.py", line 8, in <module>
            print('Number of descriptors (second read): %s' % len(list(desc_file.read(directory = '/tmp/collector_cache'))))
          File "/home/atagar/Desktop/stem/stem/descriptor/collector.py", line 273, in read
            path = self.download(directory, True, timeout, retries)
          File "/home/atagar/Desktop/stem/stem/descriptor/collector.py", line 335, in download
            raise OSError("%s already exists but mismatches CollecTor's checksum (expected: %s, actual: %s)" % (path, expected_hash, actual_hash))
        OSError: /tmp/collector_cache/server-descriptors-2005-12.tar already exists but mismatches CollecTor's checksum (expected: bf700d8b6143e310219b2ce2810abd82f94bc295c7f08e9f1a88989562e33b2f, actual: 32a5ea8fd761e5967fbb8d399742f0da7cbb1c79c1539f2e58cad2e668462652)
      
      After...
      
        % python demo.py
        Number of descriptors (first read): 3112
        Number of descriptors (second read): 3112
      
      We can either solve this by dropping the hash check or caching compressed
      archives. Initially I leaned toward the former to expedite cache reads, but on
      reflection the later is conceptually simpler. Essentially, is this a network
      cache or a read cache? A network cache is safer in that if CollecTor replaces a
      file (but keeps the same filename) this will catch the change.
      78ad7080
    • Damian Johnson's avatar
      Update website build instructions · cc7b22c8
      Damian Johnson authored
      Building now requires the typehint plugin. Noting that and the pip command to
      install it and sphinx.
      cc7b22c8
  23. Oct 22, 2020
    • Damian Johnson's avatar
      Test retrieving HS client name · 831dd051
      Damian Johnson authored
      The issue that prevented us from testing this was fixed...
      
        19:28 <+atagar> dgoulet: What is the status of
          tpo/core/tor#40089 ? The last
          comment discusses another review, but then the 'Needs Review' tag was
          removed.
        19:29 <+dgoulet> atagar: so that has been merged upstream it appears
          and waiting for backport down to 043
        19:31 <+atagar> Ahh, great - thanks. Per chance do you know what tor
          version has the fix? If so then I can check for it in our tests
          (https://gitweb.torproject.org/stem.git/tree/test/integ/control/controller.py#n1650).
        19:34 <+dgoulet> atagar: not sure exactly which one but I think 0.4.4.5 +
        19:36 <+atagar> Thanks, I'll conditional the assertion on that version.
          If it makes any test runs sad just let me know.
        19:36 <+dgoulet> ack thanks
      831dd051
  24. Oct 17, 2020
    • Damian Johnson's avatar
      Static check fixes · c6952fee
      Damian Johnson authored
      Upgrading to pycodestyle 2.6.0 produced a few new warnings...
      
        STATIC CHECKS
        * /home/atagar/Desktop/stem/stem/descriptor/certificate.py
          line 257  - undefined name 'cryptography'            | def __init__(self, cert_type: Optional['stem.client.datatype.CertType'] = None, expiration: Optional[datetime.datetime] = None, key_type: Optional[int] = None, key: Optional[bytes] = None, extensions: Optional[Sequence['stem.descriptor.certificate.Ed25519Extension']] = None, signature: Optional[bytes] = None, signing_key: Optional['cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey'] = None) -> None:  # type: ignore
      
        * /home/atagar/Desktop/stem/stem/descriptor/hidden_service.py
          line 288  - E741 ambiguous variable name 'l'         | link_specifiers = link_count + b''.join([l.pack() for l in self.link_specifiers])
      
        * /home/atagar/Desktop/stem/stem/interpreter/commands.py
          line 272  - E741 ambiguous variable name 'l'         | lines += [format(l, *STANDARD_OUTPUT) for l in str(desc).splitlines()]
      
        * /home/atagar/Desktop/stem/stem/util/__init__.py
          line 84   - undefined name 'cryptography'            | def _pubkey_bytes(key: Union['cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey', 'cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey', 'cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey', 'cryptography.hazmat.primitives.asymmetric.x25519.X25519PublicKey']) -> bytes:  # type: ignore
      
        * /home/atagar/Desktop/stem/test/unit/response/events.py
          line 540  - 'stem.control.Controller' imported but unused | from stem.control import Controller, EventType
      
        * stem/client/__init__.py
          line 322  - unused 'type: ignore' comment
      
        * stem/control.py
          line 2493 - Unpacking a string is disallowed  [misc]
          line 2511 - Unpacking a string is disallowed  [misc]
          line 2516 - Unpacking a string is disallowed  [misc]
      
        * stem/directory.py
          line 270  - Unpacking a string is disallowed  [misc]
          line 271  - Unpacking a string is disallowed  [misc]
          line 436  - Unpacking a string is disallowed  [misc]
      c6952fee
    • Damian Johnson's avatar
      Avoid 'never awaited' test warnings · d018d6e2
      Damian Johnson authored
      When running our tests with Python 3.8.5 I'm getting the following warnings...
      
      	/home/atagar/Desktop/stem/test/unit/response/events.py:553: RuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was never awaited
      	  controller.authenticate()
      	RuntimeWarning: Enable tracemalloc to get the object allocation traceback
      
      Our mock spec doesn't provide anything here, so simply omitting it to silence
      these.
      d018d6e2
    • Damian Johnson's avatar
      Normalize label input arguments · c90e87ca
      Damian Johnson authored
      Functions like size_label() and time_label() are documented as taking an int
      argument, but getting a float shouldn't make them choke. Especially in such an
      unhelpful way...
      
        ======================================================================
        ERROR: test_time_label
        Checks the time_label() function.
        ----------------------------------------------------------------------
        Traceback (most recent call last):
          File "/home/atagar/Desktop/stem/test/unit/util/str_tools.py", line 99, in test_time_label
            self.assertEqual('0s', str_tools.time_label(0.1))
          File "/home/atagar/Desktop/stem/stem/util/str_tools.py", line 366, in time_label
            return _get_label(TIME_UNITS, seconds, decimal, is_long)
          File "/home/atagar/Desktop/stem/stem/util/str_tools.py", line 595, in _get_label
            raise ValueError('BUG: %s should always be divisible by a unit (%s)' % (count, str(units)))
        ValueError: BUG: 0.1 should always be divisible by a unit (((86400.0, 'd', ' day'), (3600.0, 'h', ' hour'), (60.0, 'm', ' minute'), (1.0, 's', ' second')))
      c90e87ca
  25. Oct 15, 2020
    • Damian Johnson's avatar
      GETINFO ip-to-country error · 99396db3
      Damian Johnson authored
      Oops, forgot to await one of our internal coroutine calls...
      
        stem/control.py:1236: RuntimeWarning: coroutine 'Controller.get_info' was never awaited
      99396db3
  26. Oct 02, 2020