Skip to content

bittensor-core: one Rust core (keys, keyfiles, timelock, codec, RFC-0078 digest, Ledger) under a thin Python SDK#2846

Open
unarbos wants to merge 19 commits into
mono-bittensorfrom
bittensor-core-exploration
Open

bittensor-core: one Rust core (keys, keyfiles, timelock, codec, RFC-0078 digest, Ledger) under a thin Python SDK#2846
unarbos wants to merge 19 commits into
mono-bittensorfrom
bittensor-core-exploration

Conversation

@unarbos

@unarbos unarbos commented Jul 9, 2026

Copy link
Copy Markdown

Summary

Implements the full sdk/bittensor-core-spec.md plan (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:

  • Phase 0 — decoded-value shape corpus recorded from cyscale as the codec's compatibility contract (sdk/python/tests/fixtures/shape_corpus/), crate skeleton, build-core-wheels.yml.
  • Phase 1py-sp-core + bittensor-drand sources consolidated into the core; old crates, workflows, and the drand C ABI deleted; release train stamps one version.
  • Phase 2 — RFC-0078 digest module (merkleized-metadata 0.5.1, vectors pinned against polkadot-js merkleizeMetadata), LedgerSigner clear-signing via the Polkadot generic app (feature ledger), --ledger CLI flag, docs guide.
  • Phase 3 — Rust Runtime + codec become the production codec.py seam (CallBytes replaces GenericCall); 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).
  • Phase 4 — signature payload, extrinsic assembly, and multisig derivation in core, byte-equal to the golden signing vectors (landed inside phases 2–3).
  • Phase 5 — docs updated (repo layout, wallets, release process, sdk-tests dev loop), spec status + acceptance benchmark recorded.

Acceptance benchmark (finney, 2026-07-10 — spec §10)

Metric Baseline Target Accepted
Codec build from metadata bytes 337 ms ≤15 ms 4 ms
Metagraph SCALE decode 3–6 MB/s ≥50 MB/s 60–77 MB/s
compose_call 1.1 ms ≤50 µs <50 µs
Sign + assemble 0.1 ms no regression 0.03 ms
query_map decode 92k entries/s ≥500k entries/s 599k entries/s
Warm connect ~1.1 s ~0.75 s ~0.6 s

Review focus

  • The codec.py seam rewrite and its consumers (storage.py, extrinsics.py, runtime.py, runtime_api.py, interface.py)
  • Shape-corpus + golden coverage: both suites run natively in Rust (cargo test -p bittensor-core) and through the Python seam
  • The Ledger APDU/proof path (bittensor-core/src/signers/, bittensor/ledger.py) — on-device verification still to be done by someone with hardware

Test 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)
  • ruff / ty / codegen static gates green
  • Acceptance benchmark recorded (table above)
  • e2e suite against a localnet / mainnet clone
  • On-device Ledger verification (generic app, real hardware)

Made with Cursor

unarbos and others added 5 commits July 9, 2026 15:46
…'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>
@vercel

vercel Bot commented Jul 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
subtensor Ready Ready Preview, Comment Jul 10, 2026 5:54pm

Request Review

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🛡️ 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

Sev File Finding
HIGH PR base branch Non-deployment PR bypasses the required integration branch (off-diff)

Other findings

  • [HIGH] Non-deployment PR bypasses the required integration branch (PR base branch) — This PR targets mono-bittensor, but repository policy requires non-deployment changes to target devnet. Merging through an unrecognized feature branch bypasses the normal integration and promotion path. Retarget the PR to devnet, or provide an explicit nucleus-approved exception explaining how mono-bittensor is governed and subsequently integrated.

Conclusion

The changes appear legitimate, but this non-deployment PR targets a feature branch rather than the required devnet integration branch. Retarget it or document an approved branch-strategy exception before merge.


# 🔍 AI Review — Auditor (domain review) has not yet run on this PR.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: VULNERABLE

unarbos and others added 6 commits July 9, 2026 16:26
- 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>
@unarbos unarbos changed the title Spec: bittensor-core — one Rust core (keys, keyfiles, timelock, codec, RFC-0078 digest, Ledger) under a thin Python SDK bittensor-core: one Rust core (keys, keyfiles, timelock, codec, RFC-0078 digest, Ledger) under a thin Python SDK Jul 10, 2026
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>
unarbos and others added 5 commits July 10, 2026 11:52
…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>
@github-actions

Copy link
Copy Markdown
Contributor

eco-tests changed — indexer review required

This PR modifies files under eco-tests/. and may affect downstream indexing.
cc @evgeny-s — please review manually

Changed files
  • eco-tests/Cargo.toml

@github-actions github-actions Bot requested a review from evgeny-s July 10, 2026 17:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant