rev194, Fix for ugly openSSL layer memory leak, memory usage test to openssl stability test

This commit is contained in:
HelloZeroNet 2015-05-27 16:58:36 +02:00
parent 9b7c21e14d
commit 94165176d3
5 changed files with 111 additions and 53 deletions

View file

@ -4,7 +4,7 @@ import ConfigParser
class Config(object):
def __init__(self):
self.version = "0.3.0"
self.rev = 193
self.rev = 194
self.parser = self.createArguments()
argv = sys.argv[:] # Copy command line arguments
argv = self.parseConfig(argv) # Add arguments from config file

View file

@ -74,9 +74,24 @@ def public_key_to_bc_address(public_key):
h160 = hash_160(public_key)
return hash_160_to_bc_address(h160)
def encode(val, base, minlen=0):
base, minlen = int(base), int(minlen)
code_string = ''.join([chr(x) for x in range(256)])
result = ""
while val > 0:
result = code_string[val % base] + result
val //= base
return code_string[0] * max(minlen - len(result), 0) + result
def num_to_var_int(x):
x = int(x)
if x < 253: return chr(x)
elif x < 65536: return chr(253)+encode(x, 256, 2)[::-1]
elif x < 4294967296: return chr(254) + encode(x, 256, 4)[::-1]
else: return chr(255) + encode(x, 256, 8)[::-1]
def msg_magic(message):
#return "\x18Bitcoin Signed Message:\n" + chr( len(message) ) + message
return "\x18Bitcoin Signed Message:\n" + chr( len(message) ) + message
return "\x18Bitcoin Signed Message:\n" + num_to_var_int( len(message) ) + message
def get_address(eckey):
size = ssl.i2o_ECPublicKey (eckey, 0)

View file

@ -10,6 +10,8 @@ import ctypes
import ctypes.util
import hashlib
import base64
import time
import logging
addrtype = 0
class _OpenSSL:
@ -17,6 +19,7 @@ class _OpenSSL:
Wrapper for OpenSSL using ctypes
"""
def __init__(self, library):
self.time_opened = time.time()
"""
Build the wrapper
"""
@ -172,14 +175,23 @@ class _OpenSSL:
self.i2o_ECPublicKey.restype = ctypes.c_void_p
self.i2o_ECPublicKey.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
self.BN_CTX_free = self._lib.BN_CTX_free
self.BN_CTX_free.restype = None
self.BN_CTX_free.argtypes = [ctypes.c_void_p]
self.EC_POINT_free = self._lib.EC_POINT_free
self.EC_POINT_free.restype = None
self.EC_POINT_free.argtypes = [ctypes.c_void_p]
def openLibrary():
global ssl
try:
ssl = _OpenSSL("src/lib/opensslVerify/libeay32.dll")
except:
ssl = _OpenSSL(ctypes.util.find_library('ssl') or ctypes.util.find_library('crypto') or 'libeay32')
openLibrary()
openssl_version = "%.9X" % ssl._lib.SSLeay()
NID_secp256k1 = 714
@ -296,7 +308,9 @@ def SetCompactSignature(pkey, hash, signature):
def ECDSA_SIG_recover_key_GFp(eckey, r, s, msg, msglen, recid, check):
n = 0
i = recid / 2
ctx = R = O = Q = None
try:
group = ssl.EC_KEY_get0_group(eckey)
ctx = ssl.BN_CTX_new()
ssl.BN_CTX_start(ctx)
@ -339,8 +353,13 @@ def ECDSA_SIG_recover_key_GFp(eckey, r, s, msg, msglen, recid, check):
ssl.EC_POINT_mul(group, Q, eor, R, sor, ctx)
ssl.EC_KEY_set_public_key(eckey, Q)
return eckey
finally:
if ctx: ssl.BN_CTX_free(ctx)
if R: ssl.EC_POINT_free(R)
if O: ssl.EC_POINT_free(O)
if Q: ssl.EC_POINT_free(Q)
def close():
def closeLibrary():
import _ctypes
if "FreeLibrary" in dir(_ctypes):
_ctypes.FreeLibrary(ssl._lib._handle)
@ -354,7 +373,12 @@ def getMessagePubkey(message, sig):
size = ssl.i2o_ECPublicKey (eckey, 0)
mb = ctypes.create_string_buffer (size)
ssl.i2o_ECPublicKey (eckey, ctypes.byref (ctypes.pointer (mb)))
return mb.raw
pub = mb.raw
if time.time()-ssl.time_opened>60*5: # Reopen every 5 min
logging.debug("Reopening OpenSSL...")
closeLibrary()
openLibrary()
return pub
def test():
sign = "HGbib2kv9gm9IJjDt1FXbXFczZi35u0rZR3iPUIt5GglDDCeIQ7v8eYXVNIaLoJRI4URGZrhwmsYQ9aVtRTnTfQ="

View file

@ -1,16 +1,35 @@
import opensslVerify, gevent, time
from gevent import monkey; monkey.patch_all(thread=False, ssl=False)
from gevent import monkey
monkey.patch_all(thread=False, ssl=False)
def test():
data = "A"*1024
sign = "G2Jo8dDa+jqvJipft9E3kfrAxjESWLBpVtuGIiEBCD/UUyHmRMYNqnlWeOiaHHpja5LOP+U5CanRALfOjCSYIa8="
for i in range(5*1000):
for i in range(2*1000):
if i%1000 == 0:
print i, len(data)
data += data+"A"
#data += data+"A"
time.sleep(0)
pub = opensslVerify.getMessagePubkey(data, sign)
print repr(pub), len(data)
while 1:
s = time.time()
gevent.joinall([gevent.spawn(test), gevent.spawn(test)])
try:
import psutil, os
process = psutil.Process(os.getpid())
print "Mem:", process.get_memory_info()[0] / float(2 ** 20)
except:
pass
raw_input("finished, in %.2fs, check memory usage" % (time.time()-s))
opensslVerify.close()
opensslVerify.open()
try:
import psutil, os
process = psutil.Process(os.getpid())
print "Mem:", process.get_memory_info()[0] / float(2 ** 20)
except:
pass
raw_input("closed and openssl, check memory again, press enter to start again")

View file

@ -13,7 +13,7 @@ def main():
# Try cleanup openssl
try:
if "lib.opensslVerify" in sys.modules:
sys.modules["lib.opensslVerify"].opensslVerify.close()
sys.modules["lib.opensslVerify"].opensslVerify.closeLibrary()
except Exception, err:
print "Error closing openssl", err