generated from dopt-python/py311-cython
C level serialisation
This commit is contained in:
parent
61753f03d8
commit
9f73e2c051
@ -11,6 +11,6 @@ struct Block {
|
|||||||
std::string hash;
|
std::string hash;
|
||||||
|
|
||||||
Block() : index(0), timestamp(0), nonce(0), data(), prev_hash(), hash() {}
|
Block() : index(0), timestamp(0), nonce(0), data(), prev_hash(), hash() {}
|
||||||
Block(uint64_t idx, double ts, uint64_t n, const std::string& d, const std::string& pre_h, const std::string& h)
|
Block(uint64_t idx, uint64_t ts, uint64_t n, const std::string& d, const std::string& pre_h, const std::string& h)
|
||||||
: index(idx), timestamp(ts), nonce(n), data(d), prev_hash(pre_h), hash(h) {}
|
: index(idx), timestamp(ts), nonce(n), data(d), prev_hash(pre_h), hash(h) {}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -4,7 +4,7 @@ from libc cimport stdint
|
|||||||
cdef extern from "block.hpp" namespace "":
|
cdef extern from "block.hpp" namespace "":
|
||||||
cdef cppclass Block:
|
cdef cppclass Block:
|
||||||
stdint.uint64_t index
|
stdint.uint64_t index
|
||||||
double timestamp
|
stdint.uint64_t timestamp
|
||||||
stdint.uint64_t nonce
|
stdint.uint64_t nonce
|
||||||
string data
|
string data
|
||||||
string prev_hash
|
string prev_hash
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -17,18 +17,40 @@ 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
|
from libc.stdint cimport uint64_t
|
||||||
|
from libc.stdlib cimport malloc, free
|
||||||
|
from libc.string cimport memcpy
|
||||||
from cython.operator import postincrement, dereference
|
from cython.operator import postincrement, dereference
|
||||||
|
|
||||||
|
|
||||||
ctypedef unsigned long ULong
|
ctypedef unsigned long ULong
|
||||||
ctypedef unordered_map[uint64_t, Block*] BcHashmap
|
ctypedef unordered_map[uint64_t, Block*] BcHashmap
|
||||||
|
|
||||||
cdef timestamp_to_datetime(double ts):
|
cdef timestamp_to_datetime(uint64_t ts):
|
||||||
return datetime.datetime.fromtimestamp(ts, dopt_basics.datetime.TIMEZONE_UTC)
|
return datetime.datetime.fromtimestamp(float(ts), dopt_basics.datetime.TIMEZONE_UTC)
|
||||||
|
|
||||||
|
|
||||||
cdef float_to_bytes(double num):
|
# cdef float_to_bytes(double num):
|
||||||
return struct.pack(">d", num)
|
# return struct.pack(">d", num)
|
||||||
|
|
||||||
|
cdef int serialize_uint32(unsigned char* out, unsigned int v) except -1 nogil:
|
||||||
|
out[0] = (v >> 24) & 0xFF
|
||||||
|
out[1] = (v >> 16) & 0xFF
|
||||||
|
out[2] = (v >> 8) & 0xFF
|
||||||
|
out[3] = v & 0xFF
|
||||||
|
|
||||||
|
cdef int serialize_uint64(unsigned char* out, unsigned long long v) except -1 nogil:
|
||||||
|
out[0] = (v >> 56) & 0xFF
|
||||||
|
out[1] = (v >> 48) & 0xFF
|
||||||
|
out[2] = (v >> 40) & 0xFF
|
||||||
|
out[3] = (v >> 32) & 0xFF
|
||||||
|
out[4] = (v >> 24) & 0xFF
|
||||||
|
out[5] = (v >> 16) & 0xFF
|
||||||
|
out[6] = (v >> 8) & 0xFF
|
||||||
|
out[7] = v & 0xFF
|
||||||
|
|
||||||
|
cdef struct SerializeResult:
|
||||||
|
unsigned char *ptr
|
||||||
|
size_t size
|
||||||
|
|
||||||
cdef class PyBlock:
|
cdef class PyBlock:
|
||||||
cdef:
|
cdef:
|
||||||
@ -52,26 +74,19 @@ cdef class PyBlock:
|
|||||||
if not from_ptr:
|
if not from_ptr:
|
||||||
self.BlockC = new Block(
|
self.BlockC = new Block(
|
||||||
index,
|
index,
|
||||||
datetime.datetime(2025, 12, 1, 12, 0, 0).timestamp(),
|
int(datetime.datetime(2025, 12, 1, 12, 0, 0).timestamp()),
|
||||||
nonce,
|
nonce,
|
||||||
data.encode("UTF-8"),
|
data.encode("UTF-8"),
|
||||||
previous_hash.encode("UTF-8"),
|
previous_hash.encode("UTF-8"),
|
||||||
"".encode("UTF-8"),
|
"".encode("UTF-8"),
|
||||||
)
|
)
|
||||||
if self.BlockC == NULL:
|
if self.BlockC == NULL:
|
||||||
raise MemoryError("Allocation of block object failed")
|
raise MemoryError()
|
||||||
|
|
||||||
self.ptr_owner = True
|
self.ptr_owner = True
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
pass
|
pass
|
||||||
# self._index = index
|
|
||||||
# # self._timestamp = dopt_basics.datetime.current_time_tz().timestamp()
|
|
||||||
# self._timestamp = datetime.datetime(2025, 12, 1, 12, 0, 0).timestamp()
|
|
||||||
# self._data = data.encode("UTF-8")
|
|
||||||
# self._prev_hash = previous_hash.encode("UTF-8")
|
|
||||||
# self._nonce = nonce
|
|
||||||
# self._hash = "".encode("UTF-8")
|
|
||||||
|
|
||||||
def __dealloc__(self):
|
def __dealloc__(self):
|
||||||
if self.BlockC is not NULL and self.ptr_owner is True:
|
if self.BlockC is not NULL and self.ptr_owner is True:
|
||||||
@ -144,6 +159,58 @@ cdef class PyBlock:
|
|||||||
def hash(self):
|
def hash(self):
|
||||||
return self.BlockC.hash.decode("UTF-8")
|
return self.BlockC.hash.decode("UTF-8")
|
||||||
|
|
||||||
|
cdef SerializeResult bytes_serialize_c(self):
|
||||||
|
cdef:
|
||||||
|
size_t total_len
|
||||||
|
unsigned char* buf
|
||||||
|
size_t pos = 0
|
||||||
|
|
||||||
|
# index (8), timestamp (8), nonce (8), data, prev_hash
|
||||||
|
total_len = (
|
||||||
|
<size_t>(8 * 3) +
|
||||||
|
self.BlockC.data.size() +
|
||||||
|
self.BlockC.prev_hash.size()
|
||||||
|
)
|
||||||
|
buf = <unsigned char*>malloc(total_len * sizeof(unsigned char))
|
||||||
|
|
||||||
|
if buf == NULL:
|
||||||
|
raise MemoryError()
|
||||||
|
|
||||||
|
serialize_uint64(buf + pos, self.BlockC.index)
|
||||||
|
pos += 8
|
||||||
|
serialize_uint64(buf + pos, self.BlockC.timestamp)
|
||||||
|
pos += 8
|
||||||
|
serialize_uint64(buf + pos, self.BlockC.nonce)
|
||||||
|
pos += 8
|
||||||
|
# Copy data
|
||||||
|
memcpy(
|
||||||
|
buf + pos,
|
||||||
|
self.BlockC.data.c_str(),
|
||||||
|
self.BlockC.data.size(),
|
||||||
|
)
|
||||||
|
pos += self.BlockC.data.size()
|
||||||
|
# Copy prev_hash
|
||||||
|
memcpy(
|
||||||
|
buf + pos,
|
||||||
|
self.BlockC.prev_hash.c_str(),
|
||||||
|
self.BlockC.prev_hash.size(),
|
||||||
|
)
|
||||||
|
pos += self.BlockC.prev_hash.size()
|
||||||
|
|
||||||
|
return SerializeResult(buf, total_len)
|
||||||
|
|
||||||
|
def bytes_serialize(self):
|
||||||
|
cdef SerializeResult serialize_res
|
||||||
|
try:
|
||||||
|
serialize_res = self.bytes_serialize_c()
|
||||||
|
return serialize_res.ptr[:serialize_res.size]
|
||||||
|
finally:
|
||||||
|
free(serialize_res.ptr)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# @hash.setter
|
# @hash.setter
|
||||||
# def hash(self, value):
|
# def hash(self, value):
|
||||||
# if not isinstance(value, str):
|
# if not isinstance(value, str):
|
||||||
@ -222,7 +289,7 @@ cdef class Blockchain:
|
|||||||
def create_genesis_block(self):
|
def create_genesis_block(self):
|
||||||
cdef Block *block = new Block(
|
cdef Block *block = new Block(
|
||||||
self._index,
|
self._index,
|
||||||
datetime.datetime(2025, 12, 1, 12, 0, 0).timestamp(),
|
int(datetime.datetime(2025, 12, 1, 12, 0, 0).timestamp()),
|
||||||
0,
|
0,
|
||||||
"Genesis Block".encode("UTF-8"),
|
"Genesis Block".encode("UTF-8"),
|
||||||
"0".encode("UTF-8"),
|
"0".encode("UTF-8"),
|
||||||
@ -242,7 +309,7 @@ cdef class Blockchain:
|
|||||||
|
|
||||||
cdef Block *block = new Block(
|
cdef Block *block = new Block(
|
||||||
new_idx,
|
new_idx,
|
||||||
datetime.datetime(2025, 12, 1, 12, 0, 0).timestamp(),
|
int(datetime.datetime(2025, 12, 1, 12, 0, 0).timestamp()),
|
||||||
0,
|
0,
|
||||||
data.encode("UTF-8"),
|
data.encode("UTF-8"),
|
||||||
prev_hash,
|
prev_hash,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user