Include prototyping steps #1

Merged
foefl merged 15 commits from native_hashing into main 2025-12-16 12:50:07 +00:00
5 changed files with 10689 additions and 2 deletions
Showing only changes of commit d3d5d04ef2 - Show all commits

View File

@ -18,8 +18,9 @@ if DEBUG:
ext_modules = cythonize( ext_modules = cythonize(
[ [
"src/polluck_blockchain/placeholder.py", # "src/polluck_blockchain/placeholder.py",
"src/polluck_blockchain/python_translate.py", "src/polluck_blockchain/placeholder_native.pyx",
# "src/polluck_blockchain/python_translate.py",
], ],
compiler_directives={ compiler_directives={
"language_level": 3, "language_level": 3,

View File

@ -0,0 +1,16 @@
// block.hpp
#pragma once
#include <string>
struct Block {
uint64_t index;
double timestamp;
uint64_t nonce;
std::string data;
std::string prev_hash;
std::string 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)
: index(idx), timestamp(ts), nonce(n), data(d), prev_hash(pre_h), hash(h) {}
};

View File

@ -0,0 +1,14 @@
from libcpp.string cimport string
from libc cimport stdint
cdef extern from "block.hpp" namespace "":
cdef cppclass Block:
stdint.uint64_t index
double timestamp
stdint.uint64_t nonce
string data
string prev_hash
string hash
Block() except +
Block(stdint.uint64_t, double, stdint.uint64_t, string, string, string) except +

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,251 @@
# distutils: language = c++
"""placeholder module for compilation"""
from __future__ import annotations
import datetime
import hashlib
import struct
import time
import cython
import dopt_basics.datetime
# from cython.cimports.cpython.ref import Py_INCREF, PyObject
from polluck_blockchain.block cimport Block
from libcpp.unordered_map cimport unordered_map
from libcpp.string cimport string
ctypedef unsigned long ULong
# 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):
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):
return struct.pack(">d", num)
# cdef struct BlockC:
# ULong _index
# double _timestamp
# string _data
# string _prev_hash
# ULong _nonce
# string _hash
cdef class BlockPy:
cdef:
ULong _index
double _timestamp
string _data
string _prev_hash
ULong _nonce
string _hash
Block* Block
def __cinit__(self,
index: int,
data: str,
previous_hash: str,
nonce: int,
):
self.Block = new Block(
index,
datetime.datetime(2025, 12, 1, 12, 0, 0).timestamp(),
nonce,
data.encode("UTF-8"),
previous_hash.encode("UTF-8"),
"".encode("UTF-8"),
)
def get_data(self):
return self.Block.data.decode("UTF-8")
# def __init__(
# self,
# 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._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")
# cpdef _perform_hash(self):
# parts = bytearray()
# parts.extend(self._index.to_bytes(8, "big"))
# parts.extend(float_to_bytes(self._timestamp))
# parts.extend(self._data)
# parts.extend(self._prev_hash)
# parts.extend(self._nonce.to_bytes(8, "big"))
# return hashlib.sha256(parts)
# def compute_hash_bytes(self):
# return self._perform_hash().digest()
# def compute_hash(self):
# return self._perform_hash().hexdigest()
# # Python public API
# @property
# def index(self):
# return self._index
# @property
# def timestamp(self):
# return timestamp_to_datetime(self._timestamp)
# @property
# def data(self):
# return self._data.decode("UTF-8")
# @property
# def prev_hash(self):
# return self._prev_hash.decode("UTF-8")
# @property
# def nonce(self):
# return self._nonce
# @nonce.setter
# def nonce(self, value: int):
# self._nonce = value
# @property
# def hash(self):
# return self._hash.decode("UTF-8")
# @hash.setter
# def hash(self, value: str):
# if not isinstance(value, str):
# raise TypeError("No string")
# self._hash = value.encode("UTF-8")
# cdef class Blockchain:
# cdef int _difficulty
# cdef size_t _index
# cdef unordered_map[size_t, int] _chain
# def __cinit__(self):
# self._difficulty = 1
# self._index = <size_t>0
# # self._chain = new unordered_map[size_t, Block]()
# def __init__(
# self,
# difficulty: int = 1,
# ) -> None:
# self._difficulty = difficulty
# @property
# def index(self):
# return self._index
# @property
# def difficulty(self):
# return self._difficulty
# cdef create_genesis_block(self):
# genesis = Block(
# index=0,
# data="Genesis Block",
# previous_hash="0",
# nonce=0,
# )
# genesis.hash = genesis.compute_hash()
# self.chain[self._index] = genesis
# cdef proof_of_work(self, block: Block):
# prefix = "0" * self._difficulty
# while True:
# block_hash = block.compute_hash()
# if block_hash.startswith(prefix):
# return block_hash
# block._nonce += 1
# cdef add_block(self, data: str):
# prev_hash = self.chain[self._index].hash
# new_block = Block(
# index=(self._index + 1),
# data=data,
# previous_hash=prev_hash,
# nonce=0,
# )
# # start = time.perf_counter()
# new_block.hash = self.proof_of_work(new_block)
# # elapsed = time.perf_counter() - start
# self.chain.append(new_block)
# self._index += 1
# print(f"Mined block {new_block.index} with nonce={new_block.nonce}")
# # print(f"Mined block {new_block.index} in {elapsed:.3f}s with nonce={new_block.nonce}")
# return new_block