Sorted out configuration loading/updating a bit:

- used BMConfigParser.safeGet.. methods instead of try .. except
  - moved all config checks from class_sqlThread into helper_startup
  - commented out initialization of settings which are then rewritten
    by updateConfig()
This commit is contained in:
Dmitri Bogomolov 2018-03-03 17:31:49 +02:00
parent 2504c80da6
commit ba5caf3fda
Signed by untrusted user: g1itch
GPG Key ID: 720A756F18DEED13
6 changed files with 315 additions and 220 deletions

View File

@ -150,9 +150,7 @@ class BMAccount(object):
"""Get a label for this bitmessage account""" """Get a label for this bitmessage account"""
if address is None: if address is None:
address = self.address address = self.address
label = address label = BMConfigParser().safeGet(address, 'label', address)
if BMConfigParser().has_section(address):
label = BMConfigParser().get(address, 'label')
queryreturn = sqlQuery( queryreturn = sqlQuery(
'''select label from addressbook where address=?''', address) '''select label from addressbook where address=?''', address)
if queryreturn != []: if queryreturn != []:

View File

@ -12,26 +12,24 @@ class LanguageBox(QtGui.QComboBox):
self.populate() self.populate()
def populate(self): def populate(self):
self.languages = []
self.clear() self.clear()
localesPath = os.path.join (paths.codePath(), 'translations') localesPath = os.path.join (paths.codePath(), 'translations')
configuredLocale = "system"
try:
configuredLocale = BMConfigParser().get('bitmessagesettings', 'userlocale', "system")
except:
pass
self.addItem(QtGui.QApplication.translate("settingsDialog", "System Settings", "system"), "system") self.addItem(QtGui.QApplication.translate("settingsDialog", "System Settings", "system"), "system")
self.setCurrentIndex(0) self.setCurrentIndex(0)
self.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically) self.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically)
for translationFile in sorted(glob.glob(os.path.join(localesPath, "bitmessage_*.qm"))): for translationFile in sorted(glob.glob(os.path.join(localesPath, "bitmessage_*.qm"))):
localeShort = os.path.split(translationFile)[1].split("_", 1)[1][:-3] localeShort = os.path.split(translationFile)[1].split("_", 1)[1][:-3]
locale = QtCore.QLocale(QtCore.QString(localeShort)) locale = QtCore.QLocale(QtCore.QString(localeShort))
if localeShort in LanguageBox.languageName: if localeShort in LanguageBox.languageName:
self.addItem(LanguageBox.languageName[localeShort], localeShort) self.addItem(LanguageBox.languageName[localeShort], localeShort)
elif locale.nativeLanguageName() == "": elif locale.nativeLanguageName() == "":
self.addItem(localeShort, localeShort) self.addItem(localeShort, localeShort)
else: else:
self.addItem(locale.nativeLanguageName(), localeShort) self.addItem(locale.nativeLanguageName(), localeShort)
configuredLocale = BMConfigParser().safeGet(
'bitmessagesettings', 'userlocale', "system")
for i in range(self.count()): for i in range(self.count()):
if self.itemData(i) == configuredLocale: if self.itemData(i) == configuredLocale:
self.setCurrentIndex(i) self.setCurrentIndex(i)

View File

@ -114,18 +114,13 @@ def createSupportMessage(myapp):
frozen = paths.frozen frozen = paths.frozen
portablemode = "True" if state.appdata == paths.lookupExeFolder() else "False" portablemode = "True" if state.appdata == paths.lookupExeFolder() else "False"
cpow = "True" if proofofwork.bmpow else "False" cpow = "True" if proofofwork.bmpow else "False"
#cpow = QtGui.QApplication.translate("Support", cpow) openclpow = str(
openclpow = str(BMConfigParser().safeGet('bitmessagesettings', 'opencl')) if openclEnabled() else "None" BMConfigParser().safeGet('bitmessagesettings', 'opencl')
#openclpow = QtGui.QApplication.translate("Support", openclpow) ) if openclEnabled() else "None"
locale = getTranslationLanguage() locale = getTranslationLanguage()
try: socks = BMConfigParser().safeGet(
socks = BMConfigParser().get('bitmessagesettings', 'socksproxytype') 'bitmessagesettings', 'socksproxytype', "N/A")
except: upnp = BMConfigParser().safeGet('bitmessagesettings', 'upnp', "N/A")
socks = "N/A"
try:
upnp = BMConfigParser().get('bitmessagesettings', 'upnp')
except:
upnp = "N/A"
connectedhosts = len(network.stats.connectedHostsList()) connectedhosts = len(network.stats.connectedHostsList())
myapp.ui.textEditMessage.setText(str(QtGui.QApplication.translate("Support", SUPPORT_MESSAGE)).format(version, os, architecture, pythonversion, opensslversion, frozen, portablemode, cpow, openclpow, locale, socks, upnp, connectedhosts)) myapp.ui.textEditMessage.setText(str(QtGui.QApplication.translate("Support", SUPPORT_MESSAGE)).format(version, os, architecture, pythonversion, opensslversion, frozen, portablemode, cpow, openclpow, locale, socks, upnp, connectedhosts))

View File

