Skip to content

feat: Jito/Solana backend (additive) - #187

Draft
RonTuretzky wants to merge 7 commits into
mainfrom
jito-backend
Draft

feat: Jito/Solana backend (additive)#187
RonTuretzky wants to merge 7 commits into
mainfrom
jito-backend

Conversation

@RonTuretzky

Copy link
Copy Markdown
Contributor

Additive Jito/Solana backend for the chassis, per the cross-track contract in jito-ncn-program docs/INTERFACES.md (§1 signature domain, §2 VerifyCertificate, §5 router backend). Zero deletions or modifications of the EVM path — new crates + additive workspace registration only (members, dependency entries, a [patch.crates-io] section that is inert for the EVM graph). The EVM default-member clippy/tests run unchanged and green.

Seams

  • jito/ crate (peer of eigenlayer/)
    • bn254: key/signature wrappers in the NCN program's signature domain — Solana alt_bn128 compressed wire formats, hash-to-curve and pairings via ncn-program-core (git dep on jito-ncn-program main; imported, never reimplemented). The signature domain is the program's, not the EVM chassis scheme's.
    • scheme::JitoBn254Scheme: implements commonware_cryptography::certificate::Scheme (modeled on core/src/bn254/scheme.rs). Certificates carry exactly the §2 wire triple — aggregated G1 signature (32B compressed), aggregated G2 (64B compressed), signer bitmap — and verify_certificate recomputes apk1 from the bitmap and runs G2Point::verify_aggregated_signature::<Sha256Normalized>, i.e. the program's own verification function (locked by an on-chain parity anchor test).
    • config::NcnDeployment: the NCN deployment JSON (NCN_DEPLOYMENT_PATH), analog of the EVM avs_deploy.json — ncn pubkey, program ids, rpc url, commitment (confirmed minimum; processed rejected), threshold/compute-budget knobs, PDA derivations.
    • network::JitoStakingClient: operators via getProgramAccounts memcmp on NCNOperatorAccount (discriminator @0, ncn @8; ip+port sockets), stake/APK facts from the Snapshot PDA, all reads at confirmed. Produces JitoQuorum with index-aligned participant set / G1 keys / on-chain operator indices / stakes from one sorted construction (participant indices are sorted-G2-set positions, NOT ncn_operator_index — the quorum carries the translation table).
    • quorum: startup reconciliation (§5) — the minimum total stake over all (N−f)-sized signer subsets must clear consensus_threshold_bps, else the router/node refuse to start. Exact arithmetic (BigUint cross-multiplication), unit-tested incl. boundary and overflow cases.
    • instruction: manual §2 VerifyCertificate construction (accounts [ncn_config, ncn, snapshot, restaking_config], all read-only; borsh args hand-rolled and cross-checked against real borsh 0.10). The on-chain bitmap is built byte-exact with ncn_program_core::utils::create_signer_bitmap (LSB-first, padding bits set), verified by a differential test.
    • submitter::JitoSubmitter + SolanaCertificateHandler (the Solana-typed peer of the EVM BlsSignatureVerificationHandler): the submitter resolves a certified height into a CertificateSubmission (§2 triple + expected_generation captured at quorum-assembly time) and hands it to the handler. VerifyCertificateHandler sends the tx with a ComputeBudget, reports Resolution{Executed} only at finalized, and on blockhash expiry rebuilds and resends the transaction (the tx expires, the certificate does not). A settlement handler (INTERFACES §4; Track C settlement_core on branch settlement-program) plugs into the same seam.
  • examples/counter-solana/ (common/node/router): wiring mirror of examples/counter — verifier-only engine + sequencer + JitoSubmitter on the router, signing participant with TaskBook/NodeReporter/NodeAutomaton on the node, digest formula sha256(domain ‖ ncn ‖ round) shared via the common crate. Needs a live NCN deployment (deployment JSON + funded payer) — nothing is mocked; unit tests use the real ncn-program-core crypto (host-side signing) end to end. The compose e2e leg comes in a later phase.

TODO-FREEZE markers (parallel-track dependencies)

  • VERIFY_CERTIFICATE_DISCRIMINATOR: the phase1-dmsg branch is not pushed yet, so the generated-client discriminator is unknowable. The const is &[10] (the CastVote slot §2 says it replaces) with a pinning test to flip to the generated client's value before any live submission. Note: the program uses 1-byte kinobi/borsh enum discriminators, not 8-byte shank-style — the test pins the length too.
  • JitoQuorum.generation: main's Snapshot has no generation field yet (Phase 1 adds it); the seam reports 0 (what Phase 1 reports for a never-mutated set) until the git dep is bumped to read snapshot.generation().
  • consensus_threshold_bps: comes from the deployment JSON (default 6667) until Phase 1 lands it on the Config PDA.

