generated from dopt-python/py311-cython
Include prototyping steps #1
File diff suppressed because it is too large
Load Diff
@ -16,118 +16,54 @@ import dopt_basics.datetime
|
|||||||
from polluck_blockchain.block cimport Block
|
from polluck_blockchain.block cimport Block
|
||||||
from libcpp.unordered_map cimport unordered_map
|
from libcpp.unordered_map cimport unordered_map
|
||||||
from libcpp.string cimport string
|
from libcpp.string cimport string
|
||||||
|
from libc.stdint cimport uint64_t
|
||||||
|
|
||||||
ctypedef unsigned long ULong
|
ctypedef unsigned long ULong
|
||||||
|
ctypedef unordered_map[uint64_t, Block*] BcHashmap
|
||||||
# cdef struct PyStringC:
|
|
||||||
# char* ptr
|
|
||||||
# Py_ssize_t length
|
|
||||||
|
|
||||||
|
|
||||||
# cdef PyStringC_to_unicode(PyStringC string):
|
|
||||||
# return string.ptr[: string.length].decode("UTF-8", "strict")
|
|
||||||
|
|
||||||
|
|
||||||
# cdef PyStringC_to_bytes(PyStringC string):
|
|
||||||
# return <bytes>string.ptr[: string.length]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cdef timestamp_to_datetime(double ts):
|
cdef timestamp_to_datetime(double ts):
|
||||||
return datetime.datetime.fromtimestamp(ts, dopt_basics.datetime.TIMEZONE_UTC)
|
return datetime.datetime.fromtimestamp(ts, dopt_basics.datetime.TIMEZONE_UTC)
|
||||||
|
|
||||||
|
|
||||||
# cdef class StringHolder:
|
|
||||||
# cdef readonly PyStringC c
|
|
||||||
# cdef object _py_data
|
|
||||||
|
|
||||||
# def __cinit__(self, data: str):
|
|
||||||
# """accepting Python str
|
|
||||||
|
|
||||||
# Parameters
|
|
||||||
# ----------
|
|
||||||
# data : str
|
|
||||||
# _description_
|
|
||||||
# """
|
|
||||||
# if not isinstance(data, str):
|
|
||||||
# raise TypeError("Data not 'str'")
|
|
||||||
|
|
||||||
# self._py_data = data.encode("UTF-8")
|
|
||||||
# self.c = PyStringC(self._py_data, len(self._py_data))
|
|
||||||
|
|
||||||
# @property
|
|
||||||
# def py_string(self):
|
|
||||||
# return PyStringC_to_unicode(self.c)
|
|
||||||
|
|
||||||
# @property
|
|
||||||
# def py_bytes(self):
|
|
||||||
# return PyStringC_to_bytes(self.c)
|
|
||||||
|
|
||||||
|
|
||||||
# BlockC = cython.struct(
|
|
||||||
# index=cython.ulonglong,
|
|
||||||
# timestamp=cython.double,
|
|
||||||
# data=PyStringC,
|
|
||||||
# previous_hash=PyStringC,
|
|
||||||
# nonce=cython.ulonglong,
|
|
||||||
# )
|
|
||||||
|
|
||||||
|
|
||||||
cdef float_to_bytes(double num):
|
cdef float_to_bytes(double num):
|
||||||
return struct.pack(">d", num)
|
return struct.pack(">d", num)
|
||||||
|
|
||||||
# cdef struct BlockC:
|
|
||||||
# ULong _index
|
|
||||||
# double _timestamp
|
|
||||||
# string _data
|
|
||||||
# string _prev_hash
|
|
||||||
# ULong _nonce
|
|
||||||
# string _hash
|
|
||||||
|
|
||||||
|
cdef class PyBlock:
|
||||||
cdef class BlockPy:
|
|
||||||
cdef:
|
cdef:
|
||||||
ULong _index
|
# ULong _index
|
||||||
double _timestamp
|
# double _timestamp
|
||||||
string _data
|
# string _data
|
||||||
string _prev_hash
|
# string _prev_hash
|
||||||
ULong _nonce
|
# ULong _nonce
|
||||||
string _hash
|
# string _hash
|
||||||
Block* Block
|
Block *BlockC
|
||||||
|
bint ptr_owner
|
||||||
|
|
||||||
def __cinit__(self,
|
def __cinit__(self,
|
||||||
index: int,
|
index,
|
||||||
data: str,
|
nonce,
|
||||||
previous_hash: str,
|
data,
|
||||||
nonce: int,
|
previous_hash,
|
||||||
|
from_ptr=False,
|
||||||
):
|
):
|
||||||
self.Block = new Block(
|
self.ptr_owner = False
|
||||||
index,
|
if not from_ptr:
|
||||||
datetime.datetime(2025, 12, 1, 12, 0, 0).timestamp(),
|
self.BlockC = new Block(
|
||||||
nonce,
|
index,
|
||||||
data.encode("UTF-8"),
|
datetime.datetime(2025, 12, 1, 12, 0, 0).timestamp(),
|
||||||
previous_hash.encode("UTF-8"),
|
nonce,
|
||||||
"".encode("UTF-8"),
|
data.encode("UTF-8"),
|
||||||
)
|
previous_hash.encode("UTF-8"),
|
||||||
|
"".encode("UTF-8"),
|
||||||
|
)
|
||||||
|
if self.BlockC == NULL:
|
||||||
|
raise MemoryError("Allocation of block object failed")
|
||||||
|
|
||||||
def get_data(self):
|
self.ptr_owner = True
|
||||||
return self.Block.data.decode("UTF-8")
|
|
||||||
|
|
||||||
# def __init__(
|
def __init__(self, *args, **kwargs):
|
||||||
# self,
|
pass
|
||||||
# index: int,
|
|
||||||
# data: str,
|
|
||||||
# previous_hash: str,
|
|
||||||
# nonce: int,
|
|
||||||
# ):
|
|
||||||
# self.C = new BlockC(
|
|
||||||
# index,
|
|
||||||
# datetime.datetime(2025, 12, 1, 12, 0, 0).timestamp(),
|
|
||||||
# data.encode("UTF-8"),
|
|
||||||
# previous_hash.encode("UTF-8"),
|
|
||||||
# nonce,
|
|
||||||
# "".encode("UTF-8"),
|
|
||||||
# )
|
|
||||||
# self._index = index
|
# self._index = index
|
||||||
# # self._timestamp = dopt_basics.datetime.current_time_tz().timestamp()
|
# # self._timestamp = dopt_basics.datetime.current_time_tz().timestamp()
|
||||||
# self._timestamp = datetime.datetime(2025, 12, 1, 12, 0, 0).timestamp()
|
# self._timestamp = datetime.datetime(2025, 12, 1, 12, 0, 0).timestamp()
|
||||||
@ -135,6 +71,26 @@ cdef class BlockPy:
|
|||||||
# self._prev_hash = previous_hash.encode("UTF-8")
|
# self._prev_hash = previous_hash.encode("UTF-8")
|
||||||
# self._nonce = nonce
|
# self._nonce = nonce
|
||||||
# self._hash = "".encode("UTF-8")
|
# self._hash = "".encode("UTF-8")
|
||||||
|
|
||||||
|
def __dealloc__(self):
|
||||||
|
if self.BlockC is not NULL and self.ptr_owner is True:
|
||||||
|
del self.BlockC
|
||||||
|
self.BlockC = NULL
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
cdef PyBlock from_ptr(Block *block, bint owner=False):
|
||||||
|
cdef PyBlock py_block = PyBlock.__new__(
|
||||||
|
PyBlock,
|
||||||
|
block.index,
|
||||||
|
block.nonce,
|
||||||
|
block.data,
|
||||||
|
block.prev_hash,
|
||||||
|
True,
|
||||||
|
)
|
||||||
|
py_block.BlockC = block
|
||||||
|
py_block.ptr_owner = owner
|
||||||
|
|
||||||
|
return py_block
|
||||||
|
|
||||||
# cpdef _perform_hash(self):
|
# cpdef _perform_hash(self):
|
||||||
# parts = bytearray()
|
# parts = bytearray()
|
||||||
@ -152,51 +108,124 @@ cdef class BlockPy:
|
|||||||
# def compute_hash(self):
|
# def compute_hash(self):
|
||||||
# return self._perform_hash().hexdigest()
|
# return self._perform_hash().hexdigest()
|
||||||
|
|
||||||
# # Python public API
|
# Python public API
|
||||||
# @property
|
@property
|
||||||
# def index(self):
|
def index(self):
|
||||||
# return self._index
|
return self.BlockC.index
|
||||||
|
|
||||||
# @property
|
@property
|
||||||
# def timestamp(self):
|
def timestamp(self):
|
||||||
# return timestamp_to_datetime(self._timestamp)
|
return timestamp_to_datetime(self.BlockC.timestamp)
|
||||||
|
|
||||||
# @property
|
@property
|
||||||
# def data(self):
|
def data(self):
|
||||||
# return self._data.decode("UTF-8")
|
return self.BlockC.data.decode("UTF-8")
|
||||||
|
|
||||||
# @property
|
@property
|
||||||
# def prev_hash(self):
|
def prev_hash(self):
|
||||||
# return self._prev_hash.decode("UTF-8")
|
return self.BlockC.prev_hash.decode("UTF-8")
|
||||||
|
|
||||||
# @property
|
@property
|
||||||
# def nonce(self):
|
def nonce(self):
|
||||||
# return self._nonce
|
return self.BlockC.nonce
|
||||||
|
|
||||||
# @nonce.setter
|
# @nonce.setter
|
||||||
# def nonce(self, value: int):
|
# def nonce(self, value: int):
|
||||||
# self._nonce = value
|
# self._nonce = value
|
||||||
|
|
||||||
# @property
|
@property
|
||||||
# def hash(self):
|
def hash(self):
|
||||||
# return self._hash.decode("UTF-8")
|
return self.BlockC.hash.decode("UTF-8")
|
||||||
|
|
||||||
# @hash.setter
|
# @hash.setter
|
||||||
# def hash(self, value: str):
|
# def hash(self, value):
|
||||||
# if not isinstance(value, str):
|
# if not isinstance(value, str):
|
||||||
# raise TypeError("No string")
|
# raise TypeError("No string")
|
||||||
# self._hash = value.encode("UTF-8")
|
# self._hash = value.encode("UTF-8")
|
||||||
|
|
||||||
|
# cdef void add_block(BcHashmap *map, Block *block):
|
||||||
|
# map[block.index] = block
|
||||||
|
|
||||||
# cdef class Blockchain:
|
|
||||||
# cdef int _difficulty
|
|
||||||
# cdef size_t _index
|
|
||||||
# cdef unordered_map[size_t, int] _chain
|
|
||||||
|
|
||||||
# def __cinit__(self):
|
cdef class Blockchain:
|
||||||
# self._difficulty = 1
|
cdef int _difficulty
|
||||||
# self._index = <size_t>0
|
cdef uint64_t _index
|
||||||
# # self._chain = new unordered_map[size_t, Block]()
|
cdef BcHashmap *_chain
|
||||||
|
cdef bint _genesis_done
|
||||||
|
|
||||||
|
def __cinit__(self):
|
||||||
|
self._difficulty = 1
|
||||||
|
self._index = <uint64_t>0
|
||||||
|
self._genesis_done = <bint>0
|
||||||
|
self._chain = new unordered_map[uint64_t, Block*]()
|
||||||
|
if self._chain is NULL:
|
||||||
|
raise MemoryError("Could not allocate hasmap")
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __dealloc__(self):
|
||||||
|
if self._chain is not NULL:
|
||||||
|
del self._chain
|
||||||
|
self._chain = NULL
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return self._index + 1
|
||||||
|
|
||||||
|
@property
|
||||||
|
def genesis_done(self):
|
||||||
|
return self._genesis_done
|
||||||
|
|
||||||
|
@property
|
||||||
|
def index(self):
|
||||||
|
return self._index
|
||||||
|
|
||||||
|
# TODO error handling
|
||||||
|
cdef Block* get_block_c(self, uint64_t idx):
|
||||||
|
return self._chain[0][idx]
|
||||||
|
|
||||||
|
def get_block(self, idx):
|
||||||
|
if idx < 0 or idx > self._index:
|
||||||
|
raise IndexError("Index value is out of bounds")
|
||||||
|
|
||||||
|
cdef Block *block = self.get_block_c(idx)
|
||||||
|
return PyBlock.from_ptr(block, owner=False)
|
||||||
|
|
||||||
|
cdef void add_block(self, Block *block):
|
||||||
|
self._chain[0][block.index] = block
|
||||||
|
if self._genesis_done:
|
||||||
|
self._index += 1
|
||||||
|
|
||||||
|
def create_genesis_block(self):
|
||||||
|
cdef Block *block = new Block(
|
||||||
|
self._index,
|
||||||
|
datetime.datetime(2025, 12, 1, 12, 0, 0).timestamp(),
|
||||||
|
0,
|
||||||
|
"Genesis Block".encode("UTF-8"),
|
||||||
|
"0".encode("UTF-8"),
|
||||||
|
"".encode("UTF-8"),
|
||||||
|
)
|
||||||
|
block.hash = <string>"dummy hash".encode("UTF-8")
|
||||||
|
self.add_block(block)
|
||||||
|
self._genesis_done = <bint>1
|
||||||
|
|
||||||
|
def new_block(self, data):
|
||||||
|
if not self._genesis_done:
|
||||||
|
raise RuntimeError("Create a genesis block first.")
|
||||||
|
|
||||||
|
cdef Block *prev_block = self.get_block_c(self._index)
|
||||||
|
cdef string prev_hash = prev_block.prev_hash
|
||||||
|
cdef uint64_t new_idx = self._index + 1
|
||||||
|
|
||||||
|
cdef Block *block = new Block(
|
||||||
|
new_idx,
|
||||||
|
datetime.datetime(2025, 12, 1, 12, 0, 0).timestamp(),
|
||||||
|
0,
|
||||||
|
data.encode("UTF-8"),
|
||||||
|
prev_hash,
|
||||||
|
"".encode("UTF-8"),
|
||||||
|
)
|
||||||
|
self.add_block(block)
|
||||||
|
|
||||||
# def __init__(
|
# def __init__(
|
||||||
# self,
|
# self,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user