Skip to content

Add Validate proxy support to runtime and Python SDK - #3041

Draft
cisterciansis wants to merge 4 commits into
RaoFoundation:mainfrom
cisterciansis:feature/validate-proxy-sdk
Draft

Add Validate proxy support to runtime and Python SDK#3041
cisterciansis wants to merge 4 commits into
RaoFoundation:mainfrom
cisterciansis:feature/validate-proxy-sdk

Conversation

@cisterciansis

@cisterciansis cisterciansis commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add ProxyType::Validate with stable on-chain ID 18
  • restrict Validate proxies to validator operations: weight set/commit/reveal calls, axon serving, EVM association, and commitments
  • preserve existing subnet set_weights call sites by reading the exact target hotkeys from WEIGHT_TARGETS
  • support any ordering and mixture of the signing hotkey and proxied hotkeys, including an empty set that performs no submission
  • isolate each target with Utility.force_batch, so a stale, revoked, or otherwise failing proxy cannot interrupt valid targets
  • return an ordered per-target outcome in result.data["weight_results"]

Attribution

This work carries forward the original ProxyType::Validate runtime design and test groundwork from #2543, authored by @ppolewicz. Thank you to Paweł Polewicz for proposing and implementing the original scoped validator proxy.

This PR adapts that work to the current monorepo proxy-filter metadata model and adds the previously missing Python SDK integration.

Why

A validator operator may be authorized by several hotkeys to compute one weight vector and submit it for each validator. The runtime needs a narrow proxy role that cannot transfer value or manage stake. For commit-reveal subnets, the SDK must also preflight and timelock-encrypt against each real validator hotkey rather than the delegate key.

Unlike #2543, Validate proxies in this version cannot create additional proxies; each validator owner grants the delegate directly.

SDK behavior

Existing subnet weight-setting code does not change:

WEIGHT_TARGETS=5F...DELEGATE,5F...VALIDATOR_A,5F...VALIDATOR_B
await client.execute(
    bt.SetWeights(netuid=1, weights={0: 0.2, 1: 0.8}),
    delegate_wallet,
)

Configuration semantics:

  • unset WEIGHT_TARGETS: preserve existing single-wallet behavior
  • empty WEIGHT_TARGETS: successful no-op without signing or submission
  • comma-separated targets: the supplied wallet hotkey is direct; every other target is dispatched through a zero-delay Validate proxy
  • explicit constructor weight_targets= remains available and overrides the environment

Each target is built against its real validator identity, including commit-reveal registration, rate-limit, and timelock-encryption inputs. Target-specific SDK preflight failures are recorded without blocking other targets.

The SDK deliberately does not preverify the complete proxy configuration before submission. Each Proxy.proxy call is authoritative on-chain, and Utility.force_batch continues after an invalid or revoked grant. This prevents one bad target from blocking a larger validator operation. The result preserves configured order:

result.data["weight_results"]
# [{"target": "5F...", "success": True}, ...]

A single extrinsic has one signer, so the supplied wallet is the only direct signer in one execution. Other configured addresses are proxied targets.

Fees and weight refunds

set_mechanism_weights is Pays::No. Proxy.proxy inherits the inner call fee classification, and Utility keeps a batch fee-free when every child is fee-free. Runtime tests assert that direct, proxied, and force_batch weight calls all remain Pays::No.

force_batch also returns accumulated actual child weight. A Utility regression test verifies that successful children refund declared weight minus actual weight across the batch.

Regression coverage

The existing live clone proxy-filter regression now creates a Validate relationship and exercises:

  • mechanism weight submission
  • axon serving
  • TLS axon serving
  • EVM-key association
  • commitments
  • rejection of a balance transfer

It intentionally does not exercise drand. The live clone test was typechecked locally; execution requires a clone/localnet endpoint and runs in the repository clone regression job.

Validation

  • full Python SDK suite: 1,073 passed, 1 skipped
  • focused intent/executor suite: 504 passed
  • Ruff lint and format: passed
  • TypeScript clone regression typecheck: passed
  • SKIP_WASM_BUILD=1 cargo test -p node-subtensor-runtime proxy_filters --lib: 14 passed
  • SKIP_WASM_BUILD=1 cargo test -p node-subtensor-runtime transaction_payment_wrapper::tests --lib: 26 passed
  • Utility successful-weight-refund regression: passed
  • cargo fmt --check: passed

Local environment note

The native WASM build could not run locally because Apple clang lacks a wasm32 backend for the zstd C build.

@vercel

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

@cisterciansis is attempting to deploy a commit to the RaoFoundation Team on Vercel.

A member of the Team first needs to authorize it.

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