Dependency notes (important for maintainers)

  • The [patch.crates-io] section mirrors jito-ncn-program's solana pin set (trimmed to used entries) so ONE solana stack (jito-solana fork rev 87dcd08) flows through ncn-program-core, the jito-restaking crates, their spl transitive deps and the jito crate. It is unused by (and inert for) every pre-existing crate.
  • Upstream deleted the v2.1-upgrade branch of jito-foundation/restaking that ncn-program-core's manifest still references; its head 358fbc3 remains fetchable by SHA and is pinned in the checked-in Cargo.lock (cargo fetches locked git revs by SHA without resolving the branch). A blanket cargo update will therefore fail against the dead branch — update surgically (cargo update -p <pkg> --precise <ver>) until jito-ncn-program re-pins by rev = (recommended upstream fix; its own fresh clones have the same exposure).

Gates

  • cargo fmt --all -- --check: clean
  • cargo clippy --all-targets -- -D warnings on the new crates: clean
  • cargo clippy --all-targets --all-features -- -D warnings (EVM default members, the CI command): clean
  • cargo test --lib --all-features (EVM default members): 43/43, untouched
  • cargo test on new crates: 49/49 (real crypto: scheme assemble/verify round-trips, on-chain parity anchor via verify_aggregated_signature, bitmap/borsh differentials, quorum reconciliation)
  • cargo check --workspace --all-targets: clean

🤖 Generated with Claude Code

RonTuretzky and others added 7 commits July 19, 2026 16:19
New crates beside the EVM path (zero deletions/modifications of it):

- jito/: BN254 wrappers in the NCN program's signature domain
  (ncn-program-core Sha256Normalized hash-to-curve, Solana compressed wire
  formats), JitoBn254Scheme (certificate::Scheme whose certificates carry the
  VerifyCertificate wire triple and whose verification IS the program's
  challenge-combined pairing), NcnDeployment config (NCN_DEPLOYMENT_PATH),
  JitoStakingClient (getProgramAccounts memcmp on NCNOperatorAccount +
  Snapshot PDA, confirmed commitment), startup quorum reconciliation
  (lightest (N-f)-subset stake vs consensus_threshold_bps), manual
  VerifyCertificate instruction construction (frozen INTERFACES 2 shape,
  discriminator TODO-FREEZE until phase1-dmsg pushes), and JitoSubmitter +
  SolanaCertificateHandler seam with finalized-only resolutions and
  blockhash-expiry rebuild.
- examples/counter-solana/{common,node,router}: wiring mirror of
  examples/counter against a live NCN deployment; no mocks (unit tests use
  the real ncn-program-core crypto).

Workspace changes are additive registration only: new members, new
[workspace.dependencies] entries, and a [patch.crates-io] section mirroring
jito-ncn-program's solana pin set (inert for the EVM path). Cargo.lock pins
jito-foundation/restaking at 358fbc3 because upstream deleted the
v2.1-upgrade branch ncn-program-core still references (fetch-by-SHA via the
lock is what keeps it resolvable).
… main; freeze VerifyCertificate seams

- jito-foundation/restaking deps pinned by rev=358fbc3c (dead v2.1-upgrade
  branch no longer referenced anywhere; fresh clones resolve by SHA), adding
  the sdk/core crates the counter-solana deployer uses
- ncn-program-core bumped to main#9013404 (post phase1-dmsg merge)
- VERIFY_CERTIFICATE_DISCRIMINATOR frozen at the generated client's value
  (byte 10); pinning test now differentially asserts the FULL instruction
  data against ncn_program_core::instruction::NCNProgramInstruction
- JitoQuorum.generation now reads Snapshot.generation (was hardcoded 0)
- consensus_threshold_bps now read from the on-chain NCN Config PDA in
  get_quorum (deployment JSON demoted to fallback when the PDA is missing)
- counter-solana-deployer crate stub (workspace member, not default-members)

Gates: fmt, clippy -D warnings (jito+examples+deployer), 41 jito tests,
8 example tests, EVM 43 tests, cargo check --workspace --all-targets.
…rt choreography, real BLS quorum, on-chain VerifyCertificate assert

