generated from dopt-python/py311-cython
Include prototyping steps #1
4
setup.py
4
setup.py
@ -60,8 +60,8 @@ linker_args: list[str] = []
|
|||||||
|
|
||||||
|
|
||||||
if sys.platform.startswith("win") and not DEBUG:
|
if sys.platform.startswith("win") and not DEBUG:
|
||||||
c_args = ("/O2", "/GL", "/Gy")
|
c_args = ("/O2", "/GL", "/Gy", "/openmp:llvm")
|
||||||
l_args = ("/LTCG", "/OPT:REF", "/OPT:ICF")
|
l_args = ("/LTCG", "/OPT:REF", "/OPT:ICF", "/openmp:llvm")
|
||||||
else:
|
else:
|
||||||
c_args = tuple()
|
c_args = tuple()
|
||||||
l_args = tuple()
|
l_args = tuple()
|
||||||
|
|||||||
@ -4,12 +4,11 @@ cdef extern from "openssl/evp.h":
|
|||||||
pass
|
pass
|
||||||
ctypedef struct EVP_MD:
|
ctypedef struct EVP_MD:
|
||||||
pass
|
pass
|
||||||
EVP_MD_CTX *EVP_MD_CTX_new()
|
EVP_MD_CTX *EVP_MD_CTX_new() nogil
|
||||||
void EVP_MD_CTX_free(EVP_MD_CTX *)
|
void EVP_MD_CTX_free(EVP_MD_CTX *) nogil
|
||||||
const EVP_MD *EVP_sha256()
|
const EVP_MD *EVP_sha256() nogil
|
||||||
int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, void *impl)
|
int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, void *impl) nogil
|
||||||
int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt)
|
int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt) nogil
|
||||||
int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md,
|
int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s) nogil
|
||||||
unsigned int *s)
|
int EVP_MD_size(const EVP_MD *md) nogil
|
||||||
int EVP_MD_size(const EVP_MD *md)
|
int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) nogil
|
||||||
int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -21,6 +21,7 @@ from libc.stdlib cimport malloc, free
|
|||||||
from libc.string cimport memcpy
|
from libc.string cimport memcpy
|
||||||
from cython.operator import postincrement, dereference
|
from cython.operator import postincrement, dereference
|
||||||
cimport polluck_blockchain.openssl_evp as ossl
|
cimport polluck_blockchain.openssl_evp as ossl
|
||||||
|
from cython.parallel cimport prange
|
||||||
|
|
||||||
|
|
||||||
ctypedef unsigned long ULong
|
ctypedef unsigned long ULong
|
||||||
@ -57,14 +58,35 @@ cdef int serialize_uint64(unsigned char* out, unsigned long long v) except -1 no
|
|||||||
# unsigned char *ptr
|
# unsigned char *ptr
|
||||||
# size_t size
|
# size_t size
|
||||||
|
|
||||||
|
cdef const size_t NONCE_OFFSET = <size_t>16
|
||||||
|
|
||||||
|
cdef inline bint has_leading_zero_bits(const unsigned char *digest, int num_bits) nogil:
|
||||||
|
cdef int i, full_bytes = num_bits // 8
|
||||||
|
cdef int rem_bits = num_bits % 8
|
||||||
|
|
||||||
|
for i in range(full_bytes):
|
||||||
|
if digest[i] != 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if rem_bits:
|
||||||
|
if digest[full_bytes] >> (8 - rem_bits) != 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
cdef inline bint has_leading_zero_bytes(const unsigned char *digest, int num_bytes) nogil:
|
||||||
|
cdef int i, full_bytes = num_bytes // 8
|
||||||
|
cdef int rem_bits = num_bytes % 8
|
||||||
|
|
||||||
|
for i in range(num_bytes):
|
||||||
|
if digest[i] != 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
cdef class PyBlock:
|
cdef class PyBlock:
|
||||||
cdef:
|
cdef:
|
||||||
# ULong _index
|
|
||||||
# double _timestamp
|
|
||||||
# string _data
|
|
||||||
# string _prev_hash
|
|
||||||
# ULong _nonce
|
|
||||||
# string _hash
|
|
||||||
Block *BlockC
|
Block *BlockC
|
||||||
bint ptr_owner
|
bint ptr_owner
|
||||||
|
|
||||||
@ -164,7 +186,7 @@ cdef class PyBlock:
|
|||||||
def hash(self):
|
def hash(self):
|
||||||
return self.BlockC.hash.decode("UTF-8")
|
return self.BlockC.hash.decode("UTF-8")
|
||||||
|
|
||||||
cdef unsigned char* bytes_serialize_c(self, size_t *size):
|
cdef unsigned char* bytes_serialize_c(self, size_t *size) nogil:
|
||||||
cdef:
|
cdef:
|
||||||
size_t total_len
|
size_t total_len
|
||||||
unsigned char* buf
|
unsigned char* buf
|
||||||
@ -179,7 +201,7 @@ cdef class PyBlock:
|
|||||||
buf = <unsigned char*>malloc(size[0] * sizeof(unsigned char))
|
buf = <unsigned char*>malloc(size[0] * sizeof(unsigned char))
|
||||||
|
|
||||||
if buf == NULL:
|
if buf == NULL:
|
||||||
raise MemoryError()
|
return NULL
|
||||||
|
|
||||||
serialize_uint64(buf + pos, self.BlockC.index)
|
serialize_uint64(buf + pos, self.BlockC.index)
|
||||||
pos += 8
|
pos += 8
|
||||||
@ -204,21 +226,13 @@ cdef class PyBlock:
|
|||||||
|
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
def bytes_serialize(self):
|
cdef unsigned char* digest(self, unsigned char *data, size_t data_size, size_t *digest_size) nogil:
|
||||||
cdef:
|
|
||||||
unsigned char *serialize_res
|
|
||||||
size_t serialize_size
|
|
||||||
try:
|
|
||||||
serialize_res = self.bytes_serialize_c(&serialize_size)
|
|
||||||
return serialize_res[:serialize_size]
|
|
||||||
finally:
|
|
||||||
free(serialize_res)
|
|
||||||
|
|
||||||
cdef unsigned char* digest(self, unsigned char *data, size_t data_size, size_t *digest_size):
|
|
||||||
cdef ossl.EVP_MD_CTX *ctx = ossl.EVP_MD_CTX_new()
|
cdef ossl.EVP_MD_CTX *ctx = ossl.EVP_MD_CTX_new()
|
||||||
if ctx == NULL:
|
if ctx == NULL:
|
||||||
raise MemoryError()
|
return NULL
|
||||||
cdef const ossl.EVP_MD *algo = ossl.EVP_sha256()
|
cdef const ossl.EVP_MD *algo = ossl.EVP_sha256()
|
||||||
|
if algo == NULL:
|
||||||
|
return NULL
|
||||||
|
|
||||||
cdef:
|
cdef:
|
||||||
unsigned char* digest
|
unsigned char* digest
|
||||||
@ -237,14 +251,74 @@ cdef class PyBlock:
|
|||||||
|
|
||||||
return digest
|
return digest
|
||||||
|
|
||||||
cdef unsigned char* perform_hash_c(self, size_t *digest_size):
|
def bytes_serialize(self):
|
||||||
|
cdef:
|
||||||
|
unsigned char *serialize_res
|
||||||
|
size_t serialize_size
|
||||||
|
try:
|
||||||
|
serialize_res = self.bytes_serialize_c(&serialize_size)
|
||||||
|
return serialize_res[:serialize_size]
|
||||||
|
finally:
|
||||||
|
free(serialize_res)
|
||||||
|
|
||||||
|
cpdef mine(self, unsigned int difficulty, unsigned int max_nonce=0xFFFFFFFF):
|
||||||
|
cdef:
|
||||||
|
unsigned char *serial_buf
|
||||||
|
size_t serialize_size
|
||||||
|
unsigned char *digest
|
||||||
|
size_t digest_size
|
||||||
|
bint nonce_found = False
|
||||||
|
int nonce, nonce_solution = 0
|
||||||
|
bint *p_nonce_found = &nonce_found
|
||||||
|
int *p_nonce_solution = &nonce_solution
|
||||||
|
|
||||||
|
serial_buf = self.bytes_serialize_c(&serialize_size)
|
||||||
|
|
||||||
|
# for nonce in prange(max_nonce, nogil=True, schedule="static", num_threads=16):
|
||||||
|
# if p_nonce_found[0]:
|
||||||
|
# break
|
||||||
|
|
||||||
|
# serialize_uint64(serial_buf + NONCE_OFFSET, <uint64_t>nonce)
|
||||||
|
# digest = self.digest(serial_buf, serialize_size, &digest_size)
|
||||||
|
|
||||||
|
# if has_leading_zero_bits(digest, difficulty):
|
||||||
|
# p_nonce_found[0] = True
|
||||||
|
# p_nonce_solution[0] = nonce
|
||||||
|
# break
|
||||||
|
|
||||||
|
# free(digest)
|
||||||
|
|
||||||
|
with nogil:
|
||||||
|
for nonce in range(max_nonce):
|
||||||
|
serialize_uint64(serial_buf + NONCE_OFFSET, <uint64_t>nonce)
|
||||||
|
digest = self.digest(serial_buf, serialize_size, &digest_size)
|
||||||
|
|
||||||
|
if has_leading_zero_bits(digest, difficulty):
|
||||||
|
nonce_found = True
|
||||||
|
nonce_solution = nonce
|
||||||
|
break
|
||||||
|
|
||||||
|
free(digest)
|
||||||
|
|
||||||
|
if not nonce_found:
|
||||||
|
raise RuntimeError("No valid nonce found")
|
||||||
|
|
||||||
|
self.BlockC.nonce = <uint64_t>nonce_solution
|
||||||
|
|
||||||
|
cdef unsigned char* perform_hash_c(self, size_t *digest_size) nogil:
|
||||||
cdef:
|
cdef:
|
||||||
unsigned char *serialize_res
|
unsigned char *serialize_res
|
||||||
size_t serialize_size
|
size_t serialize_size
|
||||||
unsigned char *digest
|
unsigned char *digest
|
||||||
|
|
||||||
serialize_res = self.bytes_serialize_c(&serialize_size)
|
serialize_res = self.bytes_serialize_c(&serialize_size)
|
||||||
|
if serialize_res == NULL:
|
||||||
|
return NULL
|
||||||
digest = self.digest(serialize_res, serialize_size, digest_size)
|
digest = self.digest(serialize_res, serialize_size, digest_size)
|
||||||
|
if digest == NULL:
|
||||||
|
return NULL
|
||||||
|
|
||||||
|
free(serialize_res)
|
||||||
|
|
||||||
return digest
|
return digest
|
||||||
|
|
||||||
@ -255,6 +329,8 @@ cdef class PyBlock:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
digest = self.perform_hash_c(&digest_size)
|
digest = self.perform_hash_c(&digest_size)
|
||||||
|
if digest == NULL:
|
||||||
|
raise MemoryError()
|
||||||
self.BlockC.hash = bytes(digest[:digest_size]).hex().encode("UTF-8")
|
self.BlockC.hash = bytes(digest[:digest_size]).hex().encode("UTF-8")
|
||||||
finally:
|
finally:
|
||||||
free(digest)
|
free(digest)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user