@ -10,26 +10,24 @@ str_chan = '[chan]'
def identiconize(address): def identiconize(address):
size = 48 size = 48
# If you include another identicon library, please generate an if not BMConfigParser().getboolean('bitmessagesettings', 'useidenticons'):
return QtGui.QIcon()
# If you include another identicon library, please generate an
# example identicon with the following md5 hash: # example identicon with the following md5 hash:
# 3fd4bf901b9d4ea1394f0fb358725b28 # 3fd4bf901b9d4ea1394f0fb358725b28
try:
identicon_lib = BMConfigParser().get('bitmessagesettings', 'identiconlib')
except:
# default to qidenticon_two_x
identicon_lib = 'qidenticon_two_x'
# As an 'identiconsuffix' you could put "@bitmessge.ch" or "@bm.addr" to make it compatible with other identicon generators. (Note however, that E-Mail programs might convert the BM-address to lowercase first.) identicon_lib = BMConfigParser().safeGet(
# It can be used as a pseudo-password to salt the generation of the identicons to decrease the risk 'bitmessagesettings', 'identiconlib', 'qidenticon_two_x')
# of attacks where someone creates an address to mimic someone else's identicon.
# As an 'identiconsuffix' you could put "@bitmessge.ch" or "@bm.addr"
# to make it compatible with other identicon generators. (Note however,
# that E-Mail programs might convert the BM-address to lowercase first.)
# It can be used as a pseudo-password to salt the generation of
# the identicons to decrease the risk of attacks where someone creates
# an address to mimic someone else's identicon.
identiconsuffix = BMConfigParser().get('bitmessagesettings', 'identiconsuffix') identiconsuffix = BMConfigParser().get('bitmessagesettings', 'identiconsuffix')
if not BMConfigParser().getboolean('bitmessagesettings', 'useidenticons'):
idcon = QtGui.QIcon()
return idcon
if (identicon_lib[:len('qidenticon')] == 'qidenticon'): if (identicon_lib[:len('qidenticon')] == 'qidenticon'):
# print identicon_lib # print identicon_lib
# originally by: # originally by:

View File

@ -6,14 +6,13 @@ import shutil # used for moving the messages.dat file
import sys import sys
import os import os
from debug import logger from debug import logger
import defaults
import helper_sql import helper_sql
from namecoin import ensureNamecoinOptions import helper_startup
import paths import paths
import queues import queues
import state import state
import tr#anslate import tr
import helper_random
# This thread exists because SQLITE3 is so un-threadsafe that we must # This thread exists because SQLITE3 is so un-threadsafe that we must
# submit queries to it and it puts results back in a different queue. They # submit queries to it and it puts results back in a different queue. They
# won't let us just use locks. # won't let us just use locks.
@ -68,35 +67,26 @@ class sqlThread(threading.Thread):
'ERROR trying to create database file (message.dat). Error message: %s\n' % str(err)) 'ERROR trying to create database file (message.dat). Error message: %s\n' % str(err))
os._exit(0) os._exit(0)
if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 1: # If the settings version is equal to 2 or 3 then the
BMConfigParser().set('bitmessagesettings', 'settingsversion', '2') # sqlThread will modify the pubkeys table and change
# If the settings version is equal to 2 or 3 then the # the settings version to 4.
# sqlThread will modify the pubkeys table and change settingsversion = BMConfigParser().getint(
# the settings version to 4. 'bitmessagesettings', 'settingsversion')
BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'none')
BMConfigParser().set('bitmessagesettings', 'sockshostname', 'localhost')
BMConfigParser().set('bitmessagesettings', 'socksport', '9050')
BMConfigParser().set('bitmessagesettings', 'socksauthentication', 'false')
BMConfigParser().set('bitmessagesettings', 'socksusername', '')
BMConfigParser().set('bitmessagesettings', 'sockspassword', '')
BMConfigParser().set('bitmessagesettings', 'sockslisten', 'false')
BMConfigParser().set('bitmessagesettings', 'keysencrypted', 'false')
BMConfigParser().set('bitmessagesettings', 'messagesencrypted', 'false')
# People running earlier versions of PyBitmessage do not have the # People running earlier versions of PyBitmessage do not have the
# usedpersonally field in their pubkeys table. Let's add it. # usedpersonally field in their pubkeys table. Let's add it.
if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 2: if settingsversion == 2:
item = '''ALTER TABLE pubkeys ADD usedpersonally text DEFAULT 'no' ''' item = '''ALTER TABLE pubkeys ADD usedpersonally text DEFAULT 'no' '''
parameters = '' parameters = ''
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
self.conn.commit() self.conn.commit()
BMConfigParser().set('bitmessagesettings', 'settingsversion', '3') settingsversion = 3
# People running earlier versions of PyBitmessage do not have the # People running earlier versions of PyBitmessage do not have the
# encodingtype field in their inbox and sent tables or the read field # encodingtype field in their inbox and sent tables or the read field
# in the inbox table. Let's add them. # in the inbox table. Let's add them.
if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 3: if settingsversion == 3:
item = '''ALTER TABLE inbox ADD encodingtype int DEFAULT '2' ''' item = '''ALTER TABLE inbox ADD encodingtype int DEFAULT '2' '''
parameters = '' parameters = ''
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
@ -110,21 +100,13 @@ class sqlThread(threading.Thread):
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
self.conn.commit() self.conn.commit()
BMConfigParser().set('bitmessagesettings', 'settingsversion', '4') settingsversion = 4
if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 4: BMConfigParser().set(
BMConfigParser().set('bitmessagesettings', 'defaultnoncetrialsperbyte', str( 'bitmessagesettings', 'settingsversion', str(settingsversion))
defaults.networkDefaultProofOfWorkNonceTrialsPerByte)) BMConfigParser().save()
BMConfigParser().set('bitmessagesettings', 'defaultpayloadlengthextrabytes', str(
defaults.networkDefaultPayloadLengthExtraBytes))
BMConfigParser().set('bitmessagesettings', 'settingsversion', '5')
if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 5: helper_startup.updateConfig()
BMConfigParser().set(
'bitmessagesettings', 'maxacceptablenoncetrialsperbyte', '0')
BMConfigParser().set(
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', '0')
BMConfigParser().set('bitmessagesettings', 'settingsversion', '6')
# From now on, let us keep a 'version' embedded in the messages.dat # From now on, let us keep a 'version' embedded in the messages.dat
# file so that when we make changes to the database, the database # file so that when we make changes to the database, the database
@ -135,7 +117,8 @@ class sqlThread(threading.Thread):
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
if self.cur.fetchall() == []: if self.cur.fetchall() == []:
# The settings table doesn't exist. We need to make it. # The settings table doesn't exist. We need to make it.
logger.debug('In messages.dat database, creating new \'settings\' table.') logger.debug(
"In messages.dat database, creating new 'settings' table.")
self.cur.execute( self.cur.execute(
'''CREATE TABLE settings (key text, value blob, UNIQUE(key) ON CONFLICT REPLACE)''' ) '''CREATE TABLE settings (key text, value blob, UNIQUE(key) ON CONFLICT REPLACE)''' )
self.cur.execute( '''INSERT INTO settings VALUES('version','1')''') self.cur.execute( '''INSERT INTO settings VALUES('version','1')''')
@ -177,17 +160,15 @@ class sqlThread(threading.Thread):
'''update sent set status='broadcastqueued' where status='broadcastpending' ''') '''update sent set status='broadcastqueued' where status='broadcastpending' ''')
self.conn.commit() self.conn.commit()
if not BMConfigParser().has_option('bitmessagesettings', 'sockslisten'): # Let's get rid of the first20bytesofencryptedmessage field in
BMConfigParser().set('bitmessagesettings', 'sockslisten', 'false') # the inventory table.
ensureNamecoinOptions()
# Let's get rid of the first20bytesofencryptedmessage field in the inventory table.
item = '''SELECT value FROM settings WHERE key='version';''' item = '''SELECT value FROM settings WHERE key='version';'''
parameters = '' parameters = ''
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
if int(self.cur.fetchall()[0][0]) == 2: if int(self.cur.fetchall()[0][0]) == 2:
logger.debug('In messages.dat database, removing an obsolete field from the inventory table.') logger.debug(
'In messages.dat database, removing an obsolete field from'
' the inventory table.')
self.cur.execute( self.cur.execute(
'''CREATE TEMPORARY TABLE inventory_backup(hash blob, objecttype text, streamnumber int, payload blob, receivedtime integer, UNIQUE(hash) ON CONFLICT REPLACE);''') '''CREATE TEMPORARY TABLE inventory_backup(hash blob, objecttype text, streamnumber int, payload blob, receivedtime integer, UNIQUE(hash) ON CONFLICT REPLACE);''')
self.cur.execute( self.cur.execute(
@ -208,7 +189,9 @@ class sqlThread(threading.Thread):
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
currentVersion = int(self.cur.fetchall()[0][0]) currentVersion = int(self.cur.fetchall()[0][0])
if currentVersion == 1 or currentVersion == 3: if currentVersion == 1 or currentVersion == 3:
logger.debug('In messages.dat database, adding tag field to the inventory table.') logger.debug(
'In messages.dat database, adding tag field to'
' the inventory table.')
item = '''ALTER TABLE inventory ADD tag blob DEFAULT '' ''' item = '''ALTER TABLE inventory ADD tag blob DEFAULT '' '''
parameters = '' parameters = ''
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
@ -216,16 +199,6 @@ class sqlThread(threading.Thread):
parameters = (4,) parameters = (4,)
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
if not BMConfigParser().has_option('bitmessagesettings', 'userlocale'):
BMConfigParser().set('bitmessagesettings', 'userlocale', 'system')
if not BMConfigParser().has_option('bitmessagesettings', 'sendoutgoingconnections'):
BMConfigParser().set('bitmessagesettings', 'sendoutgoingconnections', 'True')
# Raise the default required difficulty from 1 to 2
# With the change to protocol v3, this is obsolete.
if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 6:
BMConfigParser().set('bitmessagesettings', 'settingsversion', '7')
# Add a new column to the pubkeys table to store the address version. # Add a new column to the pubkeys table to store the address version.
# We're going to trash all of our pubkeys and let them be redownloaded. # We're going to trash all of our pubkeys and let them be redownloaded.
item = '''SELECT value FROM settings WHERE key='version';''' item = '''SELECT value FROM settings WHERE key='version';'''
@ -233,28 +206,15 @@ class sqlThread(threading.Thread):
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
currentVersion = int(self.cur.fetchall()[0][0]) currentVersion = int(self.cur.fetchall()[0][0])
if currentVersion == 4: if currentVersion == 4:
self.cur.execute( '''DROP TABLE pubkeys''') self.cur.execute('''DROP TABLE pubkeys''')
self.cur.execute( self.cur.execute(
'''CREATE TABLE pubkeys (hash blob, addressversion int, transmitdata blob, time int, usedpersonally text, UNIQUE(hash, addressversion) ON CONFLICT REPLACE)''' ) '''CREATE TABLE pubkeys (hash blob, addressversion int, transmitdata blob, time int, usedpersonally text, UNIQUE(hash, addressversion) ON CONFLICT REPLACE)''')
self.cur.execute( self.cur.execute(
'''delete from inventory where objecttype = 'pubkey';''') '''delete from inventory where objecttype = 'pubkey';''')
item = '''update settings set value=? WHERE key='version';''' item = '''update settings set value=? WHERE key='version';'''
parameters = (5,) parameters = (5,)
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
if not BMConfigParser().has_option('bitmessagesettings', 'useidenticons'):
BMConfigParser().set('bitmessagesettings', 'useidenticons', 'True')
if not BMConfigParser().has_option('bitmessagesettings', 'identiconsuffix'): # acts as a salt
BMConfigParser().set('bitmessagesettings', 'identiconsuffix', ''.join(helper_random.randomchoice("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") for x in range(12)))# a twelve character pseudo-password to salt the identicons
#Add settings to support no longer resending messages after a certain period of time even if we never get an ack
if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 7:
BMConfigParser().set(
'bitmessagesettings', 'stopresendingafterxdays', '')
BMConfigParser().set(
'bitmessagesettings', 'stopresendingafterxmonths', '')
BMConfigParser().set('bitmessagesettings', 'settingsversion', '8')
# Add a new table: objectprocessorqueue with which to hold objects # Add a new table: objectprocessorqueue with which to hold objects
# that have yet to be processed if the user shuts down Bitmessage. # that have yet to be processed if the user shuts down Bitmessage.
item = '''SELECT value FROM settings WHERE key='version';''' item = '''SELECT value FROM settings WHERE key='version';'''
@ -262,21 +222,24 @@ class sqlThread(threading.Thread):
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
currentVersion = int(self.cur.fetchall()[0][0]) currentVersion = int(self.cur.fetchall()[0][0])
if currentVersion == 5: if currentVersion == 5:
self.cur.execute( '''DROP TABLE knownnodes''') self.cur.execute('''DROP TABLE knownnodes''')
self.cur.execute( self.cur.execute(
'''CREATE TABLE objectprocessorqueue (objecttype text, data blob, UNIQUE(objecttype, data) ON CONFLICT REPLACE)''' ) '''CREATE TABLE objectprocessorqueue (objecttype text, data blob, UNIQUE(objecttype, data) ON CONFLICT REPLACE)''')
item = '''update settings set value=? WHERE key='version';''' item = '''update settings set value=? WHERE key='version';'''
parameters = (6,) parameters = (6,)
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
# changes related to protocol v3 # changes related to protocol v3
# In table inventory and objectprocessorqueue, objecttype is now an integer (it was a human-friendly string previously) # In table inventory and objectprocessorqueue, objecttype is now
# an integer (it was a human-friendly string previously)
item = '''SELECT value FROM settings WHERE key='version';''' item = '''SELECT value FROM settings WHERE key='version';'''
parameters = '' parameters = ''
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
currentVersion = int(self.cur.fetchall()[0][0]) currentVersion = int(self.cur.fetchall()[0][0])
if currentVersion == 6: if currentVersion == 6:
logger.debug('In messages.dat database, dropping and recreating the inventory table.') logger.debug(
'In messages.dat database, dropping and recreating'
' the inventory table.')
self.cur.execute( '''DROP TABLE inventory''') self.cur.execute( '''DROP TABLE inventory''')
self.cur.execute( '''CREATE TABLE inventory (hash blob, objecttype int, streamnumber int, payload blob, expirestime integer, tag blob, UNIQUE(hash) ON CONFLICT REPLACE)''' ) self.cur.execute( '''CREATE TABLE inventory (hash blob, objecttype int, streamnumber int, payload blob, expirestime integer, tag blob, UNIQUE(hash) ON CONFLICT REPLACE)''' )
self.cur.execute( '''DROP TABLE objectprocessorqueue''') self.cur.execute( '''DROP TABLE objectprocessorqueue''')
@ -284,57 +247,26 @@ class sqlThread(threading.Thread):
item = '''update settings set value=? WHERE key='version';''' item = '''update settings set value=? WHERE key='version';'''
parameters = (7,) parameters = (7,)
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
logger.debug('Finished dropping and recreating the inventory table.') logger.debug(
'Finished dropping and recreating the inventory table.')
# With the change to protocol version 3, reset the user-settable difficulties to 1
if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 8:
BMConfigParser().set('bitmessagesettings','defaultnoncetrialsperbyte', str(defaults.networkDefaultProofOfWorkNonceTrialsPerByte))
BMConfigParser().set('bitmessagesettings','defaultpayloadlengthextrabytes', str(defaults.networkDefaultPayloadLengthExtraBytes))
previousTotalDifficulty = int(BMConfigParser().getint('bitmessagesettings', 'maxacceptablenoncetrialsperbyte')) / 320
previousSmallMessageDifficulty = int(BMConfigParser().getint('bitmessagesettings', 'maxacceptablepayloadlengthextrabytes')) / 14000
BMConfigParser().set('bitmessagesettings','maxacceptablenoncetrialsperbyte', str(previousTotalDifficulty * 1000))
BMConfigParser().set('bitmessagesettings','maxacceptablepayloadlengthextrabytes', str(previousSmallMessageDifficulty * 1000))
BMConfigParser().set('bitmessagesettings', 'settingsversion', '9')
# Adjust the required POW values for each of this user's addresses to conform to protocol v3 norms.
if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 9:
for addressInKeysFile in BMConfigParser().addressses():
try:
previousTotalDifficulty = float(BMConfigParser().getint(addressInKeysFile, 'noncetrialsperbyte')) / 320
previousSmallMessageDifficulty = float(BMConfigParser().getint(addressInKeysFile, 'payloadlengthextrabytes')) / 14000
if previousTotalDifficulty <= 2:
previousTotalDifficulty = 1
if previousSmallMessageDifficulty < 1:
previousSmallMessageDifficulty = 1
BMConfigParser().set(addressInKeysFile,'noncetrialsperbyte', str(int(previousTotalDifficulty * 1000)))
BMConfigParser().set(addressInKeysFile,'payloadlengthextrabytes', str(int(previousSmallMessageDifficulty * 1000)))
except:
continue
BMConfigParser().set('bitmessagesettings', 'maxdownloadrate', '0')
BMConfigParser().set('bitmessagesettings', 'maxuploadrate', '0')
BMConfigParser().set('bitmessagesettings', 'settingsversion', '10')
BMConfigParser().save()
# sanity check
if BMConfigParser().getint('bitmessagesettings', 'maxacceptablenoncetrialsperbyte') == 0:
BMConfigParser().set('bitmessagesettings','maxacceptablenoncetrialsperbyte', str(defaults.ridiculousDifficulty * defaults.networkDefaultProofOfWorkNonceTrialsPerByte))
if BMConfigParser().getint('bitmessagesettings', 'maxacceptablepayloadlengthextrabytes') == 0:
BMConfigParser().set('bitmessagesettings','maxacceptablepayloadlengthextrabytes', str(defaults.ridiculousDifficulty * defaults.networkDefaultPayloadLengthExtraBytes))
# The format of data stored in the pubkeys table has changed. Let's # The format of data stored in the pubkeys table has changed. Let's
# clear it, and the pubkeys from inventory, so that they'll be re-downloaded. # clear it, and the pubkeys from inventory, so that they'll
# be re-downloaded.
item = '''SELECT value FROM settings WHERE key='version';''' item = '''SELECT value FROM settings WHERE key='version';'''
parameters = '' parameters = ''
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
currentVersion = int(self.cur.fetchall()[0][0]) currentVersion = int(self.cur.fetchall()[0][0])
if currentVersion == 7: if currentVersion == 7:
logger.debug('In messages.dat database, clearing pubkeys table because the data format has been updated.') logger.debug(
'In messages.dat database, clearing pubkeys table'
' because the data format has been updated.')
self.cur.execute( self.cur.execute(
'''delete from inventory where objecttype = 1;''') '''delete from inventory where objecttype = 1;''')
self.cur.execute( self.cur.execute(
'''delete from pubkeys;''') '''delete from pubkeys;''')
# Any sending messages for which we *thought* that we had the pubkey must # Any sending messages for which we *thought* that we had
# be rechecked. # the pubkey must be rechecked.
self.cur.execute( self.cur.execute(
'''UPDATE sent SET status='msgqueued' WHERE status='doingmsgpow' or status='badkey';''') '''UPDATE sent SET status='msgqueued' WHERE status='doingmsgpow' or status='badkey';''')
query = '''update settings set value=? WHERE key='version';''' query = '''update settings set value=? WHERE key='version';'''
@ -342,14 +274,17 @@ class sqlThread(threading.Thread):
self.cur.execute(query, parameters) self.cur.execute(query, parameters)
logger.debug('Finished clearing currently held pubkeys.') logger.debug('Finished clearing currently held pubkeys.')
# Add a new column to the inbox table to store the hash of the message signature. # Add a new column to the inbox table to store the hash of
# We'll use this as temporary message UUID in order to detect duplicates. # the message signature. We'll use this as temporary message UUID
# in order to detect duplicates.
item = '''SELECT value FROM settings WHERE key='version';''' item = '''SELECT value FROM settings WHERE key='version';'''
parameters = '' parameters = ''
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
currentVersion = int(self.cur.fetchall()[0][0]) currentVersion = int(self.cur.fetchall()[0][0])
if currentVersion == 8: if currentVersion == 8:
logger.debug('In messages.dat database, adding sighash field to the inbox table.') logger.debug(
'In messages.dat database, adding sighash field to'
' the inbox table.')
item = '''ALTER TABLE inbox ADD sighash blob DEFAULT '' ''' item = '''ALTER TABLE inbox ADD sighash blob DEFAULT '' '''
parameters = '' parameters = ''
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
@ -357,17 +292,18 @@ class sqlThread(threading.Thread):
parameters = (9,) parameters = (9,)
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
# TTL is now user-specifiable. Let's add an option to save whatever the user selects. # We'll also need a `sleeptill` field and a `ttl` field. Also we
if not BMConfigParser().has_option('bitmessagesettings', 'ttl'): # can combine the pubkeyretrynumber and msgretrynumber into one.
BMConfigParser().set('bitmessagesettings', 'ttl', '367200')
# We'll also need a `sleeptill` field and a `ttl` field. Also we can combine
# the pubkeyretrynumber and msgretrynumber into one.
item = '''SELECT value FROM settings WHERE key='version';''' item = '''SELECT value FROM settings WHERE key='version';'''
parameters = '' parameters = ''
self.cur.execute(item, parameters) self.cur.execute(item, parameters)
currentVersion = int(self.cur.fetchall()[0][0]) currentVersion = int(self.cur.fetchall()[0][0])
if currentVersion == 9: if currentVersion == 9:
logger.info('In messages.dat database, making TTL-related changes: combining the pubkeyretrynumber and msgretrynumber fields into the retrynumber field and adding the sleeptill and ttl fields...') logger.info(
'In messages.dat database, making TTL-related changes:'
' combining the pubkeyretrynumber and msgretrynumber'
' fields into the retrynumber field and adding the'
' sleeptill and ttl fields...')
self.cur.execute( self.cur.execute(
'''CREATE TEMPORARY TABLE sent_backup (msgid blob, toaddress text, toripe blob, fromaddress text, subject text, message text, ackdata blob, lastactiontime integer, status text, retrynumber integer, folder text, encodingtype int)''' ) '''CREATE TEMPORARY TABLE sent_backup (msgid blob, toaddress text, toripe blob, fromaddress text, subject text, message text, ackdata blob, lastactiontime integer, status text, retrynumber integer, folder text, encodingtype int)''' )
self.cur.execute( self.cur.execute(
@ -406,30 +342,9 @@ class sqlThread(threading.Thread):
logger.debug('In messages.dat database, done adding address field to the pubkeys table and removing the hash field.') logger.debug('In messages.dat database, done adding address field to the pubkeys table and removing the hash field.')
self.cur.execute('''update settings set value=10 WHERE key='version';''') self.cur.execute('''update settings set value=10 WHERE key='version';''')
if not BMConfigParser().has_option('bitmessagesettings', 'onionhostname'):
BMConfigParser().set('bitmessagesettings', 'onionhostname', '')
if not BMConfigParser().has_option('bitmessagesettings', 'onionport'):
BMConfigParser().set('bitmessagesettings', 'onionport', '8444')
if not BMConfigParser().has_option('bitmessagesettings', 'onionbindip'):
BMConfigParser().set('bitmessagesettings', 'onionbindip', '127.0.0.1')
if not BMConfigParser().has_option('bitmessagesettings', 'smtpdeliver'):
BMConfigParser().set('bitmessagesettings', 'smtpdeliver', '')
if not BMConfigParser().has_option('bitmessagesettings', 'hidetrayconnectionnotifications'):
BMConfigParser().set('bitmessagesettings', 'hidetrayconnectionnotifications', 'false')
if BMConfigParser().has_option('bitmessagesettings', 'maxoutboundconnections'):
try:
if BMConfigParser().getint('bitmessagesettings', 'maxoutboundconnections') < 1: raise ValueError
except ValueError as err:
BMConfigParser().remove_option('bitmessagesettings', 'maxoutboundconnections')
logger.error('Your maximum outbound connections must be a number.')
if not BMConfigParser().has_option('bitmessagesettings', 'maxoutboundconnections'):
logger.info('Setting maximum outbound connections to 8.')
BMConfigParser().set('bitmessagesettings', 'maxoutboundconnections', '8')
BMConfigParser().save()
# Are you hoping to add a new option to the keys.dat file of existing # Are you hoping to add a new option to the keys.dat file of existing
# Bitmessage users or modify the SQLite database? Add it right above this line! # Bitmessage users or modify the SQLite database? Add it right
# above this line!
try: try:
testpayload = '\x00\x00' testpayload = '\x00\x00'

View File

@ -12,9 +12,9 @@ import paths
import state import state
import helper_random import helper_random
# The user may de-select Portable Mode in the settings if they want
# the config files to stay in the application data folder.
StoreConfigFilesInSameDirectoryAsProgramByDefault = False StoreConfigFilesInSameDirectoryAsProgramByDefault = False
# The user may de-select Portable Mode in the settings if they want the config
# files to stay in the application data folder.
def _loadTrustedPeer(): def _loadTrustedPeer():
@ -33,13 +33,12 @@ def loadConfig():
if state.appdata: if state.appdata:
BMConfigParser().read(state.appdata + 'keys.dat') BMConfigParser().read(state.appdata + 'keys.dat')
# state.appdata must have been specified as a startup option. # state.appdata must have been specified as a startup option.
try: needToCreateKeysFile = BMConfigParser().safeGet(
BMConfigParser().get('bitmessagesettings', 'settingsversion') 'bitmessagesettings', 'settingsversion') is None
print 'Loading config files from directory specified on startup: ' + state.appdata if not needToCreateKeysFile:
needToCreateKeysFile = False print(
except Exception: 'Loading config files from directory specified'
needToCreateKeysFile = True ' on startup: %s' % state.appdata)
else: else:
BMConfigParser().read(paths.lookupExeFolder() + 'keys.dat') BMConfigParser().read(paths.lookupExeFolder() + 'keys.dat')
try: try:
@ -47,19 +46,18 @@ def loadConfig():
print 'Loading config files from same directory as program.' print 'Loading config files from same directory as program.'
needToCreateKeysFile = False needToCreateKeysFile = False
state.appdata = paths.lookupExeFolder() state.appdata = paths.lookupExeFolder()
except Exception: except:
# Could not load the keys.dat file in the program directory. # Could not load the keys.dat file in the program directory.
# Perhaps it is in the appdata directory. # Perhaps it is in the appdata directory.
state.appdata = paths.lookupAppdataFolder() state.appdata = paths.lookupAppdataFolder()
BMConfigParser().read(state.appdata + 'keys.dat') BMConfigParser().read(state.appdata + 'keys.dat')
try: needToCreateKeysFile = BMConfigParser().safeGet(
BMConfigParser().get('bitmessagesettings', 'settingsversion') 'bitmessagesettings', 'settingsversion') is None
if not needToCreateKeysFile:
print 'Loading existing config files from', state.appdata print 'Loading existing config files from', state.appdata
needToCreateKeysFile = False
except Exception:
needToCreateKeysFile = True
if needToCreateKeysFile: if needToCreateKeysFile:
# This appears to be the first time running the program; there is # This appears to be the first time running the program; there is
# no config file (or it cannot be accessed). Create config file. # no config file (or it cannot be accessed). Create config file.
BMConfigParser().add_section('bitmessagesettings') BMConfigParser().add_section('bitmessagesettings')
@ -72,9 +70,9 @@ def loadConfig():
if 'linux' in sys.platform: if 'linux' in sys.platform:
BMConfigParser().set( BMConfigParser().set(
'bitmessagesettings', 'minimizetotray', 'false') 'bitmessagesettings', 'minimizetotray', 'false')
# This isn't implimented yet and when True on # This isn't implimented yet and when True on
# Ubuntu causes Bitmessage to disappear while # Ubuntu causes Bitmessage to disappear while
# running when minimized. # running when minimized.
else: else:
BMConfigParser().set( BMConfigParser().set(
'bitmessagesettings', 'minimizetotray', 'true') 'bitmessagesettings', 'minimizetotray', 'true')
@ -87,46 +85,54 @@ def loadConfig():
BMConfigParser().set('bitmessagesettings', 'socksport', '9050') BMConfigParser().set('bitmessagesettings', 'socksport', '9050')
BMConfigParser().set( BMConfigParser().set(
'bitmessagesettings', 'socksauthentication', 'false') 'bitmessagesettings', 'socksauthentication', 'false')
BMConfigParser().set( # BMConfigParser().set(
'bitmessagesettings', 'sockslisten', 'false') # 'bitmessagesettings', 'sockslisten', 'false')
BMConfigParser().set('bitmessagesettings', 'socksusername', '') BMConfigParser().set('bitmessagesettings', 'socksusername', '')
BMConfigParser().set('bitmessagesettings', 'sockspassword', '') BMConfigParser().set('bitmessagesettings', 'sockspassword', '')
BMConfigParser().set('bitmessagesettings', 'keysencrypted', 'false') BMConfigParser().set('bitmessagesettings', 'keysencrypted', 'false')
BMConfigParser().set( BMConfigParser().set(
'bitmessagesettings', 'messagesencrypted', 'false') 'bitmessagesettings', 'messagesencrypted', 'false')
BMConfigParser().set('bitmessagesettings', 'defaultnoncetrialsperbyte', str( BMConfigParser().set(
defaults.networkDefaultProofOfWorkNonceTrialsPerByte)) 'bitmessagesettings', 'defaultnoncetrialsperbyte',
BMConfigParser().set('bitmessagesettings', 'defaultpayloadlengthextrabytes', str( str(defaults.networkDefaultProofOfWorkNonceTrialsPerByte))
defaults.networkDefaultPayloadLengthExtraBytes)) BMConfigParser().set(
'bitmessagesettings', 'defaultpayloadlengthextrabytes',
str(defaults.networkDefaultPayloadLengthExtraBytes))
BMConfigParser().set('bitmessagesettings', 'minimizeonclose', 'false') BMConfigParser().set('bitmessagesettings', 'minimizeonclose', 'false')
BMConfigParser().set( # BMConfigParser().set(
'bitmessagesettings', 'maxacceptablenoncetrialsperbyte', '0') # 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte', '0')
BMConfigParser().set( # BMConfigParser().set(
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', '0') # 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes',
# '0')
BMConfigParser().set('bitmessagesettings', 'dontconnect', 'true') BMConfigParser().set('bitmessagesettings', 'dontconnect', 'true')
BMConfigParser().set('bitmessagesettings', 'userlocale', 'system') # BMConfigParser().set('bitmessagesettings', 'userlocale', 'system')
BMConfigParser().set('bitmessagesettings', 'useidenticons', 'True') # BMConfigParser().set('bitmessagesettings', 'useidenticons', 'True')
BMConfigParser().set('bitmessagesettings', 'identiconsuffix', ''.join(helper_random.randomchoice("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") for x in range(12)))# a twelve character pseudo-password to salt the identicons # BMConfigParser().set(
# 'bitmessagesettings', 'identiconsuffix',
# ''.join(helper_random.randomchoice(
# "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
# ) for x in range(12)
# )) # a twelve character pseudo-password to salt the identicons
BMConfigParser().set('bitmessagesettings', 'replybelow', 'False') BMConfigParser().set('bitmessagesettings', 'replybelow', 'False')
BMConfigParser().set('bitmessagesettings', 'maxdownloadrate', '0') BMConfigParser().set('bitmessagesettings', 'maxdownloadrate', '0')
BMConfigParser().set('bitmessagesettings', 'maxuploadrate', '0') BMConfigParser().set('bitmessagesettings', 'maxuploadrate', '0')
BMConfigParser().set('bitmessagesettings', 'maxoutboundconnections', '8') # BMConfigParser().set(
BMConfigParser().set('bitmessagesettings', 'ttl', '367200') # 'bitmessagesettings', 'maxoutboundconnections', '8')
# BMConfigParser().set('bitmessagesettings', 'ttl', '367200')
#start:UI setting to stop trying to send messages after X days/months # UI setting to stop trying to send messages after X days/months
BMConfigParser().set( BMConfigParser().set(
'bitmessagesettings', 'stopresendingafterxdays', '') 'bitmessagesettings', 'stopresendingafterxdays', '')
BMConfigParser().set( BMConfigParser().set(
'bitmessagesettings', 'stopresendingafterxmonths', '') 'bitmessagesettings', 'stopresendingafterxmonths', '')
#BMConfigParser().set( # BMConfigParser().set(
# 'bitmessagesettings', 'timeperiod', '-1') # 'bitmessagesettings', 'timeperiod', '-1')
#end
# Are you hoping to add a new option to the keys.dat file? You're in # Are you hoping to add a new option to the keys.dat file? You're in
# the right place for adding it to users who install the software for # the right place for adding it to users who install the software for
# the first time. But you must also add it to the keys.dat file of # the first time. But you must also add it to the keys.dat file of
# existing users. To do that, search the class_sqlThread.py file for the # existing users. To do that, search the class_sqlThread.py file
# text: "right above this line!" # for the text: "right above this line!"
if StoreConfigFilesInSameDirectoryAsProgramByDefault: if StoreConfigFilesInSameDirectoryAsProgramByDefault:
# Just use the same directory as the program and forget about # Just use the same directory as the program and forget about
@ -140,15 +146,200 @@ def loadConfig():
if not sys.platform.startswith('win'): if not sys.platform.startswith('win'):
os.umask(0o077) os.umask(0o077)
BMConfigParser().save() BMConfigParser().save()
else:
updateConfig()
_loadTrustedPeer() _loadTrustedPeer()
def updateConfig():
settingsversion = BMConfigParser().getint(
'bitmessagesettings', 'settingsversion')
if settingsversion == 1:
BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'none')
BMConfigParser().set(
'bitmessagesettings', 'sockshostname', 'localhost')
BMConfigParser().set('bitmessagesettings', 'socksport', '9050')
BMConfigParser().set(
'bitmessagesettings', 'socksauthentication', 'false')
BMConfigParser().set('bitmessagesettings', 'socksusername', '')
BMConfigParser().set('bitmessagesettings', 'sockspassword', '')
BMConfigParser().set('bitmessagesettings', 'sockslisten', 'false')
BMConfigParser().set('bitmessagesettings', 'keysencrypted', 'false')
BMConfigParser().set(
'bitmessagesettings', 'messagesencrypted', 'false')
settingsversion = 2
# let class_sqlThread update SQL and continue
elif settingsversion == 4:
BMConfigParser().set(
'bitmessagesettings', 'defaultnoncetrialsperbyte',
str(defaults.networkDefaultProofOfWorkNonceTrialsPerByte))
BMConfigParser().set(
'bitmessagesettings', 'defaultpayloadlengthextrabytes',
str(defaults.networkDefaultPayloadLengthExtraBytes))
settingsversion = 5
if settingsversion == 5:
BMConfigParser().set(
'bitmessagesettings', 'maxacceptablenoncetrialsperbyte', '0')
BMConfigParser().set(
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', '0')
settingsversion = 7
# Raise the default required difficulty from 1 to 2
# With the change to protocol v3, this is obsolete.
# if settingsversion == 6:
# if int(shared.config.get(
# 'bitmessagesettings', 'defaultnoncetrialsperbyte'
# )) == defaults.networkDefaultProofOfWorkNonceTrialsPerByte:
# shared.config.set(
# 'bitmessagesettings', 'defaultnoncetrialsperbyte',
# str(
# defaults.networkDefaultProofOfWorkNonceTrialsPerByte
# * 2)
# )
# settingsversion = 7
if not BMConfigParser().has_option('bitmessagesettings', 'sockslisten'):
BMConfigParser().set('bitmessagesettings', 'sockslisten', 'false')
if not BMConfigParser().has_option('bitmessagesettings', 'userlocale'):
BMConfigParser().set('bitmessagesettings', 'userlocale', 'system')
if not BMConfigParser().has_option(
'bitmessagesettings', 'sendoutgoingconnections'):
BMConfigParser().set(
'bitmessagesettings', 'sendoutgoingconnections', 'True')
if not BMConfigParser().has_option(
'bitmessagesettings', 'useidenticons'):
BMConfigParser().set('bitmessagesettings', 'useidenticons', 'True')
if not BMConfigParser().has_option(
'bitmessagesettings', 'identiconsuffix'):
# acts as a salt
BMConfigParser().set(
'bitmessagesettings', 'identiconsuffix',
''.join(helper_random.randomchoice(
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
) for x in range(12)
)) # a twelve character pseudo-password to salt the identicons
# Add settings to support no longer resending messages after
# a certain period of time even if we never get an ack
if settingsversion == 7:
BMConfigParser().set(
'bitmessagesettings', 'stopresendingafterxdays', '')
BMConfigParser().set(
'bitmessagesettings', 'stopresendingafterxmonths', '')
settingsversion = 8
# With the change to protocol version 3, reset the user-settable
# difficulties to 1
if settingsversion == 8:
BMConfigParser().set(
'bitmessagesettings', 'defaultnoncetrialsperbyte',
str(defaults.networkDefaultProofOfWorkNonceTrialsPerByte))
BMConfigParser().set(
'bitmessagesettings', 'defaultpayloadlengthextrabytes',
str(defaults.networkDefaultPayloadLengthExtraBytes))
previousTotalDifficulty = int(
BMConfigParser().getint(
'bitmessagesettings', 'maxacceptablenoncetrialsperbyte')
) / 320
previousSmallMessageDifficulty = int(
BMConfigParser().getint(
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes')
) / 14000
BMConfigParser().set(
'bitmessagesettings', 'maxacceptablenoncetrialsperbyte',
str(previousTotalDifficulty * 1000))
BMConfigParser().set(
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes',
str(previousSmallMessageDifficulty * 1000))
settingsversion = 9
# Adjust the required POW values for each of this user's addresses
# to conform to protocol v3 norms.
if settingsversion == 9:
for addressInKeysFile in BMConfigParser().addresses():
try:
previousTotalDifficulty = float(
BMConfigParser().getint(
addressInKeysFile, 'noncetrialsperbyte')) / 320
previousSmallMessageDifficulty = float(
BMConfigParser().getint(
addressInKeysFile, 'payloadlengthextrabytes')) / 14000
if previousTotalDifficulty <= 2:
previousTotalDifficulty = 1
if previousSmallMessageDifficulty < 1:
previousSmallMessageDifficulty = 1
BMConfigParser().set(
addressInKeysFile, 'noncetrialsperbyte',
str(int(previousTotalDifficulty * 1000)))
BMConfigParser().set(
addressInKeysFile, 'payloadlengthextrabytes',
str(int(previousSmallMessageDifficulty * 1000)))
except Exception:
continue
BMConfigParser().set('bitmessagesettings', 'maxdownloadrate', '0')
BMConfigParser().set('bitmessagesettings', 'maxuploadrate', '0')
settingsversion = 10
# sanity check
if BMConfigParser().safeGetInt(
'bitmessagesettings', 'maxacceptablenoncetrialsperbyte') == 0:
BMConfigParser().set(
'bitmessagesettings', 'maxacceptablenoncetrialsperbyte',
str(
defaults.ridiculousDifficulty
* defaults.networkDefaultProofOfWorkNonceTrialsPerByte)
)
if BMConfigParser().safeGetInt(
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes'
) == 0:
BMConfigParser().set(
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes',
str(
defaults.ridiculousDifficulty
* defaults.networkDefaultPayloadLengthExtraBytes)
)
if not BMConfigParser().has_option('bitmessagesettings', 'onionhostname'):
BMConfigParser().set('bitmessagesettings', 'onionhostname', '')
if not BMConfigParser().has_option('bitmessagesettings', 'onionport'):
BMConfigParser().set('bitmessagesettings', 'onionport', '8444')
if not BMConfigParser().has_option('bitmessagesettings', 'onionbindip'):
BMConfigParser().set('bitmessagesettings', 'onionbindip', '127.0.0.1')
if not BMConfigParser().has_option('bitmessagesettings', 'smtpdeliver'):
BMConfigParser().set('bitmessagesettings', 'smtpdeliver', '')
if not BMConfigParser().has_option(
'bitmessagesettings', 'hidetrayconnectionnotifications'):
BMConfigParser().set(
'bitmessagesettings', 'hidetrayconnectionnotifications', 'false')
if BMConfigParser().safeGetInt(
'bitmessagesettings', 'maxoutboundconnections') < 1:
BMConfigParser().set(
'bitmessagesettings', 'maxoutboundconnections', '8')
print('WARNING: your maximum outbound connections must be a number.')
# TTL is now user-specifiable. Let's add an option to save
# whatever the user selects.
if not BMConfigParser().has_option('bitmessagesettings', 'ttl'):
BMConfigParser().set('bitmessagesettings', 'ttl', '367200')
BMConfigParser().set(
'bitmessagesettings', 'settingsversion', str(settingsversion))
BMConfigParser().save()
def isOurOperatingSystemLimitedToHavingVeryFewHalfOpenConnections(): def isOurOperatingSystemLimitedToHavingVeryFewHalfOpenConnections():
try: try:
if sys.platform[0:3] == "win": if sys.platform[0:3] == "win":
VER_THIS = StrictVersion(platform.version()) VER_THIS = StrictVersion(platform.version())
return StrictVersion("5.1.2600")<=VER_THIS and StrictVersion("6.0.6000")>=VER_THIS return (
StrictVersion("5.1.2600") <= VER_THIS and
StrictVersion("6.0.6000") >= VER_THIS
)
return False return False
except Exception: except Exception:
return False pass