zexus 1.6.8 → 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -5
- package/package.json +1 -1
- package/src/__init__.py +7 -0
- package/src/zexus/__init__.py +1 -1
- package/src/zexus/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/capability_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/debug_sanitizer.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/environment.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/error_reporter.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/input_validation.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/lexer.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/module_cache.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/module_manager.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/object.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/security.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/security_enforcement.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/syntax_validator.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/zexus_ast.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/zexus_token.cpython-312.pyc +0 -0
- package/src/zexus/access_control_system/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/access_control_system/__pycache__/access_control.cpython-312.pyc +0 -0
- package/src/zexus/advanced_types.py +17 -2
- package/src/zexus/blockchain/__init__.py +411 -0
- package/src/zexus/blockchain/accelerator.py +1160 -0
- package/src/zexus/blockchain/chain.py +660 -0
- package/src/zexus/blockchain/consensus.py +821 -0
- package/src/zexus/blockchain/contract_vm.py +1019 -0
- package/src/zexus/blockchain/crypto.py +79 -14
- package/src/zexus/blockchain/events.py +526 -0
- package/src/zexus/blockchain/loadtest.py +721 -0
- package/src/zexus/blockchain/monitoring.py +350 -0
- package/src/zexus/blockchain/mpt.py +716 -0
- package/src/zexus/blockchain/multichain.py +951 -0
- package/src/zexus/blockchain/multiprocess_executor.py +338 -0
- package/src/zexus/blockchain/network.py +886 -0
- package/src/zexus/blockchain/node.py +666 -0
- package/src/zexus/blockchain/rpc.py +1203 -0
- package/src/zexus/blockchain/rust_bridge.py +421 -0
- package/src/zexus/blockchain/storage.py +423 -0
- package/src/zexus/blockchain/tokens.py +750 -0
- package/src/zexus/blockchain/upgradeable.py +1004 -0
- package/src/zexus/blockchain/verification.py +1602 -0
- package/src/zexus/blockchain/wallet.py +621 -0
- package/src/zexus/capability_system.py +184 -9
- package/src/zexus/cli/__pycache__/main.cpython-312.pyc +0 -0
- package/src/zexus/cli/main.py +383 -34
- package/src/zexus/cli/zpm.py +1 -1
- package/src/zexus/compiler/__pycache__/bytecode.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/lexer.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/parser.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/semantic.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/zexus_ast.cpython-312.pyc +0 -0
- package/src/zexus/compiler/bytecode.py +124 -7
- package/src/zexus/compiler/compat_runtime.py +6 -2
- package/src/zexus/compiler/lexer.py +16 -5
- package/src/zexus/compiler/parser.py +108 -7
- package/src/zexus/compiler/semantic.py +18 -19
- package/src/zexus/compiler/zexus_ast.py +26 -1
- package/src/zexus/concurrency_system.py +79 -0
- package/src/zexus/config.py +54 -0
- package/src/zexus/crypto_bridge.py +244 -8
- package/src/zexus/dap/__init__.py +10 -0
- package/src/zexus/dap/__main__.py +4 -0
- package/src/zexus/dap/dap_server.py +391 -0
- package/src/zexus/dap/debug_engine.py +298 -0
- package/src/zexus/environment.py +112 -9
- package/src/zexus/evaluator/__pycache__/bytecode_compiler.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/core.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/expressions.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/functions.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/resource_limiter.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/statements.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/unified_execution.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/utils.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/bytecode_compiler.py +457 -37
- package/src/zexus/evaluator/core.py +644 -50
- package/src/zexus/evaluator/expressions.py +358 -62
- package/src/zexus/evaluator/functions.py +458 -20
- package/src/zexus/evaluator/resource_limiter.py +4 -4
- package/src/zexus/evaluator/statements.py +774 -122
- package/src/zexus/evaluator/unified_execution.py +573 -72
- package/src/zexus/evaluator/utils.py +14 -2
- package/src/zexus/evaluator_original.py +1 -1
- package/src/zexus/event_loop.py +186 -0
- package/src/zexus/lexer.py +742 -458
- package/src/zexus/lsp/__init__.py +1 -1
- package/src/zexus/lsp/definition_provider.py +163 -9
- package/src/zexus/lsp/server.py +22 -8
- package/src/zexus/lsp/symbol_provider.py +182 -9
- package/src/zexus/module_cache.py +239 -9
- package/src/zexus/module_manager.py +129 -1
- package/src/zexus/object.py +76 -6
- package/src/zexus/parser/__pycache__/parser.cpython-312.pyc +0 -0
- package/src/zexus/parser/__pycache__/strategy_context.cpython-312.pyc +0 -0
- package/src/zexus/parser/__pycache__/strategy_structural.cpython-312.pyc +0 -0
- package/src/zexus/parser/parser.py +1349 -408
- package/src/zexus/parser/strategy_context.py +755 -58
- package/src/zexus/parser/strategy_structural.py +121 -21
- package/src/zexus/persistence.py +15 -1
- package/src/zexus/renderer/__init__.py +61 -0
- package/src/zexus/renderer/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/renderer/__pycache__/backend.cpython-312.pyc +0 -0
- package/src/zexus/renderer/__pycache__/canvas.cpython-312.pyc +0 -0
- package/src/zexus/renderer/__pycache__/color_system.cpython-312.pyc +0 -0
- package/src/zexus/renderer/__pycache__/layout.cpython-312.pyc +0 -0
- package/src/zexus/renderer/__pycache__/main_renderer.cpython-312.pyc +0 -0
- package/src/zexus/renderer/__pycache__/painter.cpython-312.pyc +0 -0
- package/src/zexus/renderer/backend.py +261 -0
- package/src/zexus/renderer/canvas.py +78 -0
- package/src/zexus/renderer/color_system.py +201 -0
- package/src/zexus/renderer/graphics.py +31 -0
- package/src/zexus/renderer/layout.py +222 -0
- package/src/zexus/renderer/main_renderer.py +66 -0
- package/src/zexus/renderer/painter.py +30 -0
- package/src/zexus/renderer/tk_backend.py +208 -0
- package/src/zexus/renderer/web_backend.py +260 -0
- package/src/zexus/runtime/__init__.py +10 -2
- package/src/zexus/runtime/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/runtime/__pycache__/async_runtime.cpython-312.pyc +0 -0
- package/src/zexus/runtime/__pycache__/load_manager.cpython-312.pyc +0 -0
- package/src/zexus/runtime/file_flags.py +137 -0
- package/src/zexus/runtime/load_manager.py +368 -0
- package/src/zexus/safety/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/safety/__pycache__/memory_safety.cpython-312.pyc +0 -0
- package/src/zexus/security.py +424 -34
- package/src/zexus/stdlib/fs.py +23 -18
- package/src/zexus/stdlib/http.py +289 -186
- package/src/zexus/stdlib/sockets.py +207 -163
- package/src/zexus/stdlib/websockets.py +282 -0
- package/src/zexus/stdlib_integration.py +369 -2
- package/src/zexus/strategy_recovery.py +6 -3
- package/src/zexus/type_checker.py +423 -0
- package/src/zexus/virtual_filesystem.py +189 -2
- package/src/zexus/vm/__init__.py +113 -3
- package/src/zexus/vm/__pycache__/async_optimizer.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/bytecode.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/bytecode_converter.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/cache.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/compiler.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/gas_metering.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/jit.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/parallel_vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/async_optimizer.py +80 -6
- package/src/zexus/vm/binary_bytecode.py +659 -0
- package/src/zexus/vm/bytecode.py +59 -11
- package/src/zexus/vm/bytecode_converter.py +26 -12
- package/src/zexus/vm/cabi.c +1985 -0
- package/src/zexus/vm/cabi.cpython-312-x86_64-linux-gnu.so +0 -0
- package/src/zexus/vm/cabi.h +127 -0
- package/src/zexus/vm/cache.py +561 -17
- package/src/zexus/vm/compiler.py +818 -51
- package/src/zexus/vm/fastops.c +15743 -0
- package/src/zexus/vm/fastops.cpython-312-x86_64-linux-gnu.so +0 -0
- package/src/zexus/vm/fastops.pyx +288 -0
- package/src/zexus/vm/gas_metering.py +50 -9
- package/src/zexus/vm/jit.py +364 -20
- package/src/zexus/vm/native_jit_backend.py +1816 -0
- package/src/zexus/vm/native_runtime.cpp +1388 -0
- package/src/zexus/vm/native_runtime.cpython-312-x86_64-linux-gnu.so +0 -0
- package/src/zexus/vm/optimizer.py +161 -11
- package/src/zexus/vm/parallel_vm.py +140 -45
- package/src/zexus/vm/peephole_optimizer.py +82 -4
- package/src/zexus/vm/profiler.py +38 -18
- package/src/zexus/vm/register_allocator.py +16 -5
- package/src/zexus/vm/register_vm.py +8 -5
- package/src/zexus/vm/vm.py +3581 -531
- package/src/zexus/vm/wasm_compiler.py +658 -0
- package/src/zexus/zexus_ast.py +137 -11
- package/src/zexus/zexus_token.py +16 -5
- package/src/zexus/zpm/installer.py +55 -15
- package/src/zexus/zpm/package_manager.py +1 -1
- package/src/zexus/zpm/registry.py +257 -28
- package/src/zexus.egg-info/PKG-INFO +16 -6
- package/src/zexus.egg-info/SOURCES.txt +129 -17
- package/src/zexus.egg-info/entry_points.txt +1 -0
- package/src/zexus.egg-info/requires.txt +4 -0
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Zexus Blockchain — Rust Execution Core Bridge
|
|
3
|
+
===============================================
|
|
4
|
+
|
|
5
|
+
Provides a seamless Python interface to the native Rust execution core
|
|
6
|
+
(``zexus_core``). When the Rust extension is compiled and installed the
|
|
7
|
+
bridge delegates hot-path operations to native code for maximum
|
|
8
|
+
throughput. When the extension is **not** available the bridge falls
|
|
9
|
+
back to the pure-Python implementations with **zero breakage** — every
|
|
10
|
+
function has a Python fallback.
|
|
11
|
+
|
|
12
|
+
The bridge is transparent: callers use the same API regardless of
|
|
13
|
+
whether Rust is present.
|
|
14
|
+
|
|
15
|
+
Exposed APIs
|
|
16
|
+
------------
|
|
17
|
+
* ``RustCoreBridge`` — unified façade
|
|
18
|
+
* ``rust_core_available()`` — quick check
|
|
19
|
+
* ``sha256()`` / ``keccak256()`` — hashing (native or fallback)
|
|
20
|
+
* ``compute_merkle_root()`` — parallel Merkle root
|
|
21
|
+
* ``verify_signature()`` / ``verify_signatures_batch()``
|
|
22
|
+
* ``execute_batch()`` — parallel tx execution via Rayon
|
|
23
|
+
* ``validate_chain()`` — parallel block-header validation
|
|
24
|
+
|
|
25
|
+
Build the Rust core
|
|
26
|
+
-------------------
|
|
27
|
+
::
|
|
28
|
+
|
|
29
|
+
cd rust_core/
|
|
30
|
+
pip install maturin
|
|
31
|
+
maturin develop --release
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
from __future__ import annotations
|
|
35
|
+
|
|
36
|
+
import hashlib
|
|
37
|
+
import json
|
|
38
|
+
import logging
|
|
39
|
+
import time
|
|
40
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple
|
|
41
|
+
|
|
42
|
+
logger = logging.getLogger("zexus.blockchain.rust_bridge")
|
|
43
|
+
|
|
44
|
+
# ── Try to import the Rust extension ───────────────────────────────────
|
|
45
|
+
|
|
46
|
+
_RUST_AVAILABLE = False
|
|
47
|
+
_zexus_core = None
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
import zexus_core as _zexus_core # type: ignore[import-untyped]
|
|
51
|
+
_RUST_AVAILABLE = _zexus_core.is_available()
|
|
52
|
+
if _RUST_AVAILABLE:
|
|
53
|
+
logger.info(
|
|
54
|
+
"Rust execution core loaded (v%s) — native acceleration enabled",
|
|
55
|
+
_zexus_core.version(),
|
|
56
|
+
)
|
|
57
|
+
except ImportError:
|
|
58
|
+
logger.info(
|
|
59
|
+
"Rust execution core not found — using pure-Python fallback. "
|
|
60
|
+
"For maximum throughput (~1800+ TPS) build the Rust core: "
|
|
61
|
+
"cd rust_core/ && maturin develop --release"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def rust_core_available() -> bool:
|
|
66
|
+
"""Return ``True`` if the native Rust execution core is loaded."""
|
|
67
|
+
return _RUST_AVAILABLE
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# ── Hashing ────────────────────────────────────────────────────────────
|
|
71
|
+
|
|
72
|
+
def sha256(data: bytes) -> str:
|
|
73
|
+
"""SHA-256 hash → hex string. Uses Rust if available."""
|
|
74
|
+
if _RUST_AVAILABLE:
|
|
75
|
+
return _zexus_core.RustHasher.sha256(data)
|
|
76
|
+
return hashlib.sha256(data).hexdigest()
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def sha256_str(text: str) -> str:
|
|
80
|
+
"""SHA-256 of UTF-8 string → hex."""
|
|
81
|
+
if _RUST_AVAILABLE:
|
|
82
|
+
return _zexus_core.RustHasher.sha256_str(text)
|
|
83
|
+
return hashlib.sha256(text.encode()).hexdigest()
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def sha256d(data: bytes) -> str:
|
|
87
|
+
"""Double SHA-256 (Bitcoin-style) → hex."""
|
|
88
|
+
if _RUST_AVAILABLE:
|
|
89
|
+
return _zexus_core.RustHasher.sha256d(data)
|
|
90
|
+
h1 = hashlib.sha256(data).digest()
|
|
91
|
+
return hashlib.sha256(h1).hexdigest()
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def keccak256(data: bytes) -> str:
|
|
95
|
+
"""Keccak-256 (Ethereum-style) → hex. Uses Rust if available."""
|
|
96
|
+
if _RUST_AVAILABLE:
|
|
97
|
+
return _zexus_core.RustHasher.keccak256(data)
|
|
98
|
+
# Python fallback using hashlib if available, else pycryptodome
|
|
99
|
+
try:
|
|
100
|
+
import sha3 # type: ignore
|
|
101
|
+
return sha3.keccak_256(data).hexdigest()
|
|
102
|
+
except ImportError:
|
|
103
|
+
# Minimal fallback — use SHA-256 as stand-in (not true keccak)
|
|
104
|
+
logger.warning("No keccak library — falling back to SHA-256")
|
|
105
|
+
return hashlib.sha256(data).hexdigest()
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def sha256_batch(items: List[bytes]) -> List[str]:
|
|
109
|
+
"""Batch SHA-256 — parallel in Rust, sequential in Python."""
|
|
110
|
+
if _RUST_AVAILABLE:
|
|
111
|
+
return _zexus_core.RustHasher.sha256_batch(items)
|
|
112
|
+
return [hashlib.sha256(d).hexdigest() for d in items]
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def keccak256_batch(items: List[bytes]) -> List[str]:
|
|
116
|
+
"""Batch Keccak-256 — parallel in Rust."""
|
|
117
|
+
if _RUST_AVAILABLE:
|
|
118
|
+
return _zexus_core.RustHasher.keccak256_batch(items)
|
|
119
|
+
return [keccak256(d) for d in items]
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
# ── Merkle ─────────────────────────────────────────────────────────────
|
|
123
|
+
|
|
124
|
+
def compute_merkle_root(leaves: List[str]) -> str:
|
|
125
|
+
"""Compute Merkle root from hex leaf hashes — parallel in Rust."""
|
|
126
|
+
if _RUST_AVAILABLE:
|
|
127
|
+
return _zexus_core.RustMerkle.compute_root(leaves)
|
|
128
|
+
return _merkle_root_py(leaves)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def verify_merkle_proof(
|
|
132
|
+
leaf_hash: str,
|
|
133
|
+
proof: List[Tuple[str, str]],
|
|
134
|
+
root: str,
|
|
135
|
+
) -> bool:
|
|
136
|
+
"""Verify a Merkle inclusion proof."""
|
|
137
|
+
if _RUST_AVAILABLE:
|
|
138
|
+
return _zexus_core.RustMerkle.verify_proof(leaf_hash, proof, root)
|
|
139
|
+
return _merkle_verify_py(leaf_hash, proof, root)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _merkle_root_py(leaves: List[str]) -> str:
|
|
143
|
+
"""Pure-Python Merkle root fallback."""
|
|
144
|
+
if not leaves:
|
|
145
|
+
return "0" * 64
|
|
146
|
+
current = list(leaves)
|
|
147
|
+
while len(current) > 1:
|
|
148
|
+
if len(current) % 2 != 0:
|
|
149
|
+
current.append(current[-1])
|
|
150
|
+
next_level = []
|
|
151
|
+
for i in range(0, len(current), 2):
|
|
152
|
+
combined = bytes.fromhex(current[i]) + bytes.fromhex(current[i + 1])
|
|
153
|
+
next_level.append(hashlib.sha256(combined).hexdigest())
|
|
154
|
+
current = next_level
|
|
155
|
+
return current[0]
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def _merkle_verify_py(
|
|
159
|
+
leaf_hash: str,
|
|
160
|
+
proof: List[Tuple[str, str]],
|
|
161
|
+
root: str,
|
|
162
|
+
) -> bool:
|
|
163
|
+
"""Pure-Python Merkle proof verification fallback."""
|
|
164
|
+
current = bytes.fromhex(leaf_hash)
|
|
165
|
+
for sibling_hex, direction in proof:
|
|
166
|
+
sibling = bytes.fromhex(sibling_hex)
|
|
167
|
+
if direction == "left":
|
|
168
|
+
combined = sibling + current
|
|
169
|
+
else:
|
|
170
|
+
combined = current + sibling
|
|
171
|
+
current = hashlib.sha256(combined).digest()
|
|
172
|
+
return current.hex() == root
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
# ── Signature verification ─────────────────────────────────────────────
|
|
176
|
+
|
|
177
|
+
def verify_signature(
|
|
178
|
+
message: bytes, signature: bytes, public_key: bytes
|
|
179
|
+
) -> bool:
|
|
180
|
+
"""Verify an ECDSA-secp256k1 signature. Uses Rust if available."""
|
|
181
|
+
if _RUST_AVAILABLE:
|
|
182
|
+
return _zexus_core.RustSignature.verify(message, signature, public_key)
|
|
183
|
+
return _verify_sig_py(message, signature, public_key)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def verify_signatures_batch(
|
|
187
|
+
items: List[Tuple[bytes, bytes, bytes]],
|
|
188
|
+
) -> List[bool]:
|
|
189
|
+
"""Batch-verify signatures — parallel in Rust."""
|
|
190
|
+
if _RUST_AVAILABLE:
|
|
191
|
+
return _zexus_core.RustSignature.verify_batch(items)
|
|
192
|
+
return [_verify_sig_py(m, s, p) for m, s, p in items]
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def _verify_sig_py(
|
|
196
|
+
message: bytes, signature: bytes, public_key: bytes
|
|
197
|
+
) -> bool:
|
|
198
|
+
"""Pure-Python ECDSA verification fallback."""
|
|
199
|
+
try:
|
|
200
|
+
from cryptography.hazmat.primitives.asymmetric import ec, utils
|
|
201
|
+
from cryptography.hazmat.primitives import hashes
|
|
202
|
+
from cryptography.hazmat.backends import default_backend
|
|
203
|
+
from cryptography.exceptions import InvalidSignature
|
|
204
|
+
|
|
205
|
+
vk = ec.EllipticCurvePublicKey.from_encoded_point(
|
|
206
|
+
ec.SECP256K1(), public_key
|
|
207
|
+
)
|
|
208
|
+
vk.verify(signature, message, ec.ECDSA(hashes.SHA256()))
|
|
209
|
+
return True
|
|
210
|
+
except Exception:
|
|
211
|
+
return False
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
# ── Batch Execution ────────────────────────────────────────────────────
|
|
215
|
+
|
|
216
|
+
class BatchResult:
|
|
217
|
+
"""Wraps Rust's TxBatchResult or pure-Python equivalent."""
|
|
218
|
+
|
|
219
|
+
def __init__(
|
|
220
|
+
self,
|
|
221
|
+
total: int = 0,
|
|
222
|
+
succeeded: int = 0,
|
|
223
|
+
failed: int = 0,
|
|
224
|
+
gas_used: int = 0,
|
|
225
|
+
elapsed: float = 0.0,
|
|
226
|
+
receipts: Optional[List[Dict[str, Any]]] = None,
|
|
227
|
+
):
|
|
228
|
+
self.total = total
|
|
229
|
+
self.succeeded = succeeded
|
|
230
|
+
self.failed = failed
|
|
231
|
+
self.gas_used = gas_used
|
|
232
|
+
self.elapsed = elapsed
|
|
233
|
+
self.receipts = receipts or []
|
|
234
|
+
|
|
235
|
+
@property
|
|
236
|
+
def throughput(self) -> float:
|
|
237
|
+
return self.total / self.elapsed if self.elapsed > 0 else 0.0
|
|
238
|
+
|
|
239
|
+
def __repr__(self) -> str:
|
|
240
|
+
return (
|
|
241
|
+
f"BatchResult(total={self.total}, ok={self.succeeded}, "
|
|
242
|
+
f"fail={self.failed}, gas={self.gas_used}, "
|
|
243
|
+
f"{self.throughput:.1f} tx/s)"
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def execute_batch(
|
|
248
|
+
transactions: List[Dict[str, Any]],
|
|
249
|
+
vm_callback: Callable,
|
|
250
|
+
max_workers: int = 0,
|
|
251
|
+
) -> BatchResult:
|
|
252
|
+
"""Execute a transaction batch using Rust parallelism or Python fallback.
|
|
253
|
+
|
|
254
|
+
Parameters
|
|
255
|
+
----------
|
|
256
|
+
transactions : list of dict
|
|
257
|
+
Each dict: ``{contract, action, args, caller, gas_limit}``
|
|
258
|
+
vm_callback : callable
|
|
259
|
+
``fn(contract, action, args_json, caller, gas_limit) -> dict``
|
|
260
|
+
max_workers : int
|
|
261
|
+
Rayon thread count (0 = auto-detect CPU cores).
|
|
262
|
+
"""
|
|
263
|
+
if _RUST_AVAILABLE:
|
|
264
|
+
# Rust executor expects args as JSON strings
|
|
265
|
+
serialized = []
|
|
266
|
+
for tx in transactions:
|
|
267
|
+
serialized.append({
|
|
268
|
+
"contract": str(tx.get("contract", "")),
|
|
269
|
+
"action": str(tx.get("action", "")),
|
|
270
|
+
"args": json.dumps(tx.get("args", {})) if not isinstance(tx.get("args"), str) else tx["args"],
|
|
271
|
+
"caller": str(tx.get("caller", "")),
|
|
272
|
+
"gas_limit": str(tx.get("gas_limit", "0")),
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
executor = _zexus_core.RustBatchExecutor(max_workers=max_workers)
|
|
276
|
+
result = executor.execute_batch(serialized, vm_callback)
|
|
277
|
+
|
|
278
|
+
receipts = []
|
|
279
|
+
for r_json in result.receipts:
|
|
280
|
+
try:
|
|
281
|
+
receipts.append(json.loads(r_json))
|
|
282
|
+
except json.JSONDecodeError:
|
|
283
|
+
receipts.append({"success": False, "error": r_json})
|
|
284
|
+
|
|
285
|
+
return BatchResult(
|
|
286
|
+
total=result.total,
|
|
287
|
+
succeeded=result.succeeded,
|
|
288
|
+
failed=result.failed,
|
|
289
|
+
gas_used=result.gas_used,
|
|
290
|
+
elapsed=result.elapsed_secs,
|
|
291
|
+
receipts=receipts,
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
# Pure-Python fallback
|
|
295
|
+
return _execute_batch_py(transactions, vm_callback)
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def _execute_batch_py(
|
|
299
|
+
transactions: List[Dict[str, Any]],
|
|
300
|
+
vm_callback: Callable,
|
|
301
|
+
) -> BatchResult:
|
|
302
|
+
"""Pure-Python sequential batch execution fallback."""
|
|
303
|
+
start = time.time()
|
|
304
|
+
result = BatchResult(total=len(transactions))
|
|
305
|
+
|
|
306
|
+
for tx in transactions:
|
|
307
|
+
args_json = json.dumps(tx.get("args", {}))
|
|
308
|
+
try:
|
|
309
|
+
receipt = vm_callback(
|
|
310
|
+
tx.get("contract", ""),
|
|
311
|
+
tx.get("action", ""),
|
|
312
|
+
args_json,
|
|
313
|
+
tx.get("caller", ""),
|
|
314
|
+
tx.get("gas_limit", 0),
|
|
315
|
+
)
|
|
316
|
+
if isinstance(receipt, dict) and receipt.get("success"):
|
|
317
|
+
result.succeeded += 1
|
|
318
|
+
result.gas_used += receipt.get("gas_used", 0)
|
|
319
|
+
else:
|
|
320
|
+
result.failed += 1
|
|
321
|
+
result.receipts.append(receipt if isinstance(receipt, dict) else {})
|
|
322
|
+
except Exception as e:
|
|
323
|
+
result.failed += 1
|
|
324
|
+
result.receipts.append({"success": False, "error": str(e)})
|
|
325
|
+
|
|
326
|
+
result.elapsed = time.time() - start
|
|
327
|
+
return result
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
# ── Block Validation ───────────────────────────────────────────────────
|
|
331
|
+
|
|
332
|
+
def validate_chain_headers(
|
|
333
|
+
blocks: List[Tuple[str, str, str]],
|
|
334
|
+
) -> List[bool]:
|
|
335
|
+
"""Validate chain of (header_json, hash, prev_hash) — parallel in Rust."""
|
|
336
|
+
if _RUST_AVAILABLE:
|
|
337
|
+
return _zexus_core.RustBlockValidator.validate_chain(blocks)
|
|
338
|
+
# Python fallback
|
|
339
|
+
results = []
|
|
340
|
+
for i, (header_json, claimed_hash, prev_hash) in enumerate(blocks):
|
|
341
|
+
hash_ok = hashlib.sha256(header_json.encode()).hexdigest() == claimed_hash
|
|
342
|
+
link_ok = True
|
|
343
|
+
if i > 0:
|
|
344
|
+
link_ok = blocks[i - 1][1] == prev_hash
|
|
345
|
+
results.append(hash_ok and link_ok)
|
|
346
|
+
return results
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
def check_pow_difficulty(block_hash: str, difficulty: int) -> bool:
|
|
350
|
+
"""Check PoW leading-zero-bits requirement — fast in Rust."""
|
|
351
|
+
if _RUST_AVAILABLE:
|
|
352
|
+
return _zexus_core.RustBlockValidator.check_pow_difficulty(
|
|
353
|
+
block_hash, difficulty
|
|
354
|
+
)
|
|
355
|
+
# Python fallback
|
|
356
|
+
hash_bytes = bytes.fromhex(block_hash)
|
|
357
|
+
leading = 0
|
|
358
|
+
for b in hash_bytes:
|
|
359
|
+
if b == 0:
|
|
360
|
+
leading += 8
|
|
361
|
+
else:
|
|
362
|
+
leading += (b ^ (b - 1)).bit_length() - 1 if b else 8
|
|
363
|
+
break
|
|
364
|
+
return leading >= difficulty
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
# ── Unified Bridge Class ───────────────────────────────────────────────
|
|
368
|
+
|
|
369
|
+
class RustCoreBridge:
|
|
370
|
+
"""Unified entry point providing all Rust-accelerated operations.
|
|
371
|
+
|
|
372
|
+
Usage::
|
|
373
|
+
|
|
374
|
+
bridge = RustCoreBridge()
|
|
375
|
+
if bridge.is_native:
|
|
376
|
+
print("Rust acceleration active")
|
|
377
|
+
|
|
378
|
+
root = bridge.merkle_root(leaf_hashes)
|
|
379
|
+
result = bridge.execute_batch(txs, vm_callback)
|
|
380
|
+
"""
|
|
381
|
+
|
|
382
|
+
def __init__(self, max_workers: int = 0):
|
|
383
|
+
self._max_workers = max_workers
|
|
384
|
+
|
|
385
|
+
@property
|
|
386
|
+
def is_native(self) -> bool:
|
|
387
|
+
return _RUST_AVAILABLE
|
|
388
|
+
|
|
389
|
+
@property
|
|
390
|
+
def engine(self) -> str:
|
|
391
|
+
return "rust/rayon" if _RUST_AVAILABLE else "python/threads"
|
|
392
|
+
|
|
393
|
+
# Hashing
|
|
394
|
+
sha256 = staticmethod(sha256)
|
|
395
|
+
sha256_str = staticmethod(sha256_str)
|
|
396
|
+
sha256d = staticmethod(sha256d)
|
|
397
|
+
keccak256 = staticmethod(keccak256)
|
|
398
|
+
sha256_batch = staticmethod(sha256_batch)
|
|
399
|
+
keccak256_batch = staticmethod(keccak256_batch)
|
|
400
|
+
|
|
401
|
+
# Merkle
|
|
402
|
+
merkle_root = staticmethod(compute_merkle_root)
|
|
403
|
+
merkle_verify = staticmethod(verify_merkle_proof)
|
|
404
|
+
|
|
405
|
+
# Signatures
|
|
406
|
+
verify_sig = staticmethod(verify_signature)
|
|
407
|
+
verify_sigs_batch = staticmethod(verify_signatures_batch)
|
|
408
|
+
|
|
409
|
+
# Execution
|
|
410
|
+
def execute_batch(
|
|
411
|
+
self,
|
|
412
|
+
transactions: List[Dict[str, Any]],
|
|
413
|
+
vm_callback: Callable,
|
|
414
|
+
) -> BatchResult:
|
|
415
|
+
return execute_batch(
|
|
416
|
+
transactions, vm_callback, max_workers=self._max_workers
|
|
417
|
+
)
|
|
418
|
+
|
|
419
|
+
# Validation
|
|
420
|
+
validate_chain = staticmethod(validate_chain_headers)
|
|
421
|
+
check_pow = staticmethod(check_pow_difficulty)
|