Repository: Bitmessage/PyBitmessage

Issue:
Error creating address
A print statement seems to create a division by 0 exception

```
Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Python27\lib\threading.py", line 810, in __bootstrap_inner
    self.run()
  File "C:\AdminRoot\TBM\PyBitmessage\src\class_addressGenerator.py", line 101,in run
    print 'Address generator calculated', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix, 'addresses at', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix / (time.time() - startTime), 'addresses per second before finding one with the correct ripe-prefix.'
ZeroDivisionError: float division by zero
```

Sidenote: the `dotimingattackmitigation` was set to false



Discussion:
For me this is a critical error, since the generatd address is never stored on the file, as the offending print statement is located before the code that saves the address.

The error seems to happen if the device is quick enough, that start and end time are on the same half second.


Resolving patch:
diff --git a/src/bitmessageqt/bitmessageui.py b/src/bitmessageqt/bitmessageui.py
--- a/src/bitmessageqt/bitmessageui.py
+++ b/src/bitmessageqt/bitmessageui.py
@@ -2,7 +2,7 @@
 
 # Form implementation generated from reading ui file 'bitmessageui.ui'
 #
-# Created: Fri Aug 01 15:30:14 2014
+# Created: Mon Jan 05 16:21:20 2015
 #      by: PyQt4 UI code generator 4.10.3
 #
 # WARNING! All changes made in this file will be lost!
@@ -625,11 +625,11 @@ def retranslateUi(self, MainWindow):
         item.setText(_translate("MainWindow", "Stream #", None))
         item = self.tableWidgetConnectionCount.horizontalHeaderItem(1)
         item.setText(_translate("MainWindow", "Connections", None))
-        self.labelTotalConnections.setText(_translate("MainWindow", "Total connections: 0", None))
-        self.labelStartupTime.setText(_translate("MainWindow", "Since startup at asdf:", None))
-        self.labelMessageCount.setText(_translate("MainWindow", "Processed 0 person-to-person message.", None))
-        self.labelPubkeyCount.setText(_translate("MainWindow", "Processed 0 public key.", None))
-        self.labelBroadcastCount.setText(_translate("MainWindow", "Processed 0 broadcast.", None))
+        self.labelTotalConnections.setText(_translate("MainWindow", "Total connections:", None))
+        self.labelStartupTime.setText(_translate("MainWindow", "Since startup:", None))
+        self.labelMessageCount.setText(_translate("MainWindow", "Processed 0 person-to-person messages.", None))
+        self.labelPubkeyCount.setText(_translate("MainWindow", "Processed 0 public keys.", None))
+        self.labelBroadcastCount.setText(_translate("MainWindow", "Processed 0 broadcasts.", None))
         self.labelLookupsPerSecond.setText(_translate("MainWindow", "Inventory lookups per second: 0", None))
         self.labelBytesRecvCount.setText(_translate("MainWindow", "Down: 0 KB/s", None))
         self.labelBytesSentCount.setText(_translate("MainWindow", "Up: 0 KB/s", None))
diff --git a/src/class_addressGenerator.py b/src/class_addressGenerator.py
--- a/src/class_addressGenerator.py
+++ b/src/class_addressGenerator.py
@@ -7,6 +7,7 @@
 import hashlib
 import highlevelcrypto
 from addresses import *
+from debug import logger
 from pyelliptic import arithmetic
 import tr
 
@@ -85,20 +86,19 @@ def run(self):
                     potentialPrivEncryptionKey = OpenSSL.rand(32)
                     potentialPubEncryptionKey = highlevelcrypto.pointMult(
                         potentialPrivEncryptionKey)
-                    # print 'potentialPubSigningKey', potentialPubSigningKey.encode('hex')
-                    # print 'potentialPubEncryptionKey',
-                    # potentialPubEncryptionKey.encode('hex')
                     ripe = hashlib.new('ripemd160')
                     sha = hashlib.new('sha512')
                     sha.update(
                         potentialPubSigningKey + potentialPubEncryptionKey)
                     ripe.update(sha.digest())
-                    # print 'potential ripe.digest',
-                    # ripe.digest().encode('hex')
                     if ripe.digest()[:numberOfNullBytesDemandedOnFrontOfRipeHash] == '\x00' * numberOfNullBytesDemandedOnFrontOfRipeHash:
                         break
-                print 'Generated address with ripe digest:', ripe.digest().encode('hex')
-                print 'Address generator calculated', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix, 'addresses at', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix / (time.time() - startTime), 'addresses per second before finding one with the correct ripe-prefix.'
+                logger.info('Generated address with ripe digest: %s' % ripe.digest().encode('hex'))
+                try:
+                    logger.info('Address generator calculated %s addresses at %s addresses per second before finding one with the correct ripe-prefix.' % (numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix, numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix / (time.time() - startTime)))
+                except ZeroDivisionError:
+                    # The user must have a pretty fast computer. time.time() - startTime equaled zero.
+                    pass
                 address = encodeAddress(addressVersionNumber, streamNumber, ripe.digest())
 
                 # An excellent way for us to store our keys is in Wallet Import Format. Let us convert now.
