zexus 1.7.2 → 1.8.1
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 +57 -6
- package/package.json +2 -1
- package/rust_core/Cargo.lock +603 -0
- package/rust_core/Cargo.toml +26 -0
- package/rust_core/README.md +15 -0
- package/rust_core/pyproject.toml +25 -0
- package/rust_core/src/binary_bytecode.rs +543 -0
- package/rust_core/src/contract_vm.rs +643 -0
- package/rust_core/src/executor.rs +847 -0
- package/rust_core/src/hasher.rs +90 -0
- package/rust_core/src/lib.rs +71 -0
- package/rust_core/src/merkle.rs +128 -0
- package/rust_core/src/rust_vm.rs +2313 -0
- package/rust_core/src/signature.rs +79 -0
- package/rust_core/src/state_adapter.rs +281 -0
- package/rust_core/src/validator.rs +116 -0
- package/scripts/postinstall.js +34 -2
- package/src/zexus/__init__.py +1 -1
- package/src/zexus/blockchain/accelerator.py +27 -0
- package/src/zexus/blockchain/contract_vm.py +409 -3
- package/src/zexus/blockchain/rust_bridge.py +64 -0
- package/src/zexus/cli/main.py +1 -1
- package/src/zexus/cli/zpm.py +1 -1
- package/src/zexus/evaluator/bytecode_compiler.py +150 -52
- package/src/zexus/evaluator/core.py +151 -809
- package/src/zexus/evaluator/expressions.py +27 -22
- package/src/zexus/evaluator/functions.py +171 -126
- package/src/zexus/evaluator/statements.py +55 -112
- package/src/zexus/module_cache.py +20 -9
- package/src/zexus/object.py +330 -38
- package/src/zexus/parser/parser.py +69 -14
- package/src/zexus/parser/strategy_context.py +228 -5
- package/src/zexus/parser/strategy_structural.py +2 -2
- package/src/zexus/persistence.py +46 -17
- package/src/zexus/security.py +140 -234
- package/src/zexus/type_checker.py +44 -5
- package/src/zexus/vm/binary_bytecode.py +7 -3
- package/src/zexus/vm/bytecode.py +6 -0
- package/src/zexus/vm/cache.py +24 -46
- package/src/zexus/vm/compiler.py +80 -20
- package/src/zexus/vm/fastops.c +1093 -2975
- package/src/zexus/vm/gas_metering.py +2 -2
- package/src/zexus/vm/memory_pool.py +21 -9
- package/src/zexus/vm/vm.py +527 -67
- package/src/zexus/zpm/package_manager.py +1 -1
- package/src/zexus.egg-info/PKG-INFO +79 -12
- package/src/zexus.egg-info/SOURCES.txt +23 -1
- package/src/zexus.egg-info/requires.txt +26 -0
- package/src/zexus.egg-info/entry_points.txt +0 -4
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
2
|
+
// Cryptographic Hashing — SHA-256 & Keccak-256
|
|
3
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
4
|
+
|
|
5
|
+
use pyo3::prelude::*;
|
|
6
|
+
use sha2::{Digest, Sha256};
|
|
7
|
+
use tiny_keccak::{Hasher as TinyHasher, Keccak};
|
|
8
|
+
|
|
9
|
+
#[pyclass]
|
|
10
|
+
pub struct RustHasher;
|
|
11
|
+
|
|
12
|
+
#[pymethods]
|
|
13
|
+
impl RustHasher {
|
|
14
|
+
#[new]
|
|
15
|
+
fn new() -> Self {
|
|
16
|
+
RustHasher
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/// SHA-256 of raw bytes → hex string.
|
|
20
|
+
#[staticmethod]
|
|
21
|
+
fn sha256(data: Vec<u8>) -> String {
|
|
22
|
+
let hash = Sha256::digest(&data);
|
|
23
|
+
hex::encode(hash)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/// SHA-256 of a UTF-8 string → hex string.
|
|
27
|
+
#[staticmethod]
|
|
28
|
+
fn sha256_str(text: &str) -> String {
|
|
29
|
+
let hash = Sha256::digest(text.as_bytes());
|
|
30
|
+
hex::encode(hash)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/// Double SHA-256 (Bitcoin-style) → hex string.
|
|
34
|
+
#[staticmethod]
|
|
35
|
+
fn sha256d(data: Vec<u8>) -> String {
|
|
36
|
+
let first = Sha256::digest(&data);
|
|
37
|
+
let second = Sha256::digest(&first);
|
|
38
|
+
hex::encode(second)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/// Keccak-256 (Ethereum-style) → hex string.
|
|
42
|
+
#[staticmethod]
|
|
43
|
+
fn keccak256(data: Vec<u8>) -> String {
|
|
44
|
+
let mut hasher = Keccak::v256();
|
|
45
|
+
let mut output = [0u8; 32];
|
|
46
|
+
hasher.update(&data);
|
|
47
|
+
hasher.finalize(&mut output);
|
|
48
|
+
hex::encode(output)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/// Keccak-256 of a UTF-8 string → hex string.
|
|
52
|
+
#[staticmethod]
|
|
53
|
+
fn keccak256_str(text: &str) -> String {
|
|
54
|
+
let mut hasher = Keccak::v256();
|
|
55
|
+
let mut output = [0u8; 32];
|
|
56
|
+
hasher.update(text.as_bytes());
|
|
57
|
+
hasher.finalize(&mut output);
|
|
58
|
+
hex::encode(output)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/// Batch SHA-256: hash many byte-arrays in parallel → list of hex strings.
|
|
62
|
+
#[staticmethod]
|
|
63
|
+
fn sha256_batch(py: Python<'_>, items: Vec<Vec<u8>>) -> Vec<String> {
|
|
64
|
+
use rayon::prelude::*;
|
|
65
|
+
py.allow_threads(|| {
|
|
66
|
+
items
|
|
67
|
+
.par_iter()
|
|
68
|
+
.map(|d| hex::encode(Sha256::digest(d)))
|
|
69
|
+
.collect()
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/// Batch Keccak-256 in parallel.
|
|
74
|
+
#[staticmethod]
|
|
75
|
+
fn keccak256_batch(py: Python<'_>, items: Vec<Vec<u8>>) -> Vec<String> {
|
|
76
|
+
use rayon::prelude::*;
|
|
77
|
+
py.allow_threads(|| {
|
|
78
|
+
items
|
|
79
|
+
.par_iter()
|
|
80
|
+
.map(|d| {
|
|
81
|
+
let mut h = Keccak::v256();
|
|
82
|
+
let mut out = [0u8; 32];
|
|
83
|
+
h.update(d);
|
|
84
|
+
h.finalize(&mut out);
|
|
85
|
+
hex::encode(out)
|
|
86
|
+
})
|
|
87
|
+
.collect()
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
2
|
+
// Zexus Blockchain — Rust Execution Core
|
|
3
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
4
|
+
//
|
|
5
|
+
// High-performance native execution engine exposed to Python via PyO3.
|
|
6
|
+
//
|
|
7
|
+
// Hot paths moved to Rust:
|
|
8
|
+
// • Batch transaction execution (parallel via Rayon)
|
|
9
|
+
// • SHA-256 / Keccak-256 hashing
|
|
10
|
+
// • ECDSA-secp256k1 signature verification
|
|
11
|
+
// • Merkle root computation
|
|
12
|
+
// • Block header validation
|
|
13
|
+
//
|
|
14
|
+
// The Python `ExecutionAccelerator` detects this extension at import
|
|
15
|
+
// time and delegates to it automatically. When the extension is not
|
|
16
|
+
// compiled the system falls back to the pure-Python implementation
|
|
17
|
+
// with zero breakage.
|
|
18
|
+
|
|
19
|
+
use pyo3::prelude::*;
|
|
20
|
+
use pyo3::types::{PyDict, PyList};
|
|
21
|
+
use std::collections::HashMap;
|
|
22
|
+
|
|
23
|
+
mod binary_bytecode;
|
|
24
|
+
mod contract_vm;
|
|
25
|
+
mod executor;
|
|
26
|
+
mod hasher;
|
|
27
|
+
mod merkle;
|
|
28
|
+
mod rust_vm;
|
|
29
|
+
mod signature;
|
|
30
|
+
mod state_adapter;
|
|
31
|
+
mod validator;
|
|
32
|
+
|
|
33
|
+
use binary_bytecode::RustBytecodeReader;
|
|
34
|
+
use contract_vm::RustContractVM;
|
|
35
|
+
use executor::{RustBatchExecutor, TxBatchResult as RustTxBatchResult};
|
|
36
|
+
use rust_vm::RustVMExecutor;
|
|
37
|
+
use hasher::RustHasher;
|
|
38
|
+
use merkle::RustMerkle;
|
|
39
|
+
use signature::RustSignature;
|
|
40
|
+
use state_adapter::RustStateAdapter;
|
|
41
|
+
use validator::RustBlockValidator;
|
|
42
|
+
|
|
43
|
+
// ── Python module definition ──────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
/// The native Zexus execution core.
|
|
46
|
+
#[pymodule]
|
|
47
|
+
fn zexus_core(m: &Bound<'_, PyModule>) -> PyResult<()> {
|
|
48
|
+
m.add_class::<RustBatchExecutor>()?;
|
|
49
|
+
m.add_class::<RustTxBatchResult>()?;
|
|
50
|
+
m.add_class::<RustHasher>()?;
|
|
51
|
+
m.add_class::<RustMerkle>()?;
|
|
52
|
+
m.add_class::<RustSignature>()?;
|
|
53
|
+
m.add_class::<RustBlockValidator>()?;
|
|
54
|
+
m.add_class::<RustBytecodeReader>()?;
|
|
55
|
+
m.add_class::<RustVMExecutor>()?;
|
|
56
|
+
m.add_class::<RustStateAdapter>()?;
|
|
57
|
+
m.add_class::<RustContractVM>()?;
|
|
58
|
+
|
|
59
|
+
// Convenience — quick check from Python: `zexus_core.is_available()`
|
|
60
|
+
#[pyfn(m)]
|
|
61
|
+
fn is_available() -> bool {
|
|
62
|
+
true
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
#[pyfn(m)]
|
|
66
|
+
fn version() -> &'static str {
|
|
67
|
+
env!("CARGO_PKG_VERSION")
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
Ok(())
|
|
71
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
2
|
+
// Merkle Root Computation — parallelised
|
|
3
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
4
|
+
|
|
5
|
+
use pyo3::prelude::*;
|
|
6
|
+
use rayon::prelude::*;
|
|
7
|
+
use sha2::{Digest, Sha256};
|
|
8
|
+
|
|
9
|
+
#[pyclass]
|
|
10
|
+
pub struct RustMerkle;
|
|
11
|
+
|
|
12
|
+
#[pymethods]
|
|
13
|
+
impl RustMerkle {
|
|
14
|
+
#[new]
|
|
15
|
+
fn new() -> Self {
|
|
16
|
+
RustMerkle
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/// Compute the Merkle root of a list of hex-encoded leaf hashes.
|
|
20
|
+
///
|
|
21
|
+
/// Uses a standard binary Merkle tree (duplicate last leaf if odd).
|
|
22
|
+
/// The hashing combines pairs with SHA-256(left || right).
|
|
23
|
+
///
|
|
24
|
+
/// Returns the root as a hex string.
|
|
25
|
+
#[staticmethod]
|
|
26
|
+
fn compute_root(py: Python<'_>, leaves: Vec<String>) -> String {
|
|
27
|
+
if leaves.is_empty() {
|
|
28
|
+
return "0".repeat(64);
|
|
29
|
+
}
|
|
30
|
+
if leaves.len() == 1 {
|
|
31
|
+
return leaves[0].clone();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Decode hex leaves to raw bytes
|
|
35
|
+
let mut current: Vec<[u8; 32]> = leaves
|
|
36
|
+
.iter()
|
|
37
|
+
.map(|h| {
|
|
38
|
+
let bytes = hex::decode(h).unwrap_or_else(|_| {
|
|
39
|
+
// If not valid hex, hash the raw string
|
|
40
|
+
Sha256::digest(h.as_bytes()).to_vec()
|
|
41
|
+
});
|
|
42
|
+
let mut arr = [0u8; 32];
|
|
43
|
+
let len = bytes.len().min(32);
|
|
44
|
+
arr[..len].copy_from_slice(&bytes[..len]);
|
|
45
|
+
arr
|
|
46
|
+
})
|
|
47
|
+
.collect();
|
|
48
|
+
|
|
49
|
+
py.allow_threads(|| {
|
|
50
|
+
while current.len() > 1 {
|
|
51
|
+
// Duplicate last if odd
|
|
52
|
+
if current.len() % 2 != 0 {
|
|
53
|
+
current.push(*current.last().unwrap());
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Pair and hash in parallel
|
|
57
|
+
let pairs: Vec<([u8; 32], [u8; 32])> = current
|
|
58
|
+
.chunks(2)
|
|
59
|
+
.map(|c| (c[0], c[1]))
|
|
60
|
+
.collect();
|
|
61
|
+
|
|
62
|
+
current = pairs
|
|
63
|
+
.par_iter()
|
|
64
|
+
.map(|(left, right)| {
|
|
65
|
+
let mut combined = Vec::with_capacity(64);
|
|
66
|
+
combined.extend_from_slice(left);
|
|
67
|
+
combined.extend_from_slice(right);
|
|
68
|
+
let hash = Sha256::digest(&combined);
|
|
69
|
+
let mut arr = [0u8; 32];
|
|
70
|
+
arr.copy_from_slice(&hash);
|
|
71
|
+
arr
|
|
72
|
+
})
|
|
73
|
+
.collect();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
hex::encode(current[0])
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/// Compute Merkle root from raw transaction data (list of byte arrays).
|
|
81
|
+
/// Each item is SHA-256 hashed first to produce the leaf, then the
|
|
82
|
+
/// tree is built.
|
|
83
|
+
#[staticmethod]
|
|
84
|
+
fn compute_root_from_data(py: Python<'_>, data: Vec<Vec<u8>>) -> String {
|
|
85
|
+
let leaves: Vec<String> = py.allow_threads(|| {
|
|
86
|
+
data.par_iter()
|
|
87
|
+
.map(|d| hex::encode(Sha256::digest(d)))
|
|
88
|
+
.collect()
|
|
89
|
+
});
|
|
90
|
+
// Re-acquire GIL for the tree computation call
|
|
91
|
+
RustMerkle::compute_root(py, leaves)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/// Verify a Merkle proof.
|
|
95
|
+
///
|
|
96
|
+
/// `leaf_hash` — the hex hash of the item to verify
|
|
97
|
+
/// `proof` — list of (hex_hash, "left"|"right") pairs
|
|
98
|
+
/// `root` — expected root hex
|
|
99
|
+
#[staticmethod]
|
|
100
|
+
fn verify_proof(
|
|
101
|
+
leaf_hash: &str,
|
|
102
|
+
proof: Vec<(String, String)>,
|
|
103
|
+
root: &str,
|
|
104
|
+
) -> bool {
|
|
105
|
+
let mut current = hex::decode(leaf_hash).unwrap_or_default();
|
|
106
|
+
if current.len() != 32 {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
for (sibling_hex, direction) in &proof {
|
|
111
|
+
let sibling = hex::decode(sibling_hex).unwrap_or_default();
|
|
112
|
+
if sibling.len() != 32 {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
let mut combined = Vec::with_capacity(64);
|
|
116
|
+
if direction == "left" {
|
|
117
|
+
combined.extend_from_slice(&sibling);
|
|
118
|
+
combined.extend_from_slice(¤t);
|
|
119
|
+
} else {
|
|
120
|
+
combined.extend_from_slice(¤t);
|
|
121
|
+
combined.extend_from_slice(&sibling);
|
|
122
|
+
}
|
|
123
|
+
current = Sha256::digest(&combined).to_vec();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
hex::encode(¤t) == root
|
|
127
|
+
}
|
|
128
|
+
}
|