bittensor-core: one Rust core (keys, keyfiles, timelock, codec, RFC-0078 digest, Ledger) under a thin Python SDK#2846
bittensor-core: one Rust core (keys, keyfiles, timelock, codec, RFC-0078 digest, Ledger) under a thin Python SDK#2846unarbos wants to merge 19 commits into
Conversation
…'s stateful epoch-schedule commit (get_encrypted_commit_v2). Co-authored-by: Cursor <cursoragent@cursor.com>
…ow CPU is 0-7% of chain-op wall time, so the spec scopes the Rust core to crypto/codec/digest (Ledger enablement, startup parse, batch compose) and keeps the transport in Python. Co-authored-by: Cursor <cursoragent@cursor.com>
…ata-shape decisions first (decoded-value shape corpus, name-vs-id type identity, CallBytes), subtraction and scaffold phases, full surface inventory, and per-phase decision gates under a frozen Python API. Co-authored-by: Cursor <cursoragent@cursor.com>
…rness, internal seam redesigned not emulated, TYPE_REGISTRY and cyscale quirks die) and map the full signer ecosystem (extensions, Polkadot Vault, Ledger, remote) onto the existing protocol seams. Co-authored-by: Cursor <cursoragent@cursor.com>
…ABI outright, pull digest+Ledger forward to phase 2) and mark Ledger chain-readiness verified: runtime already ships CheckMetadataHash with metadata-hash production builds, generic app supports sr25519. Co-authored-by: Cursor <cursoragent@cursor.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🛡️ AI Review — Skeptic (security review)VERDICT: VULNERABLE MEDIUM scrutiny: 114-day-old account with substantial activity and repository write access; bittensor-core-exploration targets mono-bittensor, with no known Gittensor association found. Static review found no malicious code, runtime panic path, dependency substitution, or modification to the trusted AI-review instructions. The changed Rust dependencies are existing workspace dependencies, and the new third-party workflow action is commit-pinned. Findings
Other findings
ConclusionThe changes appear legitimate, but this non-deployment PR targets a feature branch rather than the required # 🔍 AI Review — Auditor (domain review) has not yet run on this PR. |
|
🔄 AI review updated — Skeptic: VULNERABLE |
- record_shape_corpus.py + tests/fixtures/shape_corpus/: pins the decoded shape of 769/775 portable-registry types (2745 samples) as the codec compatibility gate; test_shape_corpus.py replays it against the active codec (trivially green under cyscale, becomes the Rust gate in phase 3) - bittensor-core/ (pure Rust) + bittensor-core-py/ (PyO3 abi3-py310) workspace skeletons with the boundary error type and exception mapping - build-core-wheels.yml: reusable wheel matrix (core-dist-* artifacts) - intents/coldkey.py, intents/multisig.py: last stray scalecodec imports repointed to bittensor.sp_core Co-authored-by: Cursor <cursoragent@cursor.com>
One Rust core, one wheel, one pyo3 pin. The pure logic moves into bittensor-core (keys/, keyfiles/, timelock/, mlkem/) with a single CoreError; bittensor-core-py exposes the union of the two retired surfaces name-for-name under 'import bittensor_core'. Subtractions decided in the spec land here rather than being migrated: the drand C ABI (ffi.rs, bindings.h, cbindgen.toml) is deleted outright, get_encrypted_commit v1 is not carried, and the ML-KEM seal is rewritten as safe Rust (it was only ever reachable through the C ABI shim). The pre-migration sp_core aliases stay, now defined once in the binding. SDK: sp_core.py/timelock.py/executor.py/intents/weights.py import from bittensor_core; pyproject collapses two native deps into one (bittensor-core>=0.1,<0.2 with a workspace uv source); uv.lock rebuilt. CI: release train and mainnet watcher stamp/pin/build one package via build-core-wheels.yml (core-dist-*); build-sp-core-wheels.yml and build-drand-wheels.yml deleted; publish-sdk-dev path triggers repointed. Verified: cargo test -p bittensor-core (29 tests incl. live drand round-trip and epoch-schedule vectors), clippy/fmt/zepter clean, SKIP_WASM_BUILD workspace check green, SDK suite 869 passed (only the pre-existing test_evm ABI-sync failure remains). Co-authored-by: Cursor <cursoragent@cursor.com>
…g, --ledger CLI The digest module binds Parity's merkleized-metadata crate over raw MetadataVersioned bytes; the digest is cross-checked byte-for-byte against polkadot-js merkleizeMetadata, and the Ledger proof blob (the MetadataProof wire shape Zondax's generic-api service ships to devices) is pinned as a golden vector with the JS envelope tail asserted shared. LedgerDevice (feature "ledger") speaks the generic app's APDU protocol over Zondax's HID transport; the Python LedgerSigner satisfies Signer + MetadataVerifyingSigner + the new UnsignedExtrinsicSigner capability, so the transport hands it the payload's wire seams (call / included_in_extrinsic / included_in_signed_data — now split by signature_payload_parts and carried on UnsignedExtrinsic) to build the per-extrinsic type proof the device decodes on-screen. SigningContext gains spec_name, threaded from state_getRuntimeVersion through the runtime manager. CLI: --ledger (shorthand for --signer ledger) with --ledger-account / --ledger-index resolves at the same seam as the extension signer; docs guide added. manylinux wheels drop the ledger feature (hidraw links libudev, which the manylinux policy excludes); the sdist keeps it. Co-authored-by: Cursor <cursoragent@cursor.com>
Runtime::parse (V14/V15) with pallet/type-name indexes; cyscale-shape decoder passing the full shape corpus; encoder + compose_call matching every golden call vector (nested Sudo/batch/proxy included); storage key construction and map-key recovery; signature payloads, signed-extrinsic assembly/decode, era birth and multisig derivation — all byte-pinned by the golden fixtures. bittensor-core-py grows the Runtime class (decode/ batch_decode/encode, compose_call as CallBytes, storage, constants, payloads, extrinsics, runtime-API map, codegen IR) plus era_birth and multisig_account_id. Co-authored-by: Cursor <cursoragent@cursor.com>
codec.py is now a thin veneer over bittensor_core.Runtime: CallBytes replaces GenericCall, cyscale/xxhash/TYPE_REGISTRY and the legacy runtime-API registry die, and the codec quirks (Weight probe, namespace guard, runtime priming) go with them. Decode hot paths run off the GIL and in parallel (rayon) with Python materialization behind a per-call object cache, and ss58 rendering gets a limb-based base58 (~6x, pinned byte-identical to sp-core). Acceptance on finney: codec build 337ms -> 4ms, metagraph decode 3-6 -> 60-77 MB/s, query_map decode 92k -> 599k entries/s, sign+assemble 10k -> 29k/s — all phase-gate targets met, corpus + goldens + 874-test suite green. Co-authored-by: Cursor <cursoragent@cursor.com>
…core Repo layout, wallets, and release-process pages now describe bittensor-core / bittensor-core-py instead of py-sp-core + bittensor-drand; sdk-tests documents the native-module dev loop (uv path source, stale-wheel reinstall) and the shape corpus as a first-class fixture layer. The spec records the acceptance benchmark against every phase-gate target and flips its status to implemented through phase 4. Co-authored-by: Cursor <cursoragent@cursor.com>
The core and its binding crate are client-side code; they now live with the Python SDK under sdk/ so the client/chain boundary the spec draws is visible in the tree, and future binding crates (napi, uniffi) slot in as siblings. Also re-vendors evm/abi/subnet.json from the canonical precompile ABI, which gained isSubnetDissolving upstream. Co-authored-by: Cursor <cursoragent@cursor.com>
…tration, Ledger on manylinux Works through the thermo-nuclear audit findings on the core seam: - Untrusted-metadata hardening: depth caps on decode/encode recursion and py_to_value (a stack overflow aborts the process; on a rayon worker there is no Python frame to catch it), canonical-compact enforcement and an element budget in strict mode, pinned by a pathological-nesting test. - Timelock decrypt workflow moves into the core and get_round_info drops its tokio runtime for blocking reqwest; the bindings now release the GIL around every network call. - Batch/map decode orchestration (rayon fan-out, spec dedup, thresholds) moves from the binding into core codec::batch; Python-object materialization splits into values.rs, leaving runtime.rs as pure forwarding. - Ledger on manylinux: a minimal HID framing layer (signers/hid.rs) over hidapi's pure-Rust hidraw backend replaces ledger-transport-hid, whose libudev link disqualified Linux wheels; wheels now ship Ledger support on every platform. - Contract cleanups: UnsignedExtrinsic payload parts are required (no older-SDK shim), the dead GenericCall type-string alias is gone, and storage.py's identity wrappers are inlined at their call sites. Verified: 47 core Rust tests (goldens, shape corpus), 875 Python unit tests, clippy and rustfmt clean, ruff clean. Co-authored-by: Cursor <cursoragent@cursor.com>
…ter regression test The call was deprecated for sudo_set_sn_owner_hotkey (call 67); the Owner-proxy denial property under test is unchanged. Co-authored-by: Cursor <cursoragent@cursor.com>
…on manylinux and run without a system libssl Co-authored-by: Cursor <cursoragent@cursor.com>
…ALNET_IMAGE_NAME as a legacy alias in conftest Co-authored-by: Cursor <cursoragent@cursor.com>
… and storage-query precompiles, registerLimit, proxy/subnet ABI fixes, localnet genesis chain ID 42 Co-authored-by: Cursor <cursoragent@cursor.com>
…iases, and -h for --help Co-authored-by: Cursor <cursoragent@cursor.com>
…ation/bls git dependency (repo now archived); drop the stale subnet-template link from the website Co-authored-by: Cursor <cursoragent@cursor.com>
eco-tests changed — indexer review requiredThis PR modifies files under Changed files
|
Summary
Implements the full
sdk/bittensor-core-spec.mdplan (phases 0–5). One workspace crate,bittensor-core, now owns everything whose right answer is chain-defined — sp-core key primitives, keyfiles, drand timelock, ML-KEM, the SCALE codec + runtime-metadata engine, extrinsic assembly, multisig derivation, and the RFC-0078 merkleized-metadata digest — exposed to Python through one PyO3 binding crate (bittensor-core-py, PyPI:bittensor-core). The Python public API is frozen throughout; each phase landed as its own commit and is independently revertible.By phase:
sdk/python/tests/fixtures/shape_corpus/), crate skeleton,build-core-wheels.yml.py-sp-core+bittensor-drandsources consolidated into the core; old crates, workflows, and the drand C ABI deleted; release train stamps one version.merkleized-metadata0.5.1, vectors pinned against polkadot-jsmerkleizeMetadata),LedgerSignerclear-signing via the Polkadot generic app (featureledger),--ledgerCLI flag, docs guide.Runtime+ codec become the productioncodec.pyseam (CallBytesreplacesGenericCall); cyscale, xxhash,TYPE_REGISTRY, and the cyscale-era quirks are deleted. Decode hot paths cross the FFI once per page and run off the GIL (rayon), with a limb-based base58 for ss58 rendering (~6x, byte-identical to sp-core).Acceptance benchmark (finney, 2026-07-10 — spec §10)
compose_callquery_mapdecodeReview focus
codec.pyseam rewrite and its consumers (storage.py,extrinsics.py,runtime.py,runtime_api.py,interface.py)cargo test -p bittensor-core) and through the Python seambittensor-core/src/signers/,bittensor/ledger.py) — on-device verification still to be done by someone with hardwareTest plan
cargo test -p bittensor-core— 44 tests green (corpus, goldens, digest vectors, keys, timelock)cd sdk/python && uv run pytest— 874 unit tests green (one pre-existing EVM ABI-drift failure from 08c1a21, unrelated)Made with Cursor