Migrate SDK to snarkvm v4.8.1 (MainnetV0) with pytest KAT suite#44
Open
iamalwaysuncomfortable wants to merge 70 commits into
Open
Migrate SDK to snarkvm v4.8.1 (MainnetV0) with pytest KAT suite#44iamalwaysuncomfortable wants to merge 70 commits into
iamalwaysuncomfortable wants to merge 70 commits into
Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…3 paths
Replace hardcoded Testnet3 with cfg-selected MainnetV0/TestnetV0 network types.
Update imports to use 4.7.3 API paths: ledger::{block, query, store}, synthesizer for
Process and Trace. Remove deprecated coinbase module imports. Add feature-gated
AleoTestnetV0 import.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lasses Replaces single _aleolib pymodule with two cfg-gated variants: - _aleolib_mainnet (default, no testnet feature) - _aleolib_testnet (when testnet feature enabled) Both delegate to shared register() function. Removes coinbase module and drops CoinbasePuzzle, CoinbaseVerifyingKey, EpochChallenge, and ProverSolution class registrations. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace rand 0.8 Standard distribution sampling with snarkvm 4.7.3's Uniform::rand API (rand 0.10). Upgrade sdk rand dep to 0.10 to align with snarkvm's transitive rand version. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The EDITION constant was removed in snarkvm 4.7.3. Replace with hardcoded 0 value. Credits module requires no changes (pure native types). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…getters, random())
- Replace StdRng::from_entropy() with rand::make_rng::<StdRng>() (rand 0.10)
- Rename #[new] fn new() -> #[staticmethod] fn random() on PrivateKey and Account
- Add Record::version() getter (U8<N> deref'd to machine u8)
- Add #[getter] to pure accessors: PrivateKey::{address,view_key,compute_key,seed}, Signature::{challenge,response,compute_key}, ViewKey::to_address, ComputeKey::address, Account::{private_key,view_key,address}, RecordPlaintext::{owner,nonce}
- Fix Plaintext::Struct/Array variant to use std::sync::OnceLock (was OnceCell)
- Update serial_number() to accept record_view_key for new to_commitment() 3-arg signature
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Fix Transition: rename is_bond() → is_bond_public(), is_unbond() → is_unbond_public() - Add #[getter] to ProgramID::name, network; Locator::program_id, name, network, resource; Program::id, functions, imports, source; Transition::id, program_id, function_name; Execution::execution_id; Response::outputs Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…flow - query.rs: QueryNative::try_from(url) replaces removed From<String> - trace.rs: prove_execution/prove_fee take VarunaVersion::V2; prepare takes &QueryNative; rng via rand::make_rng - process.rs: interior-mutability receivers (&self) for add_program/insert_*_key; add_program routes through Process::lock(); fee authorize uses (base_fee, priority_fee, id) plain-u64 signature; execution_cost uses free fn with ConsensusVersion::V15; verify_execution/verify_fee take (ConsensusVersion, VarunaVersion, InclusionVersion); ProcessAuthError/ProcessExecError mapped to anyhow - fee.rs: payer/transition become #[getter] Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Create sdk/python/aleo/mainnet.py with wildcard re-export from _aleolib_mainnet - Update sdk/pyproject.toml module-name from aleo._aleolib to aleo._aleolib_mainnet - Update sdk/python/aleo/__init__.py to import mainnet submodule (no star import) - Update sdk/python/aleo/encryptor.py to import from .mainnet instead of top-level . - Update sdk/.gitignore to cover all *.abi3.so build artifacts Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Historical ciphertext from records.json (sdk@543b41e) parsed and
decrypted successfully under snarkvm 4.7.3 — KAT path taken, no
fallback needed.
Assertions:
- is_owner(vk) True / is_owner(non_owner_vk) False
- pt.owner (stripped of .private qualifier) == vector owner address
- pt.nonce == vector nonce
- pt.version == 0 (v0-era record; snarkvm 4.7.3 exposes _version=0u8)
- f"{microcredits}u64" in str(pt) — checks decrypted plaintext content
against the vector value, not just vector-internal consistency
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Delete sdk/python/test.py (legacy ad-hoc unittest referencing removed APIs) - git mv _aleolib.pyi -> _aleolib_mainnet.pyi; add mainnet.pyi re-export stub - Drop coinbase symbols (CoinbasePuzzle, CoinbaseVerifyingKey, EpochChallenge, ProverSolution) from stubs - Apply API deltas: random() staticmethods, property accessors, renamed is_bond_public/is_unbond_public, updated authorize_fee signatures, Trace.prove_execution(locator: str), Network.edition removed - CI: maturin develop --features mainnet; replace python3 test.py with pip install pytest + python -m pytest python/tests -v; fix double-cd (working_directory already in sdk/) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- ViewKey: rename #[getter] fn to_address → fn address so Python is vk.address - Stubs: update ViewKey.to_address → @Property address in both .pyi files - Stubs: replace Optional[...] with X | None in __init__.pyi; drop unused Optional import - lib.rs: add #![allow(non_local_definitions)] for pyo3 0.20 / newer rustc compat Suite: 9/9 passed; zero aleo-crate compiler warnings. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…add encryptor tests Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ypes Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- snarkvm moves from crates.io 4.7.3 to git tag v4.8.1 (not yet published) - ConsensusVersion pins bumped V15 -> V17 (4.8.x added V16/V17) in verify_execution, verify_fee, and execution_cost - add .cargo/config.toml so plain cargo builds link pyo3 extension modules on macOS (maturin injects these flags itself) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…n assembly, serial numbers Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…stubs Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ency - sdk.yml: three parallel lanes — lint (fmt/clippy/pyright + testnet cfg check), fast pytest matrix on linux/macos/windows with pytest-xdist, and a proving job with a cached ~/.aleo parameter store - remove unused openssl 0.10 dependency and the openssl/vendored flags from the wheels workflow (never referenced in src/) - fix pyright reportUnusedImport on the aleo.mainnet re-export Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
e374825 to
5acd697
Compare
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… exceptions Replace catch_unwind/wrap_overflow with primitive checked_add/sub/mul/div/pow and guarded rem/rem_wrapped; division and remainder by zero now raise ZeroDivisionError, other failures raise OverflowError without any panic. Fix vacuous Field.random test and add rem zero-divisor + I8 MIN%-1 pinned tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… hardening
- metadata.rs: refactor make_metadata to accept separate prover_meta and
verifier_meta params; always read prover_checksum from each respective
metadata JSON (mirrors wasm reference mechanics exactly). Update all 15
static constructors to pass both XxxProver::METADATA and
XxxVerifier::METADATA. Drop the now-unused verifier_checksum helper.
- offline_query.rs: replace .unwrap() with .expect("OfflineQuery
serialization failed") in __str__ per codebase convention.
- dynamic_record.rs: use direct PartialEq comparison (self.0 == other.0)
since DynamicRecordNative implements std PartialEq; remove string-form
workaround.
- test_program_keys.py: add regex assertion for verifier filename format
(bond_public.verifier.<7 hex chars>).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…t_record_members, get_struct_members, address Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…shapes)
- test_program_get_record_members: assert microcredits member has type u64 and visibility private; _nonce has type group and visibility public
- test_program_get_struct_members: assert full dict shape with exactly {name, type} keys; verify x and y types are u32
- test_program_get_mappings: assert account mapping has key_type address and value_type u64
- test_program_get_function_inputs_record: new test for transfer_private record input path, verifying 3 inputs, record structure with microcredits/nonce members, and address/u64 field inputs
All assertions now match exact dict shapes from Rust implementation.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… 16 is_*_verifier checkers Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Eliminate DRY violation by reusing the read_prover_checksum function from metadata.rs instead of duplicating it in proving_key.rs. All 30 checker call sites (15 checkers x 2 cfg branches) now use the shared implementation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…h_transition_info Implements two decrypt methods on the Ciphertext pyclass in sdk/src/account/text.rs, mirroring the wasm SDK's key derivation: compute_function_id + hash_psd4([fn_id, tvk, index]). Tests use a self-generated MainnetV0 KAT (network ID 0) since the wasm KAT was testnet (ID 1). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
….decrypt_transition Add test_ciphertext_decrypt_cross_validates_with_transition_decrypt to test_program_keys.py. The existing Task 9 KAT tests only prove that decrypt_with_transition_view_key decrypts its own self-generated output; a shared derivation bug (e.g. wrong field order in hash_psd4) would not be caught. The new test exercises both paths against the vendored hello_hello.aleo/main mainnet fixture (private input index 1 = "2u32"), where Transition.decrypt_transition was independently tested in test_chain_data.py, ensuring that any per-path derivation regression is caught. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ery, Program/VK/PK/Ciphertext additions Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…DynamicRecord) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…03 retry - .gitignore had '*.pkl.idea/' concatenation (both patterns dead) - test naming: 15 credits verifiers, not 16 - proving tests: api.explorer.provable.com/v2 (verified live) + 3-attempt retry around trace.prepare for transient API 503s Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Pure-Python AleoNetworkClient (requests) and AsyncAleoNetworkClient (httpx) mirroring TS SDK semantics: block/program/transaction endpoints, JWT refresh, DPS sealed-box encryption via PyNaCl, retry on 5xx, wait_for_confirmation. Shared logic in _client_common.py; security helpers in security.py. 519 tests pass (+62); pyright 0 errors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…outing tests - pyproject.toml: move dependencies=["requests>=2"] from invalid [project.dependencies] table to correct array under [project] - network_client.py: wire transport param via _http() helper that routes all HTTP through callable transport when provided; document contract - async_network_client.py: pass transport to httpx.AsyncClient(transport=...) in __init__; add 5 missing async methods (get_program_imports, get_program_import_names, get_program_object, get_program_mapping_plaintext, get_transaction_object) with async DFS _collect_program_imports - _client_common.py: TypeVar'd retry_with_backoff signature Callable[[], T]->T - test_network_client.py: remove @pytest.mark.slow + blanket except/skip from DPS tests; add Request-variant routing test (prove/request endpoint); add sync transport callable test; assert mock called once in block_range_50 test - test_network_client_async.py: remove object.__new__ bypass, use __init__ with MockTransport; add transport-wiring tests; add async parity tests for 5 new methods; add Request-variant async DPS routing test - Both: URL-encode commitments in get_state_paths via urllib.parse.quote Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…saction-object test Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rity Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds sdk-abi/, a standalone maturin/PyO3 package (aleo-abi) that wraps leo-abi@ba2c017 to expose generate_abi() and check_compatibility() to Python. Also wires a lazy aleo.abi integration module into the main SDK and extends sdk-wheels.yml with build-abi / sdist-abi jobs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ion canary - new test-abi job: builds both wheels, runs the aleo-abi KAT suite and the main-package hook tests for real, and asserts sdk/Cargo.lock never references leo's dev_skip_checks feature (build-graph isolation canary) - hook tests skip gracefully where aleo-abi isn't installed (3-OS matrix) - abi wheel jobs gated on the tests workflow like the main wheels Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e imports The aleo package now genuinely depends on requests (PEP 621 fix), so --no-index wheel installs broke every lane. Allow dependency resolution, add the new client test deps to test lanes, and give the pyright action an environment that can resolve requests/httpx/nacl imports. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ptional import) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rty boundaries pynacl/httpx are optional deps and aleo_abi is a separate package; strict pyright's reportUnknownMemberType cascades from those boundary calls. Relax only those three rules in the four glue modules; the ~40 core binding modules stay fully strict. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… dirs The legacy root setup.cfg injects --numprocesses/--timeout addopts (needs xdist/timeout plugins) into any pytest run from repo root. Running each suite from inside its package dir makes pytest use that package's pytest.ini instead, so the test-abi lane needs no extra plugins. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Migrates the
aleoPyO3 crate from snarkvm 0.16.6 (Testnet3) to v4.8.1 (MainnetV0), replaces the ad-hoctest.pywith a pytest suite validated against TS-SDK known-answer vectors, and restructures the package for per-network builds.Architecture
CurrentNetwork/CurrentAleoselected by Cargo feature (mainnetdefault /testnet). Each build emits a distinct pymodule (_aleolib_mainnet/_aleolib_testnet); Python namespaces them asaleo.mainnet/aleo.testnet(mainnet ships now, testnet is a build config away — zero source change).pk.address,record.owner/nonce/version), explicitPrivateKey.random()(no implicit-RNG constructor), dunders overto_string()/equals(), snake_case throughout;.pyistubs retargeted to match.Breaking API changes (from upstream 4.x)
Network.edition()removed (editions are per-program in 4.x)RecordPlaintext.serial_number()requires a newrecord_view_key: FieldargTransition.is_bond()/is_unbond()→is_bond_public()/is_unbond_public()(base_fee: int, priority_fee: int, deployment_or_execution_id: Field)— priority fee now requiredexecution_costreturns(total, (storage, finalize))as plain intsverify_execution/verify_feepin ConsensusVersion::V17/VarunaVersion::V2/InclusionVersion::V1 (current network tip; historical executions proven under older rules may be rejected — follow-up planned to parameterize)Query.rest()validates the URL and can raiseTests
sdk/python/tests(pytest, wired into CI replacingpython3 test.py):tests/vectors/*.json, source commit recorded): private key → view key → address triples; record ciphertext ownership + decryption (owner/nonce/microcredits/version asserted from actual decrypted plaintext)transfer_publicauthorization built and JSON round-tripped (offline, ~6s)11/11 passing.
maturin develop --features mainnetclean (0 crate warnings); testnet cfg builds.Test plan
cd sdk && maturin develop --features mainnet && python -m pytest python/tests -v→ 11/11cargo build --no-default-features --features testnetlinks🤖 Generated with Claude Code