Include prototyping steps #1

Merged
foefl merged 15 commits from native_hashing into main 2025-12-16 12:50:07 +00:00
17 changed files with 45235 additions and 1697 deletions

3
.gitignore vendored
View File

@ -5,6 +5,9 @@ reports/
*.code-workspace *.code-workspace
# credentials # credentials
CREDENTIALS* CREDENTIALS*
bin
openssl
*.dll
# Byte-compiled / optimized / DLL files # Byte-compiled / optimized / DLL files
__pycache__/ __pycache__/

99
pdm.lock generated
View File

@ -5,7 +5,7 @@
groups = ["default", "dev", "lint", "nb", "tests"] groups = ["default", "dev", "lint", "nb", "tests"]
strategy = ["inherit_metadata"] strategy = ["inherit_metadata"]
lock_version = "4.5.0" lock_version = "4.5.0"
content_hash = "sha256:c0680aa00cf7474d542ab72daaea39fe9f3c23b3b68f724f49da67b2d74ff588" content_hash = "sha256:813bab76055ae1081c8e05c3f2d6b429ac1caf20ae5353aa06c90e70a17f75cb"
[[metadata.targets]] [[metadata.targets]]
requires_python = ">=3.11" requires_python = ">=3.11"
@ -831,6 +831,56 @@ files = [
{file = "fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f"}, {file = "fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f"},
] ]
[[package]]
name = "greenlet"
version = "3.3.0"
requires_python = ">=3.10"
summary = "Lightweight in-process concurrent programming"
groups = ["default"]
marker = "platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\""
files = [
{file = "greenlet-3.3.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:e29f3018580e8412d6aaf5641bb7745d38c85228dacf51a73bd4e26ddf2a6a8e"},
{file = "greenlet-3.3.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a687205fb22794e838f947e2194c0566d3812966b41c78709554aa883183fb62"},
{file = "greenlet-3.3.0-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4243050a88ba61842186cb9e63c7dfa677ec146160b0efd73b855a3d9c7fcf32"},
{file = "greenlet-3.3.0-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:670d0f94cd302d81796e37299bcd04b95d62403883b24225c6b5271466612f45"},
{file = "greenlet-3.3.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6cb3a8ec3db4a3b0eb8a3c25436c2d49e3505821802074969db017b87bc6a948"},
{file = "greenlet-3.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2de5a0b09eab81fc6a382791b995b1ccf2b172a9fec934747a7a23d2ff291794"},
{file = "greenlet-3.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4449a736606bd30f27f8e1ff4678ee193bc47f6ca810d705981cfffd6ce0d8c5"},
{file = "greenlet-3.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:7652ee180d16d447a683c04e4c5f6441bae7ba7b17ffd9f6b3aff4605e9e6f71"},
{file = "greenlet-3.3.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:b01548f6e0b9e9784a2c99c5651e5dc89ffcbe870bc5fb2e5ef864e9cc6b5dcb"},
{file = "greenlet-3.3.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:349345b770dc88f81506c6861d22a6ccd422207829d2c854ae2af8025af303e3"},
{file = "greenlet-3.3.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e8e18ed6995e9e2c0b4ed264d2cf89260ab3ac7e13555b8032b25a74c6d18655"},
{file = "greenlet-3.3.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c024b1e5696626890038e34f76140ed1daf858e37496d33f2af57f06189e70d7"},
{file = "greenlet-3.3.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:047ab3df20ede6a57c35c14bf5200fcf04039d50f908270d3f9a7a82064f543b"},
{file = "greenlet-3.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2d9ad37fc657b1102ec880e637cccf20191581f75c64087a549e66c57e1ceb53"},
{file = "greenlet-3.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:83cd0e36932e0e7f36a64b732a6f60c2fc2df28c351bae79fbaf4f8092fe7614"},
{file = "greenlet-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a7a34b13d43a6b78abf828a6d0e87d3385680eaf830cd60d20d52f249faabf39"},
{file = "greenlet-3.3.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:a1e41a81c7e2825822f4e068c48cb2196002362619e2d70b148f20a831c00739"},
{file = "greenlet-3.3.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9f515a47d02da4d30caaa85b69474cec77b7929b2e936ff7fb853d42f4bf8808"},
{file = "greenlet-3.3.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7d2d9fd66bfadf230b385fdc90426fcd6eb64db54b40c495b72ac0feb5766c54"},
{file = "greenlet-3.3.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30a6e28487a790417d036088b3bcb3f3ac7d8babaa7d0139edbaddebf3af9492"},
{file = "greenlet-3.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:087ea5e004437321508a8d6f20efc4cfec5e3c30118e1417ea96ed1d93950527"},
{file = "greenlet-3.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ab97cf74045343f6c60a39913fa59710e4bd26a536ce7ab2397adf8b27e67c39"},
{file = "greenlet-3.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5375d2e23184629112ca1ea89a53389dddbffcf417dad40125713d88eb5f96e8"},
{file = "greenlet-3.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:9ee1942ea19550094033c35d25d20726e4f1c40d59545815e1128ac58d416d38"},
{file = "greenlet-3.3.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:60c2ef0f578afb3c8d92ea07ad327f9a062547137afe91f38408f08aacab667f"},
{file = "greenlet-3.3.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a5d554d0712ba1de0a6c94c640f7aeba3f85b3a6e1f2899c11c2c0428da9365"},
{file = "greenlet-3.3.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3a898b1e9c5f7307ebbde4102908e6cbfcb9ea16284a3abe15cab996bee8b9b3"},
{file = "greenlet-3.3.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:dcd2bdbd444ff340e8d6bdf54d2f206ccddbb3ccfdcd3c25bf4afaa7b8f0cf45"},
{file = "greenlet-3.3.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5773edda4dc00e173820722711d043799d3adb4f01731f40619e07ea2750b955"},
{file = "greenlet-3.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ac0549373982b36d5fd5d30beb8a7a33ee541ff98d2b502714a09f1169f31b55"},
{file = "greenlet-3.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d198d2d977460358c3b3a4dc844f875d1adb33817f0613f663a656f463764ccc"},
{file = "greenlet-3.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:73f51dd0e0bdb596fb0417e475fa3c5e32d4c83638296e560086b8d7da7c4170"},
{file = "greenlet-3.3.0-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:d6ed6f85fae6cdfdb9ce04c9bf7a08d666cfcfb914e7d006f44f840b46741931"},
{file = "greenlet-3.3.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9125050fcf24554e69c4cacb086b87b3b55dc395a8b3ebe6487b045b2614388"},
{file = "greenlet-3.3.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:87e63ccfa13c0a0f6234ed0add552af24cc67dd886731f2261e46e241608bee3"},
{file = "greenlet-3.3.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2662433acbca297c9153a4023fe2161c8dcfdcc91f10433171cf7e7d94ba2221"},
{file = "greenlet-3.3.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3c6e9b9c1527a78520357de498b0e709fb9e2f49c3a513afd5a249007261911b"},
{file = "greenlet-3.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:286d093f95ec98fdd92fcb955003b8a3d054b4e2cab3e2707a5039e7b50520fd"},
{file = "greenlet-3.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c10513330af5b8ae16f023e8ddbfb486ab355d04467c4679c5cfe4659975dd9"},
{file = "greenlet-3.3.0.tar.gz", hash = "sha256:a82bb225a4e9e4d653dd2fb7b8b2d36e4fb25bc0165422a11e48b88e9e6f78fb"},
]
[[package]] [[package]]
name = "h11" name = "h11"
version = "0.16.0" version = "0.16.0"
@ -2426,6 +2476,51 @@ files = [
{file = "soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f"}, {file = "soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f"},
] ]
[[package]]
name = "sqlalchemy"
version = "2.0.45"
requires_python = ">=3.7"
summary = "Database Abstraction Library"
groups = ["default"]
dependencies = [
"greenlet>=1; platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\"",
"importlib-metadata; python_version < \"3.8\"",
"typing-extensions>=4.6.0",
]
files = [
{file = "sqlalchemy-2.0.45-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e90a344c644a4fa871eb01809c32096487928bd2038bf10f3e4515cb688cc56"},
{file = "sqlalchemy-2.0.45-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8c8b41b97fba5f62349aa285654230296829672fc9939cd7f35aab246d1c08b"},
{file = "sqlalchemy-2.0.45-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:12c694ed6468333a090d2f60950e4250b928f457e4962389553d6ba5fe9951ac"},
{file = "sqlalchemy-2.0.45-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f7d27a1d977a1cfef38a0e2e1ca86f09c4212666ce34e6ae542f3ed0a33bc606"},
{file = "sqlalchemy-2.0.45-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d62e47f5d8a50099b17e2bfc1b0c7d7ecd8ba6b46b1507b58cc4f05eefc3bb1c"},
{file = "sqlalchemy-2.0.45-cp311-cp311-win32.whl", hash = "sha256:3c5f76216e7b85770d5bb5130ddd11ee89f4d52b11783674a662c7dd57018177"},
{file = "sqlalchemy-2.0.45-cp311-cp311-win_amd64.whl", hash = "sha256:a15b98adb7f277316f2c276c090259129ee4afca783495e212048daf846654b2"},
{file = "sqlalchemy-2.0.45-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3ee2aac15169fb0d45822983631466d60b762085bc4535cd39e66bea362df5f"},
{file = "sqlalchemy-2.0.45-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba547ac0b361ab4f1608afbc8432db669bd0819b3e12e29fb5fa9529a8bba81d"},
{file = "sqlalchemy-2.0.45-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:215f0528b914e5c75ef2559f69dca86878a3beeb0c1be7279d77f18e8d180ed4"},
{file = "sqlalchemy-2.0.45-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:107029bf4f43d076d4011f1afb74f7c3e2ea029ec82eb23d8527d5e909e97aa6"},
{file = "sqlalchemy-2.0.45-cp312-cp312-win32.whl", hash = "sha256:0c9f6ada57b58420a2c0277ff853abe40b9e9449f8d7d231763c6bc30f5c4953"},
{file = "sqlalchemy-2.0.45-cp312-cp312-win_amd64.whl", hash = "sha256:8defe5737c6d2179c7997242d6473587c3beb52e557f5ef0187277009f73e5e1"},
{file = "sqlalchemy-2.0.45-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe187fc31a54d7fd90352f34e8c008cf3ad5d064d08fedd3de2e8df83eb4a1cf"},
{file = "sqlalchemy-2.0.45-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:672c45cae53ba88e0dad74b9027dddd09ef6f441e927786b05bec75d949fbb2e"},
{file = "sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:470daea2c1ce73910f08caf10575676a37159a6d16c4da33d0033546bddebc9b"},
{file = "sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9c6378449e0940476577047150fd09e242529b761dc887c9808a9a937fe990c8"},
{file = "sqlalchemy-2.0.45-cp313-cp313-win32.whl", hash = "sha256:4b6bec67ca45bc166c8729910bd2a87f1c0407ee955df110d78948f5b5827e8a"},
{file = "sqlalchemy-2.0.45-cp313-cp313-win_amd64.whl", hash = "sha256:afbf47dc4de31fa38fd491f3705cac5307d21d4bb828a4f020ee59af412744ee"},
{file = "sqlalchemy-2.0.45-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:83d7009f40ce619d483d26ac1b757dfe3167b39921379a8bd1b596cf02dab4a6"},
{file = "sqlalchemy-2.0.45-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d8a2ca754e5415cde2b656c27900b19d50ba076aa05ce66e2207623d3fe41f5a"},
{file = "sqlalchemy-2.0.45-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f46ec744e7f51275582e6a24326e10c49fbdd3fc99103e01376841213028774"},
{file = "sqlalchemy-2.0.45-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:883c600c345123c033c2f6caca18def08f1f7f4c3ebeb591a63b6fceffc95cce"},
{file = "sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2c0b74aa79e2deade948fe8593654c8ef4228c44ba862bb7c9585c8e0db90f33"},
{file = "sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8a420169cef179d4c9064365f42d779f1e5895ad26ca0c8b4c0233920973db74"},
{file = "sqlalchemy-2.0.45-cp314-cp314-win32.whl", hash = "sha256:e50dcb81a5dfe4b7b4a4aa8f338116d127cb209559124f3694c70d6cd072b68f"},
{file = "sqlalchemy-2.0.45-cp314-cp314-win_amd64.whl", hash = "sha256:4748601c8ea959e37e03d13dcda4a44837afcd1b21338e637f7c935b8da06177"},
{file = "sqlalchemy-2.0.45-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd337d3526ec5298f67d6a30bbbe4ed7e5e68862f0bf6dd21d289f8d37b7d60b"},
{file = "sqlalchemy-2.0.45-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9a62b446b7d86a3909abbcd1cd3cc550a832f99c2bc37c5b22e1925438b9367b"},
{file = "sqlalchemy-2.0.45-py3-none-any.whl", hash = "sha256:5225a288e4c8cc2308dbdd874edad6e7d0fd38eac1e9e5f23503425c8eee20d0"},
{file = "sqlalchemy-2.0.45.tar.gz", hash = "sha256:1632a4bda8d2d25703fdad6363058d882541bdaaee0e5e3ddfa0cd3229efce88"},
]
[[package]] [[package]]
name = "stack-data" name = "stack-data"
version = "0.6.3" version = "0.6.3"
@ -2519,7 +2614,7 @@ name = "typing-extensions"
version = "4.15.0" version = "4.15.0"
requires_python = ">=3.9" requires_python = ">=3.9"
summary = "Backported and Experimental Type Hints for Python 3.9+" summary = "Backported and Experimental Type Hints for Python 3.9+"
groups = ["dev", "nb"] groups = ["default", "dev", "nb"]
files = [ files = [
{file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"},
{file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"},

View File

@ -1,11 +1,11 @@
[project] [project]
name = "polluck-blockchain" name = "dopt-pollublock-blockchain"
version = "0.1.0" version = "0.1.0"
description = "blockchain module of the research project >Polluck<" description = "blockchain module of the research project >Polluck<"
authors = [ authors = [
{name = "d-opt GmbH, resp. Florian Foerster", email = "f.foerster@d-opt.com"}, {name = "d-opt GmbH, resp. Florian Foerster", email = "f.foerster@d-opt.com"},
] ]
dependencies = ["dopt-basics>=0.2.4"] dependencies = ["dopt-basics>=0.2.4", "sqlalchemy>=2.0.45"]
requires-python = ">=3.11" requires-python = ">=3.11"
readme = "README.md" readme = "README.md"
license = {text = "LicenseRef-Proprietary"} license = {text = "LicenseRef-Proprietary"}

View File

@ -1,30 +1,51 @@
import os import os
import sys import sys
from pathlib import Path
from Cython.Build import cythonize from Cython.Build import cythonize
from Cython.Compiler import Options from Cython.Compiler import Options
from setuptools import setup from setuptools import Extension, setup
# Cython compilation options
Options.docstrings = False Options.docstrings = False
Options.embed_pos_in_docstring = False Options.embed_pos_in_docstring = False
Options.annotate = False Options.annotate = False
Options.fast_fail = True Options.fast_fail = True
OPEN_MP = False
DEBUG = bool(os.getenv("DOPT_DEBUG", None)) DEBUG = bool(os.getenv("DOPT_DEBUG", None))
linetrace_opt: bool = False linetrace_opt: bool = False
if DEBUG: if DEBUG:
linetrace_opt = True linetrace_opt = True
# includes
OPENSSL_DIR = (Path(__file__).parent / "openssl").resolve()
assert OPENSSL_DIR.exists()
openssl_include = OPENSSL_DIR / "include"
assert openssl_include.exists()
openssl_lib = OPENSSL_DIR / "lib"
assert openssl_lib.exists()
ext = Extension(
name="dopt_pollublock_blockchain.blockchain",
sources=["src/dopt_pollublock_blockchain/blockchain.pyx"],
include_dirs=[str(openssl_include)],
library_dirs=[str(openssl_lib)],
libraries=["libssl", "libcrypto"],
)
ext_modules = cythonize( ext_modules = cythonize(
[ [
"src/polluck_blockchain/placeholder.py", ext,
"src/polluck_blockchain/python_translate.py", # "src/polluck_blockchain/placeholder.py",
# "src/polluck_blockchain/placeholder_native.pyx",
# "src/polluck_blockchain/python_translate.py",
], ],
compiler_directives={ compiler_directives={
"language_level": 3, "language_level": 3,
"boundscheck": False, "boundscheck": False,
"wraparound": True, "wraparound": False,
"embedsignature": False, "embedsignature": False,
"annotation_typing": True, "annotation_typing": True,
"linetrace": linetrace_opt, "linetrace": linetrace_opt,
@ -40,8 +61,11 @@ 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"]
l_args = ("/LTCG", "/OPT:REF", "/OPT:ICF") l_args = ["/LTCG", "/OPT:REF", "/OPT:ICF"]
if OPEN_MP:
c_args.extend(["/openmp:llvm"])
l_args.extend(["/openmp:llvm"])
else: else:
c_args = tuple() c_args = tuple()
l_args = tuple() l_args = tuple()

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, 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) {}
};

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
stdint.uint64_t 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 one or more lines are too long

View File

@ -0,0 +1,630 @@
# distutils: language = c++
"""placeholder module for compilation"""
from __future__ import annotations
import datetime
from pathlib import Path
import dopt_basics.datetime
import sqlalchemy as sql
from dopt_pollublock_blockchain import db
from dopt_pollublock_blockchain.block cimport Block
from libcpp.unordered_map cimport unordered_map
from libcpp.vector cimport vector
from libcpp.string cimport string
from libc.stdint cimport uint64_t
from libc.stdlib cimport malloc, free
from libc.string cimport memcpy
from cython.operator import postincrement, dereference
cimport dopt_pollublock_blockchain.openssl_evp as ossl
ctypedef unsigned long ULong
ctypedef unordered_map[uint64_t, Block*] BcHashmap
cdef const size_t NONCE_OFFSET = <size_t>16
cdef timestamp_to_datetime(uint64_t ts):
return datetime.datetime.fromtimestamp(float(ts), dopt_basics.datetime.TIMEZONE_UTC)
cdef uint64_t current_timestamp_integer():
cdef uint64_t ts
dt = dopt_basics.datetime.current_time_tz(cut_microseconds=True)
ts = <uint64_t>int(dt.timestamp())
return ts
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 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:
Block *BlockC
bint ptr_owner
def __cinit__(self,
index,
nonce,
data,
previous_hash,
from_ptr=False,
):
self.ptr_owner = False
if not from_ptr:
self.BlockC = new Block(
index,
current_timestamp_integer(),
nonce,
data.encode("UTF-8"),
previous_hash.encode("UTF-8"),
"".encode("UTF-8"),
)
if self.BlockC is NULL:
raise MemoryError()
self.ptr_owner = True
def __init__(self, *args, **kwargs):
pass
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
def __repr__(self):
return (
f"PyBlock(\n\tIndex:\t\t{self.index}\n\ttimestamp:\t{self.timestamp}\n\tnonce:\t\t{self.nonce}\n\t"
f"Prev Hash:\t{self.prev_hash}\n\tHash:\t\t{self.hash}\n\tData:\t\t{self.data}\n)"
)
def __str__(self):
return self.__repr__()
def serialize_dict(self):
contents = {}
contents["index"] = self.BlockC.index
contents["timestamp"] = self.BlockC.timestamp
contents["nonce"] = self.BlockC.nonce
contents["previous_hash"] = self.prev_hash
contents["hash"] = self.hash
contents["data"] = self.data
return contents
# Python public API
@property
def index(self):
return self.BlockC.index
@property
def timestamp(self):
return timestamp_to_datetime(self.BlockC.timestamp)
@property
def data(self):
return self.BlockC.data.decode("UTF-8")
@property
def prev_hash(self):
return self.BlockC.prev_hash.decode("UTF-8")
@property
def nonce(self):
return self.BlockC.nonce
@property
def hash(self):
return self.BlockC.hash.decode("UTF-8")
def bytes_serialize(self):
cdef:
unsigned char *serialize_res
size_t serialize_size
try:
serialize_res = bytes_serialize_c(self.BlockC, &serialize_size)
return serialize_res[:serialize_size]
finally:
free(serialize_res)
def perform_hash(self):
cdef:
unsigned char *digest
size_t digest_size
try:
digest = perform_hash_c(self.BlockC, &digest_size)
if digest is NULL:
raise MemoryError()
# TODO out: hash assignment in blockchain
self.BlockC.hash = bytes(digest[:digest_size]).hex().encode("UTF-8")
finally:
free(digest)
# TODO rework
return self.hash
cdef unsigned char* bytes_serialize_c(Block *block, size_t *size) nogil:
cdef:
size_t total_len
unsigned char* buf
size_t pos = 0
# index (8), timestamp (8), nonce (8), data, prev_hash
size[0] = (
<size_t>(8 * 3) +
block.data.size() +
block.prev_hash.size()
)
buf = <unsigned char*>malloc(size[0] * sizeof(unsigned char))
if buf is NULL:
return NULL
serialize_uint64(buf + pos, block.index)
pos += 8
serialize_uint64(buf + pos, block.timestamp)
pos += 8
serialize_uint64(buf + pos, block.nonce)
pos += 8
# Copy data
memcpy(
buf + pos,
block.data.c_str(),
block.data.size(),
)
pos += block.data.size()
# Copy prev_hash
memcpy(
buf + pos,
block.prev_hash.c_str(),
block.prev_hash.size(),
)
pos += block.prev_hash.size()
return buf
cdef unsigned char* SHA256_digest(const void *data, size_t data_size, size_t *digest_size) nogil:
cdef ossl.EVP_MD_CTX *ctx = ossl.EVP_MD_CTX_new()
if ctx is NULL:
return NULL
cdef const ossl.EVP_MD *algo = ossl.EVP_sha256()
if algo is NULL:
return NULL
cdef:
unsigned char* digest
size_t dig_buff_len
unsigned int digest_len
dig_buff_len = <size_t>ossl.EVP_MD_size(algo)
digest_size[0] = dig_buff_len
digest = <unsigned char*>malloc(dig_buff_len * sizeof(unsigned char))
ossl.EVP_DigestInit_ex(ctx, algo, NULL)
ossl.EVP_DigestUpdate(ctx, data, data_size)
ossl.EVP_DigestFinal_ex(ctx, digest, &digest_len)
ossl.EVP_MD_CTX_free(ctx)
return digest
cdef unsigned char* perform_hash_c(Block *block, size_t *digest_size) nogil:
cdef:
unsigned char *serialize_res
size_t serialize_size
unsigned char *digest
serialize_res = bytes_serialize_c(block, &serialize_size)
if serialize_res is NULL:
return NULL
digest = SHA256_digest(serialize_res, serialize_size, digest_size)
free(serialize_res)
if digest is NULL:
return NULL
return digest
cdef int mine_block(Block *block, unsigned int difficulty, uint64_t *nonce_solution, unsigned int max_nonce=0xFFFFFFFF) nogil:
cdef:
unsigned char *serial_buf
size_t serialize_size
unsigned char *digest
size_t digest_size
bint nonce_found = False
int nonce
serial_buf = bytes_serialize_c(block, &serialize_size)
with nogil:
for nonce in range(max_nonce):
serialize_uint64(serial_buf + NONCE_OFFSET, <uint64_t>nonce)
digest = SHA256_digest(serial_buf, serialize_size, &digest_size)
if has_leading_zero_bits(digest, difficulty):
nonce_found = True
nonce_solution[0] = nonce
break
free(digest)
free(serial_buf)
if not nonce_found:
return 1
return 0
cdef class Blockchain:
cdef:
unsigned int _difficulty
uint64_t _index
BcHashmap *_chain_map
vector[Block*] *_chain
bint _genesis_done
bint _loaded
readonly object db_path
readonly object _engine
def __cinit__(self, *args, **kwargs):
self._difficulty = 26
self._index = <uint64_t>0
self._genesis_done = False
self._loaded = False
self._chain_map = new unordered_map[uint64_t, Block*]()
self._chain = new vector[Block*]()
if self._chain_map is NULL:
raise MemoryError("Could not allocate hasmap")
if self._chain is NULL:
raise MemoryError("Could not allocate vector")
def __init__(self, db_path):
self.db_path = Path(db_path).resolve()
if not self.db_path.parent.exists():
raise FileNotFoundError(
"The parent directory of the provided database path does not exist"
)
self._engine = sql.create_engine(f"sqlite:///{str(self.db_path)}")
db.metadata_blockchain.create_all(self._engine)
def __dealloc__(self):
# ownership is typically not transferred from the Blockchain extension class
cdef BcHashmap.iterator it = self._chain_map.begin()
if self._chain_map is not NULL:
while it != self._chain_map.end():
del dereference(it).second
postincrement(it)
del self._chain_map
self._chain_map = NULL
if self._chain is not NULL:
del self._chain
self._chain = NULL
cdef Block* get_block_c(self, uint64_t idx) nogil:
if idx > self._index:
return NULL
return self._chain_map[0][idx]
cdef void add_block_from_loading(self, Block *block) nogil:
self._chain[0].push_back(block)
self._chain_map[0][block.index] = block
self._index = block.index
if not self._genesis_done:
self._genesis_done = True
cdef int add_block(self, Block *block) nogil:
cdef:
uint64_t mined_nonce
size_t digest_size
unsigned char *sha256_digest
# mine block
if mine_block(block, self._difficulty, &mined_nonce) != 0:
return 1
block.nonce = mined_nonce
# hash block, add hash to block, add block to blockchain hashmap
sha256_digest = perform_hash_c(block, &digest_size)
with gil:
block.hash = bytes(sha256_digest[:digest_size]).hex().encode("UTF-8")
free(sha256_digest)
self._chain[0].push_back(block)
self._chain_map[0][block.index] = block
if self._genesis_done:
self._index += 1
return 0
cdef string hash_data(self, data):
cdef:
string data_str
unsigned char *data_digest
size_t digest_size
data_str = data.encode("UTF-8")
data_digest = SHA256_digest(data_str.c_str(), data_str.size(), &digest_size)
if data_digest is NULL:
raise RuntimeError("Failed to hash data")
data_str = bytes(data_digest[:digest_size]).hex().encode("UTF-8")
free(data_digest)
return data_str
cdef load_from_batch(self, batch):
cdef Block *block
for entry in batch:
block = new Block(
entry[0],
entry[1],
entry[2],
entry[5].encode("UTF-8"),
entry[3].encode("UTF-8"),
entry[4].encode("UTF-8"),
)
self.add_block_from_loading(block)
# // Python public API
def __len__(self):
return self._index + 1
@property
def difficulty(self):
return self._difficulty
@difficulty.setter
def difficulty(self, value):
if not isinstance(value, int):
raise TypeError("Difficulty must be integer value")
if value <= 0:
raise ValueError("Difficulty must be greater than 0")
self._difficulty = value
@property
def genesis_done(self):
return self._genesis_done
@property
def index(self):
return self._index
def _print_key_value_pair(self):
cdef BcHashmap.iterator it = self._chain_map.begin()
cdef Block *block
while it != self._chain_map.end():
print(dereference(it).first)
block = dereference(it).second
py_block = PyBlock.from_ptr(block)
print(py_block)
postincrement(it)
def print_blocks(self, max_num):
cdef:
Block *block
int max_nummber = max_num
int idx, num = 0
if max_num <= 0:
raise ValueError("Maximum number must be greater than 0")
for idx in range(self._chain[0].size()):
block = self._chain[0][idx]
py_block = PyBlock.from_ptr(block)
print(py_block)
num += 1
if num == max_nummber:
break
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)
if block is NULL:
raise IndexError("Provided index not found")
return PyBlock.from_ptr(block, owner=False)
def create_genesis_block(self):
if self._genesis_done:
raise RuntimeError(
("Blockchain already has a genesis block. "
"Either it was created or loaded.")
)
genesis_prev_hash = ("0" * 64).encode("UTF-8")
cdef string data_str = self.hash_data("Genesis Block")
cdef Block *block = new Block(
self._index,
current_timestamp_integer(),
0,
data_str,
genesis_prev_hash,
"".encode("UTF-8"),
)
cdef int res = self.add_block(block)
if res != 0:
raise RuntimeError("Could not mine block. No nonce found")
self._genesis_done = True
def new_block(self, data):
cdef:
Block *prev_block
string prev_hash
uint64_t new_idx
string data_str
unsigned char *data_digest
size_t digest_size
if not self._genesis_done:
raise RuntimeError("Create a genesis block first.")
if not isinstance(data, str):
raise TypeError("Data must be a string")
data_str = self.hash_data(data)
prev_block = self.get_block_c(self._index)
prev_hash = prev_block.hash
new_idx = self._index + 1
cdef Block *block = new Block(
new_idx,
current_timestamp_integer(),
0,
data_str,
prev_hash,
"".encode("UTF-8"),
)
cdef int res = self.add_block(block)
if res != 0:
raise RuntimeError("Could not mine block. No nonce found")
def validate(self):
cdef:
Block *block
Block *prev_block = NULL
int idx = 0
unsigned char *digest
size_t digest_size
for idx in range(self._chain[0].size()):
block = self._chain[0][idx]
py_bytes = bytes.fromhex(block.hash.decode("UTF-8"))
digest = perform_hash_c(block, &digest_size)
py_bytes_rehashed = bytes(digest[:digest_size])
free(digest)
if py_bytes != py_bytes_rehashed:
print(f"Index {idx}: Hashes to not match. Abort.")
return False
if prev_block is not NULL:
if prev_block.hash != block.prev_hash:
print(
(f"Index {idx}: Hash mismatch. Hash of previous block does not "
"match the saved one in the current block. Abort.")
)
return False
prev_block = block
return True
def get_saving_entries(self, max_idx):
entries = []
cdef:
Block *block
int idx = 0
int _max_idx
if max_idx is None:
_max_idx = -1
else:
_max_idx = max_idx
for idx in range(self._chain[0].size()):
if idx <= _max_idx:
continue
block = self._chain[0][idx]
contents = {}
contents["index"] = block.index
contents["timestamp"] = block.timestamp
contents["nonce"] = block.nonce
contents["previous_hash"] = block.prev_hash.decode("UTF-8")
contents["hash"] = block.hash.decode("UTF-8")
contents["data"] = block.data.decode("UTF-8")
entries.append(contents)
return entries
def save(self):
# get max index from db
# only retrieve indices greater than max value
stmt = sql.select(sql.func.max(db.blocks.c.index))
with self._engine.connect() as conn:
result = conn.execute(stmt)
max_value = result.scalar()
entries = self.get_saving_entries(max_value)
if not entries:
return
with self._engine.begin() as con:
con.execute(sql.insert(db.blocks), entries)
def close_db_connections(self):
self._engine.dispose()
def load(self, batch_size):
if self._loaded:
raise RuntimeError("Blockchain was already loaded")
with self._engine.connect() as con:
res = con.execute(sql.select(db.blocks).order_by(db.blocks.c.index.asc()))
for batch in res.partitions(batch_size):
self.load_from_batch(batch)
self._loaded = True

View File

@ -0,0 +1,16 @@
from __future__ import annotations
import sqlalchemy as sql
metadata_blockchain: sql.MetaData = sql.MetaData()
blocks = sql.Table(
"blocks",
metadata_blockchain,
sql.Column("index", sql.BigInteger, primary_key=True),
sql.Column("timestamp", sql.BigInteger, nullable=False),
sql.Column("nonce", sql.BigInteger, nullable=False),
sql.Column("previous_hash", sql.String(64), nullable=False),
sql.Column("hash", sql.String(64), nullable=False),
sql.Column("data", sql.String(64), nullable=False),
)

View File

@ -0,0 +1,14 @@
cdef extern from "openssl/evp.h":
ctypedef struct EVP_MD_CTX:
pass
ctypedef struct EVP_MD:
pass
EVP_MD_CTX *EVP_MD_CTX_new() nogil
void EVP_MD_CTX_free(EVP_MD_CTX *) nogil
const EVP_MD *EVP_sha256() nogil
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) nogil
int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s) nogil
int EVP_MD_size(const EVP_MD *md) nogil
int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) nogil

View File

@ -158,15 +158,32 @@ class Block:
self._hash = StringHolder.__new__(StringHolder, value) self._hash = StringHolder.__new__(StringHolder, value)
@cython.cclass
class Blockchain: class Blockchain:
_difficulty = cython.declare(cython.int, visibility="private")
_index = cython.declare(cython.Py_ssize_t, visibility="private")
chain = cython.declare(list[Block], visibility="public")
def __cinit__(self):
self._index = 0
def __init__( def __init__(
self, self,
difficulty: int = 1, difficulty: int = 1,
) -> None: ) -> None:
self.chain: list[Block] = [] self.chain: list[Block] = []
# self.difficulty = difficulty.to_bytes(8, "big") # self.difficulty = difficulty.to_bytes(8, "big")
self.difficulty = difficulty self._difficulty = difficulty
@property
def index(self):
return self._index
@property
def difficulty(self):
return self._difficulty
@cython.ccall
def create_genesis_block(self): def create_genesis_block(self):
genesis = Block( genesis = Block(
index=0, index=0,
@ -177,22 +194,25 @@ class Blockchain:
genesis.hash = genesis.compute_hash() genesis.hash = genesis.compute_hash()
self.chain.append(genesis) self.chain.append(genesis)
@cython.ccall
def proof_of_work( def proof_of_work(
self, self,
block: Block, block: Block,
) -> str: ) -> str:
prefix = "0" * self.difficulty prefix = "0" * self._difficulty
while True: while True:
block_hash = block.compute_hash() block_hash = block.compute_hash()
if block_hash.startswith(prefix): if block_hash.startswith(prefix):
return block_hash return block_hash
block.nonce += 1 block._nonce += 1
@cython.ccall
def add_block(self, data: str) -> Block: def add_block(self, data: str) -> Block:
prev_hash = self.chain[self._index].hash
new_block = Block( new_block = Block(
index=len(self.chain), index=(self._index + 1),
data=data, data=data,
previous_hash=self.chain[-1].hash, previous_hash=prev_hash,
nonce=0, nonce=0,
) )
@ -201,6 +221,7 @@ class Blockchain:
# elapsed = time.perf_counter() - start # elapsed = time.perf_counter() - start
self.chain.append(new_block) 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} with nonce={new_block.nonce}")
# print(f"Mined block {new_block.index} in {elapsed:.3f}s with nonce={new_block.nonce}") # print(f"Mined block {new_block.index} in {elapsed:.3f}s with nonce={new_block.nonce}")

File diff suppressed because one or more lines are too long

View File

@ -2045,6 +2045,13 @@ static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
PyObject_Format(s, f)) PyObject_Format(s, f))
#endif #endif
/* PyObjectFormat.proto */
#if CYTHON_USE_UNICODE_WRITER
static PyObject* __Pyx_PyObject_Format(PyObject* s, PyObject* f);
#else
#define __Pyx_PyObject_Format(s, f) PyObject_Format(s, f)
#endif
/* JoinPyUnicode.export */ /* JoinPyUnicode.export */
static PyObject* __Pyx_PyUnicode_Join(PyObject** values, Py_ssize_t value_count, Py_ssize_t result_ulength, static PyObject* __Pyx_PyUnicode_Join(PyObject** values, Py_ssize_t value_count, Py_ssize_t result_ulength,
Py_UCS4 max_char); Py_UCS4 max_char);
@ -2444,7 +2451,7 @@ typedef struct {
__Pyx_CachedCFunction __pyx_umethod_PyByteArray_Type__extend; __Pyx_CachedCFunction __pyx_umethod_PyByteArray_Type__extend;
PyObject *__pyx_tuple[4]; PyObject *__pyx_tuple[4];
PyObject *__pyx_codeobj_tab[17]; PyObject *__pyx_codeobj_tab[17];
PyObject *__pyx_string_tab[122]; PyObject *__pyx_string_tab[127];
PyObject *__pyx_number_tab[5]; PyObject *__pyx_number_tab[5];
/* #### Code section: module_state_contents ### */ /* #### Code section: module_state_contents ### */
/* CommonTypesMetaclass.module_state_decls */ /* CommonTypesMetaclass.module_state_decls */
@ -2488,126 +2495,131 @@ static __pyx_mstatetype * const __pyx_mstate_global = &__pyx_mstate_global_stati
/* #### Code section: constant_name_defines ### */ /* #### Code section: constant_name_defines ### */
#define __pyx_kp_u_ __pyx_string_tab[0] #define __pyx_kp_u_ __pyx_string_tab[0]
#define __pyx_kp_u_0 __pyx_string_tab[1] #define __pyx_kp_u_0 __pyx_string_tab[1]
#define __pyx_kp_u_Genesis_Block __pyx_string_tab[2] #define __pyx_kp_u_3f __pyx_string_tab[2]
#define __pyx_kp_u_Mined_block __pyx_string_tab[3] #define __pyx_kp_u_Genesis_Block __pyx_string_tab[3]
#define __pyx_kp_u_No_string __pyx_string_tab[4] #define __pyx_kp_u_Mined_block __pyx_string_tab[4]
#define __pyx_kp_u_Note_that_Cython_is_deliberately __pyx_string_tab[5] #define __pyx_kp_u_No_string __pyx_string_tab[5]
#define __pyx_kp_u_UTF_8 __pyx_string_tab[6] #define __pyx_kp_u_Note_that_Cython_is_deliberately __pyx_string_tab[6]
#define __pyx_kp_u__2 __pyx_string_tab[7] #define __pyx_kp_u_UTF_8 __pyx_string_tab[7]
#define __pyx_kp_u_add_note __pyx_string_tab[8] #define __pyx_kp_u__2 __pyx_string_tab[8]
#define __pyx_kp_u_d __pyx_string_tab[9] #define __pyx_kp_u_add_note __pyx_string_tab[9]
#define __pyx_kp_u_datetime_datetime __pyx_string_tab[10] #define __pyx_kp_u_d __pyx_string_tab[10]
#define __pyx_kp_u_src_polluck_blockchain_python_tr __pyx_string_tab[11] #define __pyx_kp_u_datetime_datetime __pyx_string_tab[11]
#define __pyx_kp_u_with_nonce __pyx_string_tab[12] #define __pyx_kp_u_in __pyx_string_tab[12]
#define __pyx_n_u_Block __pyx_string_tab[13] #define __pyx_kp_u_s_with_nonce __pyx_string_tab[13]
#define __pyx_n_u_Block___init __pyx_string_tab[14] #define __pyx_kp_u_src_polluck_blockchain_python_tr __pyx_string_tab[14]
#define __pyx_n_u_Block__perform_hash __pyx_string_tab[15] #define __pyx_n_u_Block __pyx_string_tab[15]
#define __pyx_n_u_Block_compute_hash __pyx_string_tab[16] #define __pyx_n_u_Block___init __pyx_string_tab[16]
#define __pyx_n_u_Block_compute_hash_bytes __pyx_string_tab[17] #define __pyx_n_u_Block__perform_hash __pyx_string_tab[17]
#define __pyx_n_u_Block_data __pyx_string_tab[18] #define __pyx_n_u_Block_compute_hash __pyx_string_tab[18]
#define __pyx_n_u_Block_hash __pyx_string_tab[19] #define __pyx_n_u_Block_compute_hash_bytes __pyx_string_tab[19]
#define __pyx_n_u_Block_index __pyx_string_tab[20] #define __pyx_n_u_Block_data __pyx_string_tab[20]
#define __pyx_n_u_Block_nonce __pyx_string_tab[21] #define __pyx_n_u_Block_hash __pyx_string_tab[21]
#define __pyx_n_u_Block_prev_hash __pyx_string_tab[22] #define __pyx_n_u_Block_index __pyx_string_tab[22]
#define __pyx_n_u_Block_timestamp __pyx_string_tab[23] #define __pyx_n_u_Block_nonce __pyx_string_tab[23]
#define __pyx_n_u_Blockchain __pyx_string_tab[24] #define __pyx_n_u_Block_prev_hash __pyx_string_tab[24]
#define __pyx_n_u_Blockchain___init __pyx_string_tab[25] #define __pyx_n_u_Block_timestamp __pyx_string_tab[25]
#define __pyx_n_u_Blockchain_add_block __pyx_string_tab[26] #define __pyx_n_u_Blockchain __pyx_string_tab[26]
#define __pyx_n_u_Blockchain_create_genesis_block __pyx_string_tab[27] #define __pyx_n_u_Blockchain___init __pyx_string_tab[27]
#define __pyx_n_u_Blockchain_proof_of_work __pyx_string_tab[28] #define __pyx_n_u_Blockchain_add_block __pyx_string_tab[28]
#define __pyx_n_u_None __pyx_string_tab[29] #define __pyx_n_u_Blockchain_create_genesis_block __pyx_string_tab[29]
#define __pyx_n_u_Pyx_PyDict_NextRef __pyx_string_tab[30] #define __pyx_n_u_Blockchain_proof_of_work __pyx_string_tab[30]
#define __pyx_n_u_add_block __pyx_string_tab[31] #define __pyx_n_u_None __pyx_string_tab[31]
#define __pyx_n_u_append __pyx_string_tab[32] #define __pyx_n_u_Pyx_PyDict_NextRef __pyx_string_tab[32]
#define __pyx_n_u_asyncio_coroutines __pyx_string_tab[33] #define __pyx_n_u_add_block __pyx_string_tab[33]
#define __pyx_n_u_big __pyx_string_tab[34] #define __pyx_n_u_append __pyx_string_tab[34]
#define __pyx_n_u_block __pyx_string_tab[35] #define __pyx_n_u_asyncio_coroutines __pyx_string_tab[35]
#define __pyx_n_u_block_hash __pyx_string_tab[36] #define __pyx_n_u_big __pyx_string_tab[36]
#define __pyx_n_u_chain __pyx_string_tab[37] #define __pyx_n_u_block __pyx_string_tab[37]
#define __pyx_n_u_cline_in_traceback __pyx_string_tab[38] #define __pyx_n_u_block_hash __pyx_string_tab[38]
#define __pyx_n_u_compute_hash __pyx_string_tab[39] #define __pyx_n_u_chain __pyx_string_tab[39]
#define __pyx_n_u_compute_hash_bytes __pyx_string_tab[40] #define __pyx_n_u_cline_in_traceback __pyx_string_tab[40]
#define __pyx_n_u_create_genesis_block __pyx_string_tab[41] #define __pyx_n_u_compute_hash __pyx_string_tab[41]
#define __pyx_n_u_data __pyx_string_tab[42] #define __pyx_n_u_compute_hash_bytes __pyx_string_tab[42]
#define __pyx_n_u_data_2 __pyx_string_tab[43] #define __pyx_n_u_create_genesis_block __pyx_string_tab[43]
#define __pyx_n_u_datetime __pyx_string_tab[44] #define __pyx_n_u_data __pyx_string_tab[44]
#define __pyx_n_u_difficulty __pyx_string_tab[45] #define __pyx_n_u_data_2 __pyx_string_tab[45]
#define __pyx_n_u_digest __pyx_string_tab[46] #define __pyx_n_u_datetime __pyx_string_tab[46]
#define __pyx_n_u_doc __pyx_string_tab[47] #define __pyx_n_u_difficulty __pyx_string_tab[47]
#define __pyx_n_u_dopt_basics __pyx_string_tab[48] #define __pyx_n_u_digest __pyx_string_tab[48]
#define __pyx_n_u_dopt_basics_datetime __pyx_string_tab[49] #define __pyx_n_u_doc __pyx_string_tab[49]
#define __pyx_n_u_encode __pyx_string_tab[50] #define __pyx_n_u_dopt_basics __pyx_string_tab[50]
#define __pyx_n_u_extend __pyx_string_tab[51] #define __pyx_n_u_dopt_basics_datetime __pyx_string_tab[51]
#define __pyx_n_u_float __pyx_string_tab[52] #define __pyx_n_u_elapsed __pyx_string_tab[52]
#define __pyx_n_u_float_to_bytes __pyx_string_tab[53] #define __pyx_n_u_encode __pyx_string_tab[53]
#define __pyx_n_u_fromtimestamp __pyx_string_tab[54] #define __pyx_n_u_extend __pyx_string_tab[54]
#define __pyx_n_u_func __pyx_string_tab[55] #define __pyx_n_u_float __pyx_string_tab[55]
#define __pyx_n_u_genesis __pyx_string_tab[56] #define __pyx_n_u_float_to_bytes __pyx_string_tab[56]
#define __pyx_n_u_hash __pyx_string_tab[57] #define __pyx_n_u_fromtimestamp __pyx_string_tab[57]
#define __pyx_n_u_hash_2 __pyx_string_tab[58] #define __pyx_n_u_func __pyx_string_tab[58]
#define __pyx_n_u_hashlib __pyx_string_tab[59] #define __pyx_n_u_genesis __pyx_string_tab[59]
#define __pyx_n_u_hexdigest __pyx_string_tab[60] #define __pyx_n_u_hash __pyx_string_tab[60]
#define __pyx_n_u_index __pyx_string_tab[61] #define __pyx_n_u_hash_2 __pyx_string_tab[61]
#define __pyx_n_u_index_2 __pyx_string_tab[62] #define __pyx_n_u_hashlib __pyx_string_tab[62]
#define __pyx_n_u_init __pyx_string_tab[63] #define __pyx_n_u_hexdigest __pyx_string_tab[63]
#define __pyx_n_u_int __pyx_string_tab[64] #define __pyx_n_u_index __pyx_string_tab[64]
#define __pyx_n_u_is_coroutine __pyx_string_tab[65] #define __pyx_n_u_index_2 __pyx_string_tab[65]
#define __pyx_n_u_items __pyx_string_tab[66] #define __pyx_n_u_init __pyx_string_tab[66]
#define __pyx_n_u_main __pyx_string_tab[67] #define __pyx_n_u_int __pyx_string_tab[67]
#define __pyx_n_u_metaclass __pyx_string_tab[68] #define __pyx_n_u_is_coroutine __pyx_string_tab[68]
#define __pyx_n_u_module __pyx_string_tab[69] #define __pyx_n_u_items __pyx_string_tab[69]
#define __pyx_n_u_name __pyx_string_tab[70] #define __pyx_n_u_main __pyx_string_tab[70]
#define __pyx_n_u_new_block __pyx_string_tab[71] #define __pyx_n_u_metaclass __pyx_string_tab[71]
#define __pyx_n_u_nonce __pyx_string_tab[72] #define __pyx_n_u_module __pyx_string_tab[72]
#define __pyx_n_u_nonce_2 __pyx_string_tab[73] #define __pyx_n_u_name __pyx_string_tab[73]
#define __pyx_n_u_num __pyx_string_tab[74] #define __pyx_n_u_new_block __pyx_string_tab[74]
#define __pyx_n_u_pack __pyx_string_tab[75] #define __pyx_n_u_nonce __pyx_string_tab[75]
#define __pyx_n_u_parts __pyx_string_tab[76] #define __pyx_n_u_nonce_2 __pyx_string_tab[76]
#define __pyx_n_u_perform_hash __pyx_string_tab[77] #define __pyx_n_u_num __pyx_string_tab[77]
#define __pyx_n_u_polluck_blockchain_python_transl __pyx_string_tab[78] #define __pyx_n_u_pack __pyx_string_tab[78]
#define __pyx_n_u_pop __pyx_string_tab[79] #define __pyx_n_u_parts __pyx_string_tab[79]
#define __pyx_n_u_prefix __pyx_string_tab[80] #define __pyx_n_u_perf_counter __pyx_string_tab[80]
#define __pyx_n_u_prepare __pyx_string_tab[81] #define __pyx_n_u_perform_hash __pyx_string_tab[81]
#define __pyx_n_u_prev_hash __pyx_string_tab[82] #define __pyx_n_u_polluck_blockchain_python_transl __pyx_string_tab[82]
#define __pyx_n_u_prev_hash_2 __pyx_string_tab[83] #define __pyx_n_u_pop __pyx_string_tab[83]
#define __pyx_n_u_previous_hash __pyx_string_tab[84] #define __pyx_n_u_prefix __pyx_string_tab[84]
#define __pyx_n_u_print __pyx_string_tab[85] #define __pyx_n_u_prepare __pyx_string_tab[85]
#define __pyx_n_u_proof_of_work __pyx_string_tab[86] #define __pyx_n_u_prev_hash __pyx_string_tab[86]
#define __pyx_n_u_property __pyx_string_tab[87] #define __pyx_n_u_prev_hash_2 __pyx_string_tab[87]
#define __pyx_n_u_qualname __pyx_string_tab[88] #define __pyx_n_u_previous_hash __pyx_string_tab[88]
#define __pyx_n_u_return __pyx_string_tab[89] #define __pyx_n_u_print __pyx_string_tab[89]
#define __pyx_n_u_self __pyx_string_tab[90] #define __pyx_n_u_proof_of_work __pyx_string_tab[90]
#define __pyx_n_u_set_name __pyx_string_tab[91] #define __pyx_n_u_property __pyx_string_tab[91]
#define __pyx_n_u_setdefault __pyx_string_tab[92] #define __pyx_n_u_qualname __pyx_string_tab[92]
#define __pyx_n_u_setter __pyx_string_tab[93] #define __pyx_n_u_return __pyx_string_tab[93]
#define __pyx_n_u_sha256 __pyx_string_tab[94] #define __pyx_n_u_self __pyx_string_tab[94]
#define __pyx_n_u_slots __pyx_string_tab[95] #define __pyx_n_u_set_name __pyx_string_tab[95]
#define __pyx_n_u_startswith __pyx_string_tab[96] #define __pyx_n_u_setdefault __pyx_string_tab[96]
#define __pyx_n_u_str __pyx_string_tab[97] #define __pyx_n_u_setter __pyx_string_tab[97]
#define __pyx_n_u_struct __pyx_string_tab[98] #define __pyx_n_u_sha256 __pyx_string_tab[98]
#define __pyx_n_u_test __pyx_string_tab[99] #define __pyx_n_u_slots __pyx_string_tab[99]
#define __pyx_n_u_time __pyx_string_tab[100] #define __pyx_n_u_start __pyx_string_tab[100]
#define __pyx_n_u_timestamp __pyx_string_tab[101] #define __pyx_n_u_startswith __pyx_string_tab[101]
#define __pyx_n_u_timestamp_2 __pyx_string_tab[102] #define __pyx_n_u_str __pyx_string_tab[102]
#define __pyx_n_u_to_bytes __pyx_string_tab[103] #define __pyx_n_u_struct __pyx_string_tab[103]
#define __pyx_n_u_value __pyx_string_tab[104] #define __pyx_n_u_test __pyx_string_tab[104]
#define __pyx_n_u_values __pyx_string_tab[105] #define __pyx_n_u_time __pyx_string_tab[105]
#define __pyx_kp_b_iso88591_6_avQ __pyx_string_tab[106] #define __pyx_n_u_timestamp __pyx_string_tab[106]
#define __pyx_kp_b_iso88591_A_4z_1A_IQ __pyx_string_tab[107] #define __pyx_n_u_timestamp_2 __pyx_string_tab[107]
#define __pyx_kp_b_iso88591_A_A_N __pyx_string_tab[108] #define __pyx_n_u_to_bytes __pyx_string_tab[108]
#define __pyx_kp_b_iso88591_A_Ja __pyx_string_tab[109] #define __pyx_n_u_value __pyx_string_tab[109]
#define __pyx_kp_b_iso88591_A_Ja_N_1F_c_S_A_IQ_N_Ja_IQ __pyx_string_tab[110] #define __pyx_n_u_values __pyx_string_tab[110]
#define __pyx_kp_b_iso88591_A_Rt1_m1_z_AQ_q_1 __pyx_string_tab[111] #define __pyx_kp_b_iso88591_6_avQ __pyx_string_tab[111]
#define __pyx_kp_b_iso88591_A_WAT_Q_WA_1D_WAT_waq_WAT_G1A_WA __pyx_string_tab[112] #define __pyx_kp_b_iso88591_A_4z_1A_IQ __pyx_string_tab[112]
#define __pyx_kp_b_iso88591_A_q_xwm1_F __pyx_string_tab[113] #define __pyx_kp_b_iso88591_A_A_N __pyx_string_tab[113]
#define __pyx_kp_b_iso88591_A_t1 __pyx_string_tab[114] #define __pyx_kp_b_iso88591_A_Ja __pyx_string_tab[114]
#define __pyx_kp_b_iso88591_A_t1_2 __pyx_string_tab[115] #define __pyx_kp_b_iso88591_A_Ja_N_1F_c_S_A_IQ_N_Ja_IQ __pyx_string_tab[115]
#define __pyx_kp_b_iso88591_A_t1_3 __pyx_string_tab[116] #define __pyx_kp_b_iso88591_A_Rt1_m1_z_AQ_q_1 __pyx_string_tab[116]
#define __pyx_kp_b_iso88591_A_t1_4 __pyx_string_tab[117] #define __pyx_kp_b_iso88591_A_WAT_Q_WA_1D_WAT_waq_WAT_G1A_WA __pyx_string_tab[117]
#define __pyx_kp_b_iso88591_A_t_7 __pyx_string_tab[118] #define __pyx_kp_b_iso88591_A_q_xwm1_F __pyx_string_tab[118]
#define __pyx_kp_b_iso88591_A_t_Q __pyx_string_tab[119] #define __pyx_kp_b_iso88591_A_t1 __pyx_string_tab[119]
#define __pyx_kp_b_iso88591_A_xy_at1 __pyx_string_tab[120] #define __pyx_kp_b_iso88591_A_t1_2 __pyx_string_tab[120]
#define __pyx_kp_b_iso88591_ha_E_Qd_fBb_1A_F_QnAY_9_1_q __pyx_string_tab[121] #define __pyx_kp_b_iso88591_A_t1_3 __pyx_string_tab[121]
#define __pyx_kp_b_iso88591_A_t1_4 __pyx_string_tab[122]
#define __pyx_kp_b_iso88591_A_t_7 __pyx_string_tab[123]
#define __pyx_kp_b_iso88591_A_t_Q __pyx_string_tab[124]
#define __pyx_kp_b_iso88591_A_xy_at1 __pyx_string_tab[125]
#define __pyx_kp_b_iso88591_ha_E_Qd_fBb_M_1A_m3b_F_QnAYk_9K __pyx_string_tab[126]
#define __pyx_int_0 __pyx_number_tab[0] #define __pyx_int_0 __pyx_number_tab[0]
#define __pyx_int_1 __pyx_number_tab[1] #define __pyx_int_1 __pyx_number_tab[1]
#define __pyx_int_8 __pyx_number_tab[2] #define __pyx_int_8 __pyx_number_tab[2]
@ -2629,7 +2641,7 @@ static CYTHON_SMALL_CODE int __pyx_m_clear(PyObject *m) {
#endif #endif
for (int i=0; i<4; ++i) { Py_CLEAR(clear_module_state->__pyx_tuple[i]); } for (int i=0; i<4; ++i) { Py_CLEAR(clear_module_state->__pyx_tuple[i]); }
for (int i=0; i<17; ++i) { Py_CLEAR(clear_module_state->__pyx_codeobj_tab[i]); } for (int i=0; i<17; ++i) { Py_CLEAR(clear_module_state->__pyx_codeobj_tab[i]); }
for (int i=0; i<122; ++i) { Py_CLEAR(clear_module_state->__pyx_string_tab[i]); } for (int i=0; i<127; ++i) { Py_CLEAR(clear_module_state->__pyx_string_tab[i]); }
for (int i=0; i<5; ++i) { Py_CLEAR(clear_module_state->__pyx_number_tab[i]); } for (int i=0; i<5; ++i) { Py_CLEAR(clear_module_state->__pyx_number_tab[i]); }
/* #### Code section: module_state_clear_contents ### */ /* #### Code section: module_state_clear_contents ### */
/* CommonTypesMetaclass.module_state_clear */ /* CommonTypesMetaclass.module_state_clear */
@ -2655,7 +2667,7 @@ static CYTHON_SMALL_CODE int __pyx_m_traverse(PyObject *m, visitproc visit, void
__Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_unicode); __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_unicode);
for (int i=0; i<4; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_tuple[i]); } for (int i=0; i<4; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_tuple[i]); }
for (int i=0; i<17; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_codeobj_tab[i]); } for (int i=0; i<17; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_codeobj_tab[i]); }
for (int i=0; i<122; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_string_tab[i]); } for (int i=0; i<127; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_string_tab[i]); }
for (int i=0; i<5; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_number_tab[i]); } for (int i=0; i<5; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_number_tab[i]); }
/* #### Code section: module_state_traverse_contents ### */ /* #### Code section: module_state_traverse_contents ### */
/* CommonTypesMetaclass.module_state_traverse */ /* CommonTypesMetaclass.module_state_traverse */
@ -5641,6 +5653,8 @@ PyObject *__pyx_args, PyObject *__pyx_kwds
static PyObject *__pyx_pf_18polluck_blockchain_16python_translate_10Blockchain_6add_block(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_data) { static PyObject *__pyx_pf_18polluck_blockchain_16python_translate_10Blockchain_6add_block(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_data) {
PyObject *__pyx_v_new_block = NULL; PyObject *__pyx_v_new_block = NULL;
PyObject *__pyx_v_start = NULL;
PyObject *__pyx_v_elapsed = NULL;
PyObject *__pyx_r = NULL; PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations __Pyx_RefNannyDeclarations
PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_1 = NULL;
@ -5652,7 +5666,7 @@ static PyObject *__pyx_pf_18polluck_blockchain_16python_translate_10Blockchain_6
PyObject *__pyx_t_7 = NULL; PyObject *__pyx_t_7 = NULL;
size_t __pyx_t_8; size_t __pyx_t_8;
int __pyx_t_9; int __pyx_t_9;
PyObject *__pyx_t_10[4]; PyObject *__pyx_t_10[6];
int __pyx_lineno = 0; int __pyx_lineno = 0;
const char *__pyx_filename = NULL; const char *__pyx_filename = NULL;
int __pyx_clineno = 0; int __pyx_clineno = 0;
@ -5730,78 +5744,158 @@ static PyObject *__pyx_pf_18polluck_blockchain_16python_translate_10Blockchain_6
__pyx_v_new_block = __pyx_t_1; __pyx_v_new_block = __pyx_t_1;
__pyx_t_1 = 0; __pyx_t_1 = 0;
/* "polluck_blockchain/python_translate.py":132
* )
*
* start = time.perf_counter() # <<<<<<<<<<<<<<
* new_block.hash = self.proof_of_work(new_block)
* elapsed = time.perf_counter() - start
*/
__pyx_t_3 = NULL;
__Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_time); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 132, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_7);
__pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_perf_counter); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 132, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_6);
__Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
__pyx_t_8 = 1;
#if CYTHON_UNPACK_METHODS
if (unlikely(PyMethod_Check(__pyx_t_6))) {
__pyx_t_3 = PyMethod_GET_SELF(__pyx_t_6);
assert(__pyx_t_3);
PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_6);
__Pyx_INCREF(__pyx_t_3);
__Pyx_INCREF(__pyx__function);
__Pyx_DECREF_SET(__pyx_t_6, __pyx__function);
__pyx_t_8 = 0;
}
#endif
{
PyObject *__pyx_callargs[2] = {__pyx_t_3, NULL};
__pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_6, __pyx_callargs+__pyx_t_8, (1-__pyx_t_8) | (__pyx_t_8*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET));
__Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 132, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
}
__pyx_v_start = __pyx_t_1;
__pyx_t_1 = 0;
/* "polluck_blockchain/python_translate.py":133 /* "polluck_blockchain/python_translate.py":133
* *
* # start = time.perf_counter() * start = time.perf_counter()
* new_block.hash = self.proof_of_work(new_block) # <<<<<<<<<<<<<< * new_block.hash = self.proof_of_work(new_block) # <<<<<<<<<<<<<<
* # elapsed = time.perf_counter() - start * elapsed = time.perf_counter() - start
* *
*/ */
__pyx_t_3 = __pyx_v_self; __pyx_t_6 = __pyx_v_self;
__Pyx_INCREF(__pyx_t_3); __Pyx_INCREF(__pyx_t_6);
__pyx_t_8 = 0; __pyx_t_8 = 0;
{ {
PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_v_new_block}; PyObject *__pyx_callargs[2] = {__pyx_t_6, __pyx_v_new_block};
__pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_proof_of_work, __pyx_callargs+__pyx_t_8, (2-__pyx_t_8) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_proof_of_work, __pyx_callargs+__pyx_t_8, (2-__pyx_t_8) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET));
__Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 133, __pyx_L1_error) if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 133, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1); __Pyx_GOTREF(__pyx_t_1);
} }
if (__Pyx_PyObject_SetAttrStr(__pyx_v_new_block, __pyx_mstate_global->__pyx_n_u_hash_2, __pyx_t_1) < (0)) __PYX_ERR(0, 133, __pyx_L1_error) if (__Pyx_PyObject_SetAttrStr(__pyx_v_new_block, __pyx_mstate_global->__pyx_n_u_hash_2, __pyx_t_1) < (0)) __PYX_ERR(0, 133, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
/* "polluck_blockchain/python_translate.py":134
* start = time.perf_counter()
* new_block.hash = self.proof_of_work(new_block)
* elapsed = time.perf_counter() - start # <<<<<<<<<<<<<<
*
* self.chain.append(new_block)
*/
__pyx_t_6 = NULL;
__Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_time); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 134, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_perf_counter); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 134, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_7);
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_t_8 = 1;
#if CYTHON_UNPACK_METHODS
if (unlikely(PyMethod_Check(__pyx_t_7))) {
__pyx_t_6 = PyMethod_GET_SELF(__pyx_t_7);
assert(__pyx_t_6);
PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_7);
__Pyx_INCREF(__pyx_t_6);
__Pyx_INCREF(__pyx__function);
__Pyx_DECREF_SET(__pyx_t_7, __pyx__function);
__pyx_t_8 = 0;
}
#endif
{
PyObject *__pyx_callargs[2] = {__pyx_t_6, NULL};
__pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_7, __pyx_callargs+__pyx_t_8, (1-__pyx_t_8) | (__pyx_t_8*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET));
__Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
__Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 134, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
}
__pyx_t_7 = PyNumber_Subtract(__pyx_t_1, __pyx_v_start); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 134, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_7);
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_v_elapsed = __pyx_t_7;
__pyx_t_7 = 0;
/* "polluck_blockchain/python_translate.py":136 /* "polluck_blockchain/python_translate.py":136
* # elapsed = time.perf_counter() - start * elapsed = time.perf_counter() - start
* *
* self.chain.append(new_block) # <<<<<<<<<<<<<< * self.chain.append(new_block) # <<<<<<<<<<<<<<
* # print(f"Mined block {new_block.index} in {elapsed:.3f}s with nonce={new_block.nonce}") * print(f"Mined block {new_block.index} in {elapsed:.3f}s with nonce={new_block.nonce}")
* print(f"Mined block {new_block.index} with nonce={new_block.nonce}") *
*/ */
__pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_chain); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 136, __pyx_L1_error) __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_chain); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 136, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1); __Pyx_GOTREF(__pyx_t_7);
__pyx_t_9 = __Pyx_PyObject_Append(__pyx_t_1, __pyx_v_new_block); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(0, 136, __pyx_L1_error) __pyx_t_9 = __Pyx_PyObject_Append(__pyx_t_7, __pyx_v_new_block); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(0, 136, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
/* "polluck_blockchain/python_translate.py":138 /* "polluck_blockchain/python_translate.py":137
*
* self.chain.append(new_block) * self.chain.append(new_block)
* # print(f"Mined block {new_block.index} in {elapsed:.3f}s with nonce={new_block.nonce}") * print(f"Mined block {new_block.index} in {elapsed:.3f}s with nonce={new_block.nonce}") # <<<<<<<<<<<<<<
* print(f"Mined block {new_block.index} with nonce={new_block.nonce}") # <<<<<<<<<<<<<<
* *
* return new_block * return new_block
*/ */
__pyx_t_3 = NULL; __pyx_t_1 = NULL;
__pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_new_block, __pyx_mstate_global->__pyx_n_u_index); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 138, __pyx_L1_error) __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_new_block, __pyx_mstate_global->__pyx_n_u_index); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 137, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_7);
__pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_t_7, __pyx_mstate_global->__pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 138, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_6); __Pyx_GOTREF(__pyx_t_6);
__Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __pyx_t_3 = __Pyx_PyObject_FormatSimple(__pyx_t_6, __pyx_mstate_global->__pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 137, __pyx_L1_error)
__pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_new_block, __pyx_mstate_global->__pyx_n_u_nonce); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 138, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3);
__Pyx_GOTREF(__pyx_t_7);
__pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_7, __pyx_mstate_global->__pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 138, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
__pyx_t_10[0] = __pyx_mstate_global->__pyx_kp_u_Mined_block;
__pyx_t_10[1] = __pyx_t_6;
__pyx_t_10[2] = __pyx_mstate_global->__pyx_kp_u_with_nonce;
__pyx_t_10[3] = __pyx_t_4;
__pyx_t_7 = __Pyx_PyUnicode_Join(__pyx_t_10, 4, 12 * 2 + __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6) + __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4), 127 | __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) | __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4));
if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 138, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_7);
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
__pyx_t_6 = __Pyx_PyObject_Format(__pyx_v_elapsed, __pyx_mstate_global->__pyx_kp_u_3f); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 137, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_6);
__pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_new_block, __pyx_mstate_global->__pyx_n_u_nonce); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 137, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__pyx_t_2 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_mstate_global->__pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 137, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__pyx_t_10[0] = __pyx_mstate_global->__pyx_kp_u_Mined_block;
__pyx_t_10[1] = __pyx_t_3;
__pyx_t_10[2] = __pyx_mstate_global->__pyx_kp_u_in;
__pyx_t_10[3] = __pyx_t_6;
__pyx_t_10[4] = __pyx_mstate_global->__pyx_kp_u_s_with_nonce;
__pyx_t_10[5] = __pyx_t_2;
__pyx_t_4 = __Pyx_PyUnicode_Join(__pyx_t_10, 6, 12 + __Pyx_PyUnicode_GET_LENGTH(__pyx_t_3) + 4 + __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6) + 13 + __Pyx_PyUnicode_GET_LENGTH(__pyx_t_2), 127 | __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_3) | __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) | __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2));
if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 137, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_t_8 = 1; __pyx_t_8 = 1;
{ {
PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_t_7}; PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_t_4};
__pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_builtin_print, __pyx_callargs+__pyx_t_8, (2-__pyx_t_8) | (__pyx_t_8*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); __pyx_t_7 = __Pyx_PyObject_FastCall((PyObject*)__pyx_builtin_print, __pyx_callargs+__pyx_t_8, (2-__pyx_t_8) | (__pyx_t_8*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET));
__Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
__Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 138, __pyx_L1_error) if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 137, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1); __Pyx_GOTREF(__pyx_t_7);
} }
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
/* "polluck_blockchain/python_translate.py":140 /* "polluck_blockchain/python_translate.py":139
* 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 # <<<<<<<<<<<<<< * return new_block # <<<<<<<<<<<<<<
*/ */
@ -5830,6 +5924,8 @@ static PyObject *__pyx_pf_18polluck_blockchain_16python_translate_10Blockchain_6
__pyx_r = NULL; __pyx_r = NULL;
__pyx_L0:; __pyx_L0:;
__Pyx_XDECREF(__pyx_v_new_block); __Pyx_XDECREF(__pyx_v_new_block);
__Pyx_XDECREF(__pyx_v_start);
__Pyx_XDECREF(__pyx_v_elapsed);
__Pyx_XGIVEREF(__pyx_r); __Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext(); __Pyx_RefNannyFinishContext();
return __pyx_r; return __pyx_r;
@ -6792,7 +6888,7 @@ __Pyx_RefNannySetupContext("PyInit_python_translate", 0);
static int __Pyx_InitCachedBuiltins(__pyx_mstatetype *__pyx_mstate) { static int __Pyx_InitCachedBuiltins(__pyx_mstatetype *__pyx_mstate) {
CYTHON_UNUSED_VAR(__pyx_mstate); CYTHON_UNUSED_VAR(__pyx_mstate);
__pyx_builtin_property = __Pyx_GetBuiltinName(__pyx_mstate->__pyx_n_u_property); if (!__pyx_builtin_property) __PYX_ERR(0, 59, __pyx_L1_error) __pyx_builtin_property = __Pyx_GetBuiltinName(__pyx_mstate->__pyx_n_u_property); if (!__pyx_builtin_property) __PYX_ERR(0, 59, __pyx_L1_error)
__pyx_builtin_print = __Pyx_GetBuiltinName(__pyx_mstate->__pyx_n_u_print); if (!__pyx_builtin_print) __PYX_ERR(0, 138, __pyx_L1_error) __pyx_builtin_print = __Pyx_GetBuiltinName(__pyx_mstate->__pyx_n_u_print); if (!__pyx_builtin_print) __PYX_ERR(0, 137, __pyx_L1_error)
/* Cached unbound methods */ /* Cached unbound methods */
__pyx_mstate->__pyx_umethod_PyDict_Type_items.type = (PyObject*)&PyDict_Type; __pyx_mstate->__pyx_umethod_PyDict_Type_items.type = (PyObject*)&PyDict_Type;
@ -6880,34 +6976,34 @@ static int __Pyx_InitCachedConstants(__pyx_mstatetype *__pyx_mstate) {
static int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate) { static int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate) {
CYTHON_UNUSED_VAR(__pyx_mstate); CYTHON_UNUSED_VAR(__pyx_mstate);
{ {
const struct { const unsigned int length: 8; } index[] = {{0},{1},{13},{12},{9},{179},{5},{1},{8},{2},{17},{42},{12},{5},{14},{19},{18},{24},{10},{10},{11},{11},{15},{15},{10},{19},{20},{31},{24},{4},{20},{9},{6},{18},{3},{5},{10},{5},{18},{12},{18},{20},{4},{5},{8},{10},{6},{7},{11},{20},{6},{6},{5},{14},{13},{8},{7},{5},{4},{7},{9},{5},{6},{8},{3},{13},{5},{8},{13},{10},{8},{9},{5},{6},{3},{4},{5},{13},{35},{3},{6},{11},{10},{9},{13},{5},{13},{8},{12},{6},{4},{12},{10},{6},{6},{9},{10},{3},{6},{8},{4},{9},{10},{8},{5},{6},{18},{36},{25},{12},{76},{54},{107},{51},{12},{12},{12},{9},{15},{15},{20},{101}}; const struct { const unsigned int length: 8; } index[] = {{0},{1},{3},{13},{12},{9},{179},{5},{1},{8},{2},{17},{4},{13},{42},{5},{14},{19},{18},{24},{10},{10},{11},{11},{15},{15},{10},{19},{20},{31},{24},{4},{20},{9},{6},{18},{3},{5},{10},{5},{18},{12},{18},{20},{4},{5},{8},{10},{6},{7},{11},{20},{7},{6},{6},{5},{14},{13},{8},{7},{5},{4},{7},{9},{5},{6},{8},{3},{13},{5},{8},{13},{10},{8},{9},{5},{6},{3},{4},{5},{12},{13},{35},{3},{6},{11},{10},{9},{13},{5},{13},{8},{12},{6},{4},{12},{10},{6},{6},{9},{5},{10},{3},{6},{8},{4},{9},{10},{8},{5},{6},{18},{36},{25},{12},{76},{54},{107},{51},{12},{12},{12},{9},{15},{15},{20},{128}};
#if (CYTHON_COMPRESS_STRINGS) == 2 /* compression: bz2 (1120 bytes) */ #if (CYTHON_COMPRESS_STRINGS) == 2 /* compression: bz2 (1150 bytes) */
const char* const cstring = "BZh91AY&SY3\223e\276\000\000\201\177\377\365\177\367\375\177\363\367\363\277\263~\241\277\377\377\360@@@@@@@@@@@@@\000@\000P\003\375\331PtQ$\273\235\303T\332\024\320\217!\2420OB\017S@\003L\2004\0324h\320\321\241\240\r\036\246\230\2156PJ\232M\030\010\324\322mI\246\324\323\322\000\032\000\001\240\000\000\000\000\000\001\240\224\321\010\002F\r\024\217\325<\246\365OPh\320\320\320\320\000z\200\000\000\001\246\214\2327\252a\246\251\004\032\030\203\020h\300\203!\204\001\21012\014&\201\202i\221\211\202yF\207\000\000\003@\000\006F\206@\000\000\000\00022\000\000\310^\301n\364\277\204+\372\303\030Q\0062\010(J\002\n\002\010\004\246XU`\311\240-(\rd3\022CD\353\036\0064j\210\326\322\035fl\307\007,\300\272\201R\220A\txD\370\306\021\2103\0052\203\365L\016J<\030\3121b\327\333s\354\267\267\351\352\366\202m\331C\365S\372t\013\213\256rUUp\031`b\033\010\300\214CN)$!\303\343\267@\341 \317\246M\360\257\016\034\230i#'yI\302\035?]\373W\340\231a\235\263\303\230\365\376.~\037\007\302\366\357\237<g1,J\005\220e\234\001\006\n:`\017\022{B+\004\342\305^Tw\257\207\364\024\264R\341}&0\205YT kn\207\337&\374\2453+.(\241E\213\245\034\335\207\017\"\266+\205c\025d\340\346N\332\266\301.l\225\305r\245\"\274\243\305_U*\016\233\254\207\341\270\351\021\311{Z.\343\360E\212\222\220\361\232\201zJ/\304\342\252l\031\325Z\002\206h:\237\355PYO\316\246l\313\314\352q\227\265\201>^\256&\234JQ\231\263\021\301\264K'h\324X\360\022\257?{\270\350\364\\{v\032\216\341\320\323#B\346A\010+\343\315\2547*\331\264\274\231\232\361\014M\010\3260\312X\330TN\325A.\023\204\267\246\n[^\366I\202+\335n}\357\010l\26324Ga\236\335\324\344\215\351a\273d\332cJr\022\341\034Tu\247\266\251%lX__,\177]\363ad\215\324\035Z'\271\0100\256\034\035\367P\222\200w\254$\251\203a\376c\247\263\241\302\016M\357\215\227\030l\337\211d26\327Fm@<\316D7\030\202&#[\263\262\002B\205G\336t\271\310g<Q\230\010\244\327T\177+4#X%\031\260\215\332H556\277\020\257<Z\314\327 \004\232\243\216F\251l4Vi\354\263\010I\220!\"\311m\264\324Au\347\025$\311\233\333I\332\245xT\266\220""\361A\207jY]r\r\364\252\264\354\244\346\224@T\354N[y\247\255cB\242\276\236\263\222Nf6\246a\262\315u\t\231J\302\335z\243@\233\025d\215\023Dx\326\245\271!\002\340\277;\025\2641<\305\362vJ\332\334\021\252^H\330IC \230;s\246N\nL\266\340c\245\351\004\006\216\027pt6CA9\332;\330;\334\345\311\370\3450\265\346S^U\230\342UU\303d\231\207\n\211\274\002\031\325\rtr*\243\245\341]\201rw\342/\245L\224\230\342\205\010\205\300\216z\337\rr\256F(\262aR\227\000\302\365\264\276\331\220\224K)E\251\241]1A\"\"\336\334\005d\335;\233\021\303\320\315\245Kn\320\317\215\340\205\341,\027D\306\314f\211\362\323b\255\004\314\367up.\275\315\001\332\241L,;\037\242\324\237\266\235\322#\3549\376\324\200\020\213\351\004\022\315\032\251\032\262\205\004`tB,\203\334q\213eO\304\n\332!\237\027\265\356\230\263\207\305 \357\235D7UD\2325\021>\301\314c\225\331\024\032\245ND\230\367-\311g\331\221\255\"\250\270.\2734Y\336\210L/\311U\256\235\254\221{\024V\2013\230@R\376\220\264\264\346\246_\250\276C\227\2409N\r\027o\237\204\322\330\326f\245Z\315\243|6r5!X\210\344zt%\"\002JF\232\026Jo:(\241\216!Uu8.\350\273\222)\302\204\201\234\233-\360"; const char* const cstring = "BZh91AY&SY\357?\217\017\000\000\205\177\377\365\177\367\375~\363\377\363\277\273\177\241\277\377\377\360@@@@@@@@@@@@@\000@\000P\004\033l5\022\000\245\2105\004I\247\244\031= \364\321\003#L\200\r6\240\365\003C\3244\036\243@=A\221\352=\rA\352~\224\022\204& \0021L\204\332\246\324\3204\0004\032\000\000\000\000\000\036\243A\2104\321\004\320\325Oh$\3654=4\214C@\032\000\000\r\000\006\201\240\001\265\032d\303P\343C@\032\000\032\000\000\000\r\000\000\000\000\310\000\000b\001\306\206\2004\0004\000\000\000\032\000\000\000\001\220\000\000\304\007l\370\323WY66\237\257\215\223\031\004\202\n\000A@A\010JR\355\221j\300l\200\022n\020\032\022\031\302\031ms\263I\300p\267%\307e\251U\260\200P+\206\016\222\014e\nP\261\206\034\204\361\002\227\005\0071\"\t\244U\313V\336\244\353\314\327\261\027UH\217\272\234h\251\215\206p\326\243p\313\030\265X.\r\351\031\004*\215\013\352\360_\224\272\234\345\016qZ8:zS\355\333\335\333$\214\205Vz\200\314WQu\253\231C;i\216\3070\305\206\036]\034~/\"\2775\372\rtZ\022(&\343<hK\210K\010\027\271\271\302\375\325\333\232\3600\344\321!\263c\340\270mj>\370\271\235\0279.\224\322\256S\203f\301>Nx\277]\002\005\213Ts\333\231\211@\337`i \223\315(%\304\300\307\023&\273\334?\237r\330I\364P\351nv\253\362\321\020\352\262\3527k\224\356\307O\232\264\250\035\245\333\"\223\0278+Z\200\023$\264\351\026r^\200]1\274\004\005\214!\261\026%G\335\024K\227\305\360\260+I\2048x\326\233;W\021\"\210\227\216zb\375\031\035\260\2338\037,x\371\016\237M\206\247Si\3317\354y\222\365\024\034\241#\013\263\016E\222&\306z\"V(\204\024S1\347\031Dir\255\226\245+p\276\033MsF\214\346\317\255\225?\013o\334\246\220\016\377-\325Xh\334\334\303VTY\263\t\236\r\323\321\341\034\367\002v\332\312\"\306\366\271\213\214 \351\n\327-\261e$\344\344\301\004S V\242\010\021Y\200\253\202\001\305\200U\220=h\251+\354[\263\243\362\3317\204\016nv\272\252\013x\271\356&\344St\250D\314\006\201\314\242b(:\002\23222(-7\216:,\276\351)\266h\034\213\300\n\326\326u}\2067\327\000\\\037\322\256\372\324\212\355L\373\322X\272\224D\251@\027\250""\347$\214\\f\376#d\315\275\010\202\212\250\240\242\2517\356\244\314qU\206\024\017E\023\325Ud\212\326\021]\373\307\2720Q\006H\3239\274;\232#%dW\261\232\216\010\262\020~\376\352\032\255\324\021\251g\340jp{\027\033\325\020M{\213\360-9H\005\333\322\254\002\307\245\025\234\207\03121[s}4\227\006;p\267v\0065\030\376\223\322\022\216\253\024l\353\214K\020\205+\244\371x\313\n\221n\253#+\361ZT\"\222\032\340\335\253\221\304!J3Lf\251\251Z\225\330B\200\252\005\031\325\244\312m)\225bh\250\203\004HC\370\200@G\275\242/\320\241\235\005'>v\205eVbp\212\022\340\226\330\261\"\300\r\022YQNJZX!\033\001\310\325\006\2314L\256\264\246\312\212/\265\222!\013\347\202T+N:\t\237V^}D\211\251\303\245}\267n\247E\304\024\304+\315\257\\\237\221\2248Q\252\311B\0065tf*\255E\3205`!9\014_S\220W\\\252\222\033\3344Q\007\274#\275!\007t\351\372\t\031(p\021\220Y \220\020y\206\365\203\245?\321\007\335\202\210\364\336\357\263QjA\336!\017\247B_5\210\231eo\002\323p\030\346~[\023\332\252\274\271KZ^ey\201\212\253\266-\207\341j\210\366\251\200i1\371\033\352\206\205m\301D~\344\016\313\351\312\211\004\203LY\273\355b5\t\334\363\321\370\204^\362\227\177%\230\022h\263UBZ'A\343z>\330\365yT\274\023(\250\244\367\253\254T\rq\031\204B\271\310h\220\"_F6\203*\037\370\273\222)\302\204\207y\374xx";
PyObject *data = __Pyx_DecompressString(cstring, 1120, 2); PyObject *data = __Pyx_DecompressString(cstring, 1150, 2);
if (unlikely(!data)) __PYX_ERR(0, 1, __pyx_L1_error) if (unlikely(!data)) __PYX_ERR(0, 1, __pyx_L1_error)
const char* const bytes = __Pyx_PyBytes_AsString(data); const char* const bytes = __Pyx_PyBytes_AsString(data);
#if !CYTHON_ASSUME_SAFE_MACROS #if !CYTHON_ASSUME_SAFE_MACROS
if (likely(bytes)); else { Py_DECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) } if (likely(bytes)); else { Py_DECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) }
#endif #endif
#elif (CYTHON_COMPRESS_STRINGS) != 0 /* compression: zlib (1028 bytes) */ #elif (CYTHON_COMPRESS_STRINGS) != 0 /* compression: zlib (1064 bytes) */
const char* const cstring = "x\332uTAo\3336\024N\207b\260W\267\211\215\264\311\222a`\326nY\006\324\235\207\254\353\006\254\203\2636E\007,\210\273\016\303.%h\211\212\271H\244\"R\261\265\323\216>\362\310\243\216:\346\230c\216;\346\250\243\177B\177\302\036\251\330N\226\326\260\237\037\037\037\371\276\357{O\372\372\005\345T2\211vB\341\035\376\3128\365Q\337\272hO \251\022\306\017\366\204\242H\r\210B?gj 8\202l\237\206\254O\023\242h\230\2714O\321\304&q\264\377|\377\341\366\223mD\270\217\022\372\027\365\224D2\355{!\221\222J$\002\324OY\250\030G*\213\251l\243\227\001\312D\2128\205\322J\240\030\362.\037P\003\312\221\244\312:h\223p.\024QLp\014\307\001\335&\362Y\002E\3301\265\247wI(i\373\367\327\273\017\237\374D|\037C6}\352\373\000T\261\210\266\247\216L\274G\261\010\303\324;\304\216\2567 \214?\212\035A\254\022\302e\010\251\3558CC\246\006\210\013\356\321\037\235F\316\2641f\234)\214/V1M\002\221Dx@\344\240\ny\"\212SE\337\023\301\375LQY\305\001\023\251\274y.\343>\035U\256+]\271qB\217/]\350\210(\022\305;3\006s\357*\302*d\005\351\3178T1/\241@\024\037Tcpm;N\204\0100|\207\"9\334\023\234b\274\237\215\340\367\014Z\216\367\350H\275\242\301\354^\022\307\224\373Df\334c\002\010'\"\205FS\331g\007n\337\031\307\300\335\356\205\260\t0\255\340\036\355\023(zI\243\353z\275\013\253U\017[3m\255\317\202\200yi\2502\237\035\200>\030\373\302\263&V\270O$\363\344%w6\020\224{\302\247@\007\360\007\241 \312\031\254DU9HD4\223\033\343 \345p\345\024\207\0058\375\301c1\240\243\252\262k\"\256\354E3\030W\030N\314\224a\212F\022\343\010\304\300\360\211\250\"n\356\335B\370iH\255\307I\004\377\234\016+\312n\"\260\263<\215b\220-&\211\222W\206\360\372p\267\377?\334\261\210a\240\002\006\340\340\037\256\260\265f#v\305a\"\225\027\013`pe&`\001uU\206\361QJ\302\niBU\232pI\303\000cxr/\360\203\347\303\254@g\300\203\327\205\034\220o\276}\014\361P\000x\014\322\002\t\373\264\301\373\004\276)\314\027V\256\201V\371\271\3723o\332\234c\022\246\324\031y\276\260jn\2247o\215\037\353\273\232\350c\323\373\247[\256}\226o\224\265[\343\355\361\337\246i6\363f\331h\351-\3231""\335\262\326\030\277\324\2203\251-\353nY\377\010\002\347\rH\237\300\306\236\331\200\303\353\237\330\244_4\201\244\305\245\362\316b\271\262Z..M\252`\351\362\276\314\267\212N\261{\362\340\304;]>\375\355\354\203\263\257\376\355N\252\273\253\214\215r\236_\025\204\273l\271\246^\326\257\2642\235\262V/\033\037\233\273&*:ec\021\240\256\347\335\274W.\255\350\243\262\321\324k\246\003hjK\272n\232e\355\366\370\017\335\325\257\315J^/\232\305\375\2427\r\275\311;\371\263\342\306<\343\236\031\346$?\232\007\326\363\027\000\266\373\216;&\265\305\361P\037\230\236!\266TK\177nK\267\364\206\255\017\242\255\001\r\273\264y#=tH\201\317\256\336\004Y\255V\240\014l)m\221\336[\231\373V\303\013\1772\013:\347i\336\312\277+6./\177(z\263##\235\345w\nR\250\223\316\371\315O\315 \007\001\227\365s\343:x_\367\264o\346\340\036\230 \337\311\373@\336\202|[[\250\267\364\252Y6o,\335\267\037.\324oO\241N\200{o\314M\327\374y\376\305\367\247\315\323\255\263\216\005v\364\037\302\362\302\362"; const char* const cstring = "x\332uT1o\0337\024N\n\243\220\0335\266\014'v\355\242\240\033\027n\nD\251\0327M\0134\205\334\304\201[D\260\322\244E\227\020\324\035\317b}G\236\217<K\327\251\243F\216\034o\274\321c\306\214\036=\336\250\237\320\237\320G\236%\331qjHO\217\217\217|\337\367\275G\177\335|\020<\243\234J&\321N(\274\303\347\214S\037\365\254\213:\002I\2250~\320\021\212\"\325'\n\375\234\251\276\340\010\262}\032\262\036M\210\242a\346\322<E\023\233\304\321\376\323\375{\333\217\266\021\341>J\350_\324S\022\311\264\347\205DJ*\221\010P/e\241b\034\251,\246\262\211\366\002\224\211\024q\n\245\225@1\344]<\240\372\224#I\225u\320\026\341\\(\242\230\340\030\216\003\272-\344\263\004\212\260cjO\357\222P\322\346\253\227\273\367\036\375D|\037C6}\354\373\000T\261\2106'\016\202\362\022\r\230\352#.\270G\177\224\211w?\026a\230z\207\330\361\367\372\204\361\373\261c\214UB\270\014\341l3\316\234P\31641f\234)\214\317W1M\002\221D\270Od\277\ny\"\212SE\377'\202{\231\242\262\212\0030Ry\263\\\306}:\254\\\007\262r\343\204\036_\270\320\262\221\212D\361\316\024\365\314\273\214\260\nYUzS\016U\314K(\220\303\007\325,\\\331\216\023!\002\014\237\201H\016;\202S\214\367\263!|\237@\337q\207\016\325\013\032L\357%qL\271Od\306=&\200p\"R\3506\225=v\340\366\235q\014\334\355^\010\233\000\323\212\354\321\036\201\242\0274\272\252\327\373\260Z\365\2605\223\376\372,\010\230\227\206*\363\331\001\350\203\261/<kb\205{D2O^p\247SAC\022K\352S\356\t\237\002+\240\021\204\202(g\260\022\025\200 \021\321Tu\214\203\224\303\315\0238\026\347\344\013O\244O\207\025\000\327K\\\331\363\2360\2560\234\230\n\304\024\215$\306\021h\202\341/\242\212\2707\340\026\302OCj=N\"\370\345tP1w\203\201\235\345i\024\203z1I\224\264\243\0107\247\034\236\345\245\271\274:\343\315wg<\0261\314X\300\000(\374\302u\266\356t\352.9L\244\362|\001l.\215\t,\240\256\3120>JIX\241N\250J\023.i\030`\014/\372\234\013x>\214\0174\013<\300+\373\344\233o\037B<\024\n\310\203\314@\310\031\373^\341\237\r|R\230;\254\\cm+f\355\230z\223n\035\2230\245\316\310\263k\253\346z9wc\364P\337\322D\037\233\356?\355r""\355\363|\243\254\335\030m\217\3766\r\263\2257\312\372\222\276kZ\246]\326\352\243=\r9\343\332\262n\227\363\037A\340\254\016\351c\330\350\230\r8\274\376\251M\372E\023HZX,o.\224+\253\345\302\342\270\n\226.\357\313\374n\321*vO6O\2747\313o~{\373\301\333\257N\333\343\352\356*c\243\234\345W\005\341.[\256\241\227\365\013\255L\253\254\315\227\365O\314-\023\025\255\262\276\000P\327\363v\336-\027W\364QYo\3505\323\0024\265E=o\032e\355\343\321\037\272\255_\232\225|\276h\024w\212\356$\364:o\345O\212\353\263\214\333f\220\223\374h\026X\317\237\001\330\366{\356\030\327\026F\003}`\272\206\330RK\372\013[zIo\330\372 \332\032\320\260K\2337\324\003\207\024\370\354\352-\220\325j\005\312\300\226\322\026\351\355\225\231o5<\367\307\323\240s\036\347K\371w\305\306\305\345\017Ewzd\250\263\374fA\nu\322:\233\373\314\364s\020pY?5\256\203wtW\373f\006n\323\004\371N\336\003\362\026\344\277\037^\233o\3509\375\034\332\r*\257\232e\363\272\342\275\2447u\224?\260\231\343\031|\253Gw\304M\333\374\231\037\2364N\266\316\276\377\365\264u\272w\366\352w\213\371\350?\r@\333\036";
PyObject *data = __Pyx_DecompressString(cstring, 1028, 1); PyObject *data = __Pyx_DecompressString(cstring, 1064, 1);
if (unlikely(!data)) __PYX_ERR(0, 1, __pyx_L1_error) if (unlikely(!data)) __PYX_ERR(0, 1, __pyx_L1_error)
const char* const bytes = __Pyx_PyBytes_AsString(data); const char* const bytes = __Pyx_PyBytes_AsString(data);
#if !CYTHON_ASSUME_SAFE_MACROS #if !CYTHON_ASSUME_SAFE_MACROS
if (likely(bytes)); else { Py_DECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) } if (likely(bytes)); else { Py_DECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) }
#endif #endif
#else /* compression: none (1806 bytes) */ #else /* compression: none (1865 bytes) */
const char* const bytes = "0Genesis BlockMined block No stringNote that Cython is deliberately stricter than PEP-484 and rejects subclasses of builtin types. If you need to pass subclasses then set the 'annotation_typing' directive to False.UTF-8?add_note>ddatetime.datetimesrc/polluck_blockchain/python_translate.py with nonce=BlockBlock.__init__Block._perform_hashBlock.compute_hashBlock.compute_hash_bytesBlock.dataBlock.hashBlock.indexBlock.nonceBlock.prev_hashBlock.timestampBlockchainBlockchain.__init__Blockchain.add_blockBlockchain.create_genesis_blockBlockchain.proof_of_workNone__Pyx_PyDict_NextRefadd_blockappendasyncio.coroutinesbigblockblock_hashchaincline_in_tracebackcompute_hashcompute_hash_bytescreate_genesis_blockdata_datadatetimedifficultydigest__doc__dopt_basicsdopt_basics.datetimeencodeextendfloatfloat_to_bytesfromtimestamp__func__genesis_hashhashhashlibhexdigestindex_index__init__int_is_coroutineitems__main____metaclass____module____name__new_blocknonce_noncenumpackparts_perform_hashpolluck_blockchain.python_translatepopprefix__prepare___prev_hashprev_hashprevious_hashprintproof_of_workproperty__qualname__returnself__set_name__setdefaultsettersha256__slots__startswithstrstruct__test__timetimestamp_timestampto_bytesvaluevalues\320\000\030\230\001\330\004\013\2106\220\025\220a\220v\230Q\200A\330\032\"\240!\330\010\013\2104\210z\230\021\230'\240\021\330\014\022\220)\2301\230A\330\010\014\210I\220Q\200A\340\010\024\220A\330\t\n\330\010\014\320\014\"\240!\340\010\014\210N\230!\200A\330\033\034\330\010\014\210J\220a\200A\340\017\020\330\016\017\330\027\030\330\017\020\340\010\014\210J\220a\330\010\014\210N\230(\240)\2501\250F\260$\260c\270\024\270S\300\002\300*\310A\340\010\014\210I\220Q\330\010\014\210N\230!\330\010\014\210J\220a\330\010\014\210I\220Q\200A\340\017\020\330\t\n\330\010\021\220\024\220R\220t\2301\330\010\t\330\014\031\230\025\230m\2501\330\014\017\210z\230\033\240A\240Q\330\020\027\220q\330\014\021\220\032\2301\200A\330\010\020\220\t\230\021\330\010\r\210W\220A\220T\230""\027\240\t\250\021\250#\250Q\330\010\r\210W\220A\220^\2401\240D\250\001\330\010\r\210W\220A\220T\230\026\230w\240a\240q\330\010\r\210W\220A\220T\230\033\240G\2501\250A\330\010\r\210W\220A\220T\230\027\240\t\250\021\250#\250Q\340\010\017\210w\220g\230Q\230a\200A\330\010\022\220%\220q\330\014\022\220!\330\014\021\220\021\330\014\032\230!\330\014\022\220!\340\010\017\210x\220w\230m\2501\330\010\014\210F\220'\230\021\230!\200A\330\027\030\330\010\017\210t\2201\200A\330\026\027\330\010\017\210t\2201\200A\330\033\034\330\010\017\210t\2201\200A\340\010\017\210t\2201\200A\330\010\017\210t\220>\240\022\2407\250!\200A\330\010\017\210t\220>\240\022\240:\250Q\200A\330\033\034\330\010\017\210x\220y\240\016\250a\250t\2601\320\004\036\230h\240a\330\010\024\220E\230\021\330\014\022\220#\220Q\220d\230!\330\014\021\220\021\330\014\032\230$\230f\240B\240b\250\001\330\014\022\220!\360\010\000\t\022\220\030\230\024\230^\2501\250A\360\006\000\t\r\210F\220'\230\021\230!\340\010\r\210Q\210n\230A\230Y\320&9\270\021\270)\3001\340\010\017\210q"; const char* const bytes = "0.3fGenesis BlockMined block No stringNote that Cython is deliberately stricter than PEP-484 and rejects subclasses of builtin types. If you need to pass subclasses then set the 'annotation_typing' directive to False.UTF-8?add_note>ddatetime.datetime in s with nonce=src/polluck_blockchain/python_translate.pyBlockBlock.__init__Block._perform_hashBlock.compute_hashBlock.compute_hash_bytesBlock.dataBlock.hashBlock.indexBlock.nonceBlock.prev_hashBlock.timestampBlockchainBlockchain.__init__Blockchain.add_blockBlockchain.create_genesis_blockBlockchain.proof_of_workNone__Pyx_PyDict_NextRefadd_blockappendasyncio.coroutinesbigblockblock_hashchaincline_in_tracebackcompute_hashcompute_hash_bytescreate_genesis_blockdata_datadatetimedifficultydigest__doc__dopt_basicsdopt_basics.datetimeelapsedencodeextendfloatfloat_to_bytesfromtimestamp__func__genesis_hashhashhashlibhexdigestindex_index__init__int_is_coroutineitems__main____metaclass____module____name__new_blocknonce_noncenumpackpartsperf_counter_perform_hashpolluck_blockchain.python_translatepopprefix__prepare___prev_hashprev_hashprevious_hashprintproof_of_workproperty__qualname__returnself__set_name__setdefaultsettersha256__slots__startstartswithstrstruct__test__timetimestamp_timestampto_bytesvaluevalues\320\000\030\230\001\330\004\013\2106\220\025\220a\220v\230Q\200A\330\032\"\240!\330\010\013\2104\210z\230\021\230'\240\021\330\014\022\220)\2301\230A\330\010\014\210I\220Q\200A\340\010\024\220A\330\t\n\330\010\014\320\014\"\240!\340\010\014\210N\230!\200A\330\033\034\330\010\014\210J\220a\200A\340\017\020\330\016\017\330\027\030\330\017\020\340\010\014\210J\220a\330\010\014\210N\230(\240)\2501\250F\260$\260c\270\024\270S\300\002\300*\310A\340\010\014\210I\220Q\330\010\014\210N\230!\330\010\014\210J\220a\330\010\014\210I\220Q\200A\340\017\020\330\t\n\330\010\021\220\024\220R\220t\2301\330\010\t\330\014\031\230\025\230m\2501\330\014\017\210z\230\033\240A\240Q\330\020\027\220q\330\014\021\220\032\2301\200A\330\010\020\220\t\230""\021\330\010\r\210W\220A\220T\230\027\240\t\250\021\250#\250Q\330\010\r\210W\220A\220^\2401\240D\250\001\330\010\r\210W\220A\220T\230\026\230w\240a\240q\330\010\r\210W\220A\220T\230\033\240G\2501\250A\330\010\r\210W\220A\220T\230\027\240\t\250\021\250#\250Q\340\010\017\210w\220g\230Q\230a\200A\330\010\022\220%\220q\330\014\022\220!\330\014\021\220\021\330\014\032\230!\330\014\022\220!\340\010\017\210x\220w\230m\2501\330\010\014\210F\220'\230\021\230!\200A\330\027\030\330\010\017\210t\2201\200A\330\026\027\330\010\017\210t\2201\200A\330\033\034\330\010\017\210t\2201\200A\340\010\017\210t\2201\200A\330\010\017\210t\220>\240\022\2407\250!\200A\330\010\017\210t\220>\240\022\240:\250Q\200A\330\033\034\330\010\017\210x\220y\240\016\250a\250t\2601\320\004\036\230h\240a\330\010\024\220E\230\021\330\014\022\220#\220Q\220d\230!\330\014\021\220\021\330\014\032\230$\230f\240B\240b\250\001\330\014\022\220!\360\006\000\t\021\220\004\220M\240\021\330\010\021\220\030\230\024\230^\2501\250A\330\010\022\220$\220m\2403\240b\250\001\340\010\014\210F\220'\230\021\230!\330\010\r\210Q\210n\230A\230Y\240k\260\021\260'\3209K\3101\310I\320UV\340\010\017\210q";
PyObject *data = NULL; PyObject *data = NULL;
CYTHON_UNUSED_VAR(__Pyx_DecompressString); CYTHON_UNUSED_VAR(__Pyx_DecompressString);
#endif #endif
PyObject **stringtab = __pyx_mstate->__pyx_string_tab; PyObject **stringtab = __pyx_mstate->__pyx_string_tab;
Py_ssize_t pos = 0; Py_ssize_t pos = 0;
for (int i = 0; i < 106; i++) { for (int i = 0; i < 111; i++) {
Py_ssize_t bytes_length = index[i].length; Py_ssize_t bytes_length = index[i].length;
PyObject *string = PyUnicode_DecodeUTF8(bytes + pos, bytes_length, NULL); PyObject *string = PyUnicode_DecodeUTF8(bytes + pos, bytes_length, NULL);
if (likely(string) && i >= 13) PyUnicode_InternInPlace(&string); if (likely(string) && i >= 15) PyUnicode_InternInPlace(&string);
if (unlikely(!string)) { if (unlikely(!string)) {
Py_XDECREF(data); Py_XDECREF(data);
__PYX_ERR(0, 1, __pyx_L1_error) __PYX_ERR(0, 1, __pyx_L1_error)
@ -6915,7 +7011,7 @@ const char* const bytes = "0Genesis BlockMined block No stringNote that Cython i
stringtab[i] = string; stringtab[i] = string;
pos += bytes_length; pos += bytes_length;
} }
for (int i = 106; i < 122; i++) { for (int i = 111; i < 127; i++) {
Py_ssize_t bytes_length = index[i].length; Py_ssize_t bytes_length = index[i].length;
PyObject *string = PyBytes_FromStringAndSize(bytes + pos, bytes_length); PyObject *string = PyBytes_FromStringAndSize(bytes + pos, bytes_length);
stringtab[i] = string; stringtab[i] = string;
@ -6926,14 +7022,14 @@ const char* const bytes = "0Genesis BlockMined block No stringNote that Cython i
} }
} }
Py_XDECREF(data); Py_XDECREF(data);
for (Py_ssize_t i = 0; i < 122; i++) { for (Py_ssize_t i = 0; i < 127; i++) {
if (unlikely(PyObject_Hash(stringtab[i]) == -1)) { if (unlikely(PyObject_Hash(stringtab[i]) == -1)) {
__PYX_ERR(0, 1, __pyx_L1_error) __PYX_ERR(0, 1, __pyx_L1_error)
} }
} }
#if CYTHON_IMMORTAL_CONSTANTS #if CYTHON_IMMORTAL_CONSTANTS
{ {
PyObject **table = stringtab + 106; PyObject **table = stringtab + 111;
for (Py_ssize_t i=0; i<16; ++i) { for (Py_ssize_t i=0; i<16; ++i) {
#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING
Py_SET_REFCNT(table[i], _Py_IMMORTAL_REFCNT_LOCAL); Py_SET_REFCNT(table[i], _Py_IMMORTAL_REFCNT_LOCAL);
@ -7073,9 +7169,9 @@ static int __Pyx_CreateCodeObjects(__pyx_mstatetype *__pyx_mstate) {
__pyx_mstate_global->__pyx_codeobj_tab[15] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_src_polluck_blockchain_python_tr, __pyx_mstate->__pyx_n_u_proof_of_work, __pyx_mstate->__pyx_kp_b_iso88591_A_Rt1_m1_z_AQ_q_1, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[15])) goto bad; __pyx_mstate_global->__pyx_codeobj_tab[15] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_src_polluck_blockchain_python_tr, __pyx_mstate->__pyx_n_u_proof_of_work, __pyx_mstate->__pyx_kp_b_iso88591_A_Rt1_m1_z_AQ_q_1, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[15])) goto bad;
} }
{ {
const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 3, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 124}; const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 5, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 124};
PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_data, __pyx_mstate->__pyx_n_u_new_block}; PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_data, __pyx_mstate->__pyx_n_u_new_block, __pyx_mstate->__pyx_n_u_start, __pyx_mstate->__pyx_n_u_elapsed};
__pyx_mstate_global->__pyx_codeobj_tab[16] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_src_polluck_blockchain_python_tr, __pyx_mstate->__pyx_n_u_add_block, __pyx_mstate->__pyx_kp_b_iso88591_ha_E_Qd_fBb_1A_F_QnAY_9_1_q, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[16])) goto bad; __pyx_mstate_global->__pyx_codeobj_tab[16] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_src_polluck_blockchain_python_tr, __pyx_mstate->__pyx_n_u_add_block, __pyx_mstate->__pyx_kp_b_iso88591_ha_E_Qd_fBb_M_1A_m3b_F_QnAYk_9K, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[16])) goto bad;
} }
Py_DECREF(tuple_dedup_map); Py_DECREF(tuple_dedup_map);
return 0; return 0;
@ -9049,6 +9145,34 @@ static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
return __Pyx_GetItemInt_Generic(o, PyLong_FromSsize_t(i)); return __Pyx_GetItemInt_Generic(o, PyLong_FromSsize_t(i));
} }
/* PyObjectFormat */
#if CYTHON_USE_UNICODE_WRITER
static PyObject* __Pyx_PyObject_Format(PyObject* obj, PyObject* format_spec) {
int ret;
_PyUnicodeWriter writer;
if (likely(PyFloat_CheckExact(obj))) {
_PyUnicodeWriter_Init(&writer);
ret = _PyFloat_FormatAdvancedWriter(
&writer,
obj,
format_spec, 0, PyUnicode_GET_LENGTH(format_spec));
} else if (likely(PyLong_CheckExact(obj))) {
_PyUnicodeWriter_Init(&writer);
ret = _PyLong_FormatAdvancedWriter(
&writer,
obj,
format_spec, 0, PyUnicode_GET_LENGTH(format_spec));
} else {
return PyObject_Format(obj, format_spec);
}
if (unlikely(ret == -1)) {
_PyUnicodeWriter_Dealloc(&writer);
return NULL;
}
return _PyUnicodeWriter_Finish(&writer);
}
#endif
/* JoinPyUnicode */ /* JoinPyUnicode */
static PyObject* __Pyx_PyUnicode_Join(PyObject** values, Py_ssize_t value_count, Py_ssize_t result_ulength, static PyObject* __Pyx_PyUnicode_Join(PyObject** values, Py_ssize_t value_count, Py_ssize_t result_ulength,
Py_UCS4 max_char) { Py_UCS4 max_char) {

View File

@ -129,12 +129,11 @@ class Blockchain:
nonce=0, nonce=0,
) )
# start = time.perf_counter() start = time.perf_counter()
new_block.hash = self.proof_of_work(new_block) new_block.hash = self.proof_of_work(new_block)
# elapsed = time.perf_counter() - start elapsed = time.perf_counter() - start
self.chain.append(new_block) self.chain.append(new_block)
# print(f"Mined block {new_block.index} in {elapsed:.3f}s with nonce={new_block.nonce}") print(f"Mined block {new_block.index} in {elapsed:.3f}s with nonce={new_block.nonce}")
print(f"Mined block {new_block.index} with nonce={new_block.nonce}")
return new_block return new_block