@@ -108,14 +108,12 @@ def run(self):
                     privSigningKey).digest()).digest()[0:4]
                 privSigningKeyWIF = arithmetic.changebase(
                     privSigningKey + checksum, 256, 58)
-                # print 'privSigningKeyWIF',privSigningKeyWIF
 
                 privEncryptionKey = '\x80' + potentialPrivEncryptionKey
                 checksum = hashlib.sha256(hashlib.sha256(
                     privEncryptionKey).digest()).digest()[0:4]
                 privEncryptionKeyWIF = arithmetic.changebase(
                     privEncryptionKey + checksum, 256, 58)
-                # print 'privEncryptionKeyWIF',privEncryptionKeyWIF
 
                 shared.config.add_section(address)
                 shared.config.set(address, 'label', label)
@@ -178,9 +176,6 @@ def run(self):
                             potentialPrivSigningKey)
                         potentialPubEncryptionKey = highlevelcrypto.pointMult(
                             potentialPrivEncryptionKey)
-                        # print 'potentialPubSigningKey', potentialPubSigningKey.encode('hex')
-                        # print 'potentialPubEncryptionKey',
-                        # potentialPubEncryptionKey.encode('hex')
                         signingKeyNonce += 2
                         encryptionKeyNonce += 2
                         ripe = hashlib.new('ripemd160')
@@ -188,13 +183,16 @@ def run(self):
                         sha.update(
                             potentialPubSigningKey + potentialPubEncryptionKey)
                         ripe.update(sha.digest())
-                        # print 'potential ripe.digest',
-                        # ripe.digest().encode('hex')
                         if ripe.digest()[:numberOfNullBytesDemandedOnFrontOfRipeHash] == '\x00' * numberOfNullBytesDemandedOnFrontOfRipeHash:
                             break
 
-                    print 'ripe.digest', ripe.digest().encode('hex')
-                    print 'Address generator calculated', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix, 'addresses at', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix / (time.time() - startTime), 'keys per second.'
+                    
+                    logger.info('Generated address with ripe digest: %s' % ripe.digest().encode('hex'))
+                    try:
+                        logger.info('Address generator calculated %s addresses at %s addresses per second before finding one with the correct ripe-prefix.' % (numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix, numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix / (time.time() - startTime)))
+                    except ZeroDivisionError:
+                        # The user must have a pretty fast computer. time.time() - startTime equaled zero.
+                        pass
                     address = encodeAddress(addressVersionNumber, streamNumber, ripe.digest())
 
                     saveAddressToDisk = True
@@ -222,14 +220,19 @@ def run(self):
                         privEncryptionKeyWIF = arithmetic.changebase(
                             privEncryptionKey + checksum, 256, 58)
 
-                        addressAlreadyExists = False
+                        
                         try:
                             shared.config.add_section(address)
+                            addressAlreadyExists = False
                         except:
-                            print address, 'already exists. Not adding it again.'
                             addressAlreadyExists = True
-                        if not addressAlreadyExists:
-                            print 'label:', label
+                            
+                        if addressAlreadyExists:
+                            logger.info('%s already exists. Not adding it again.' % address)
+                            shared.UISignalQueue.put((
+                                'updateStatusBar', tr.translateText("MainWindow","%1 is already in 'Your Identities'. Not adding it again.").arg(address)))
+                        else:
+                            logger.debug('label: %s' % label)
                             shared.config.set(address, 'label', label)
                             shared.config.set(address, 'enabled', 'true')
                             shared.config.set(address, 'decoy', 'false')
@@ -262,18 +265,16 @@ def run(self):
                             elif addressVersionNumber == 4:
                                 shared.workerQueue.put((
                                     'sendOutOrStoreMyV4Pubkey', address))
+                            shared.UISignalQueue.put((
+                                'updateStatusBar', tr.translateText("MainWindow", "Done generating address")))
 
 
                 # Done generating addresses.
                 if command == 'createDeterministicAddresses' or command == 'joinChan' or command == 'createChan':
                     shared.apiAddressGeneratorReturnQueue.put(
                         listOfNewAddressesToSendOutThroughTheAPI)
-                    shared.UISignalQueue.put((
-                        'updateStatusBar', tr.translateText("MainWindow", "Done generating address")))
-                    # shared.reloadMyAddressHashes()
                 elif command == 'getDeterministicAddress':
                     shared.apiAddressGeneratorReturnQueue.put(address)
-                #todo: return things to the API if createChan or joinChan assuming saveAddressToDisk
             else:
                 raise Exception(
                     "Error in the addressGenerator thread. Thread was given a command it could not understand: " + command)


Test patch: