support for encoding and decoding variable length addresses #450

Merged
Atheros1 merged 7 commits from master into master 2013-08-26 21:29:30 +02:00
5 changed files with 24 additions and 8 deletions

View File

@ -97,13 +97,18 @@ def calculateInventoryHash(data):
return sha2.digest()[0:32]
def encodeAddress(version,stream,ripe):
if version >= 2:
if version >= 2 and version < 4:
if len(ripe) != 20:
raise Exception("Programming error in encodeAddress: The length of a given ripe hash was not 20.")
if ripe[:2] == '\x00\x00':
ripe = ripe[2:]
elif ripe[:1] == '\x00':
ripe = ripe[1:]
elif version == 4:
if len(ripe) != 20:
raise Exception("Programming error in encodeAddress: The length of a given ripe hash was not 20.")
ripe = ripe.lstrip('\x00')
a = encodeVarint(version) + encodeVarint(stream) + ripe
sha = hashlib.new('sha512')
sha.update(a)
@ -164,7 +169,7 @@ def decodeAddress(address):
#print 'addressVersionNumber', addressVersionNumber
#print 'bytesUsedByVersionNumber', bytesUsedByVersionNumber
if addressVersionNumber > 3:
if addressVersionNumber > 4:
print 'cannot decode address version numbers this high'
status = 'versiontoohigh'
return status,0,0,0
@ -191,6 +196,15 @@ def decodeAddress(address):
return 'ripetoolong',0,0,0
else:
return 'otherproblem',0,0,0
elif addressVersionNumber == 4:
if len(data[bytesUsedByVersionNumber+bytesUsedByStreamNumber:-4]) > 20:
return 'ripetoolong',0,0,0
elif len(data[bytesUsedByVersionNumber+bytesUsedByStreamNumber:-4]) < 4:
return 'ripetooshort',0,0,0
else:
x00string = '\x00' * (20 - len(data[bytesUsedByVersionNumber+bytesUsedByStreamNumber:-4]))
return status,addressVersionNumber,streamNumber,x00string+data[bytesUsedByVersionNumber+bytesUsedByStreamNumber:-4]
def addBMIfNotPresent(address):
address = str(address).strip()

View File

@ -875,8 +875,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
except APIError as e:
return str(e)
except Exception as e:
logger.critical(e)
logger.critical(sys.exc_info()[0])
logger.exception(e)
return "API Error 0021: Unexpected API Failure - %s" % str(e)
# This thread, of which there is only one, runs the API.

View File

@ -1220,7 +1220,7 @@ class receiveDataThread(threading.Thread):
if addressVersion == 0:
print '(Within processpubkey) addressVersion of 0 doesn\'t make sense.'
return
if addressVersion >= 4 or addressVersion == 1:
if addressVersion > 3 or addressVersion == 1:
with shared.printLock:
print 'This version of Bitmessage cannot handle version', addressVersion, 'addresses.'

View File

@ -535,6 +535,8 @@ class singleWorker(threading.Thread):
pubEncryptionKeyBase256 = pubkeyPayload[
readPosition:readPosition + 64]
readPosition += 64
# Let us fetch the amount of work required by the recipient.
if toAddressVersionNumber == 2:
requiredAverageProofOfWorkNonceTrialsPerByte = shared.networkDefaultProofOfWorkNonceTrialsPerByte
requiredPayloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes
@ -569,6 +571,7 @@ class singleWorker(threading.Thread):
requiredPayloadLengthExtraBytes) / shared.networkDefaultPayloadLengthExtraBytes)).arg(unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8')))))
continue
embeddedTime = pack('>Q', (int(time.time()) + random.randrange(
-300, 300))) # the current time plus or minus five minutes. We will use this time both for our message and for the ackdata packed within our message.
if fromAddressVersionNumber == 2:

View File

@ -20,6 +20,7 @@ import sys
import stat
import threading
import time
from os import path, environ
# Project imports.
from addresses import *
@ -125,7 +126,6 @@ def assembleVersionMessage(remoteHost, remotePort, myStreamNumber):
def lookupAppdataFolder():
APPNAME = "PyBitmessage"
from os import path, environ
if sys.platform == 'darwin':
if "HOME" in environ:
dataFolder = path.join(os.environ["HOME"], "Library/Application Support/", APPNAME) + '/'
@ -239,7 +239,7 @@ def reloadMyAddressHashes():
if isEnabled:
hasEnabledKeys = True
status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile)
if addressVersionNumber == 2 or addressVersionNumber == 3:
if addressVersionNumber == 2 or addressVersionNumber == 3 or addressVersionNumber == 4:
# Returns a simple 32 bytes of information encoded in 64 Hex characters,
# or null if there was an error.
privEncryptionKey = decodeWalletImportFormat(
@ -250,7 +250,7 @@ def reloadMyAddressHashes():
myAddressesByHash[hash] = addressInKeysFile
else:
logger.error('Error in reloadMyAddressHashes: Can\'t handle address versions other than 2 or 3.\n')
logger.error('Error in reloadMyAddressHashes: Can\'t handle address versions other than 2, 3, or 4.\n')
if not keyfileSecure:
fixSensitiveFilePermissions(appdata + 'keys.dat', hasEnabledKeys)