scripts/solana_e2e_local.sh boots the entire Solana leg from a clean
checkout: builds jito restaking+vault from source at rev 358fbc3c
(declare_id env-injected) + the NCN program from BreadchainCoop main,
starts solana-test-validator with the three programs at genesis, deploys
and registers EVERYTHING with real transactions (4 operators, full
handshake mesh, vault, delegations, BLS proof-of-possession
registrations, on-chain ip/port), restarts the validator with
--warp-slot into epoch 2, cranks vault update-state-tracker + NCN
snapshot, runs 4 counter-solana nodes + the router to BLS quorum, and
asserts a successful VerifyCertificate transaction on-chain at
confirmed. NO mocks, NO fake programs. Verified green end-to-end
locally (exit 0; certificate tx asserted by independent chain query).

Key mechanics (documented in the script):
- epoch_length is HARDCODED to 432,000 slots at InitializeConfig and no
  admin ix can change it; SlotToggle needs current_epoch >
  activation_epoch + 1. The two-phase --warp-slot restart compresses the
  empty epochs while every state transition stays a real tx.
- SlotToggle refuses same-slot activation: the deployer crosses a slot
  boundary between every init and its warmup.
- A --warp-slot restart rebuilds from the latest FULL SNAPSHOT ARCHIVE
  (100-slot interval) and does NOT replay the blockstore tail — the
  script waits for a snapshot covering the deploy tip before killing
  phase A (empirically verified account-loss failure mode).

New pieces:
- examples/counter-solana/deployer: deploy / activate / assert-verified;
  jito ixs via the programs' own sdk builders (jito-restaking-sdk /
  jito-vault-sdk, lock-pinned at the same rev), ncn ixs by
  borsh-serializing NCNProgramInstruction itself.
- .github/workflows/solana-e2e.yml: clean-runner CI job running the
  script (Agave install, cargo + source caches, failure log artifact).
- docker-compose.solana.yml + docker/solana-e2e.Dockerfile: the
  containerized variant runs the SAME script in one service — the
  warp-restart choreography cannot be split into a fire-and-forget
  validator container; design note in the compose file. settlement
  profile reserved for the settlement-program leg.
- fix: counter-solana node+router dropped their tracing guard
  (let _ = set_default(..)), silently disabling all log output.
- scripts/README.md + jito/README.md run documentation.

Gates: fmt, clippy -D warnings (jito + examples + deployer), 41 jito +
8 example tests, EVM 43 tests untouched, cargo check --workspace.
Root cause of the pre-existing red Rust CI on jito-backend: cargo's fetch
of the ncn-program-core git dependency clones its repo's
commonware-avs-router-solana submodule, which is pinned by SSH url
(git@github.com:Unboxed-Software/...) — unauthenticated runners fail.
Public repo; only the scheme is the problem.

- rust-ci.yml + solana-e2e.yml: git config --global https insteadOf SSH
  before any cargo step (libgit2's submodule path reads config files).
- solana_e2e_local.sh: self-contained process-scoped rewrite
  (CARGO_NET_GIT_FETCH_WITH_CLI + GIT_CONFIG_* env) so clean local
  machines work without touching the user's global git config.

Verified locally with the exact CI commands: fmt --check OK, clippy
--all-targets --all-features -D warnings 0 errors, check --all-targets
--all-features 0 errors, cargo test --lib --all-features green.
- deps: bump jito-ncn-program to main#2fe8e4e (settlement merged); add
  settlement-core (same git source) + base64
- jito: SettleCertificateHandler lands Settle{payload, cert} via the
  SolanaCertificateHandler seam (digest recomputed from the task's borsh
  SettlementPayload, refuse on mismatch; story_meta => buffer account);
  FinalizedSender extracts the shared finalized-only send/rebuild policy;
  NcnDeployment grows the optional settlement binding
  (settlementProgramId + appId -> GkState PDA)
- counter-solana common: LlmTaskData (payload bytes ride the directive),
  LlmSettleValidator (binds the node's OWN state PDA + settle
  discriminator + single-Store + buffer PDA before signing
  sha256(borsh(payload))), LLM namespace
- counter-solana node/router: generic over the task flavor; LLM_SETTLE=1
  switches to the settle task source (one-shot producer-fixture payload,
  LLM_PAYLOAD_FIXTURE) + settle handler
- deployer: llm-init (InitializeState, app_id=sha256(gaskiller-llm-demo),
  profile/env pins hashed from fixture provenance, emits llm_env.sh +
  frontend-config.json + patched ncn_deploy.json), llm-stage (chunked
  WriteBuffer + staged-hash check), llm-assert (root/count/buffer-hash/
  story_meta self-CPI at confirmed, prints the story read back), llm-replay
  (resubmits the landed Settle, asserts InvalidTransitionIndex 0x9100)
…oducer, llm-init/regen/stage, settle-mode router+nodes, assert + replay gate, frontend config)
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.

2 participants