From 709213e66e66fc2d0e1637f7f224d56202a50ec4 Mon Sep 17 00:00:00 2001 From: Loom Agent Date: Mon, 13 Jul 2026 15:42:37 +0000 Subject: [PATCH 1/3] docs(precompiles): rustdoc the NeuronPrecompile dispatch methods Document all eight NeuronPrecompile precompile methods (setWeights, commitWeights, revealWeights, burnedRegister, registerLimit, serveAxon, serveAxonTls, servePrometheus) and the struct itself, modeled on the existing VotingPowerPrecompile docs. Pure rustdoc, no behavior change. Toward #1684. --- precompiles/src/neuron.rs | 134 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/precompiles/src/neuron.rs b/precompiles/src/neuron.rs index 8856acdbbd..b901baa780 100644 --- a/precompiles/src/neuron.rs +++ b/precompiles/src/neuron.rs @@ -11,6 +11,14 @@ use sp_std::vec::Vec; use crate::{PrecompileExt, PrecompileHandleExt}; +/// Neuron precompile for smart-contract (EVM) access to neuron management operations. +/// +/// Each method maps to a `pallet-subtensor` dispatchable and is dispatched as a +/// signed runtime call on behalf of the EVM caller (its mapped Substrate account), +/// so the caller pays the underlying extrinsic weight and is subject to the same +/// authorization rules (e.g. the caller coldkey must own the addressed hotkey). +/// All methods are `payable` so attached EVM value is forwarded as the dispatch +/// origin's deposit. pub struct NeuronPrecompile(PhantomData); impl PrecompileExt for NeuronPrecompile @@ -61,6 +69,22 @@ where + IsSubType>, ::AddressMapping: AddressMapping, { + /// Set inter-neuron weights for the calling neuron on a subnet. + /// + /// Dispatches `set_weights`. This direct path is only honored when commit-reveal + /// weights are **disabled** for the subnet; when commit-reveal is enabled the + /// weights must instead be committed and revealed via `commitWeights` / + /// `revealWeights`. + /// + /// # Arguments + /// * `netuid` - The subnet identifier (uint16) + /// * `dests` - Destination UIDs the weights apply to (uint16[]) + /// * `weights` - Weight values, one per destination UID (uint16[]) + /// * `version_key` - Neuron version key; rejected if it does not match the + /// neuron's current version (uint64) + /// + /// # Returns + /// * `()` on success, or an EVM error reverts the call #[precompile::public("setWeights(uint16,uint16[],uint16[],uint64)")] #[precompile::payable] pub fn set_weights( @@ -83,6 +107,20 @@ where ) } + /// Commit a hash of intended weights for the commit-reveal-v2 flow. + /// + /// Dispatches `commit_weights`. Stores a commitment for the caller's neuron on + /// the subnet so the weights can later be revealed during the correct reveal + /// epoch. Requires commit-reveal weights to be enabled for the subnet and the + /// caller to meet the subnet's stake threshold. + /// + /// # Arguments + /// * `netuid` - The subnet identifier (uint16) + /// * `commit_hash` - Hash of `(hotkey, netuid, uids, values, salt, version_key)` + /// committing to the weights that will be revealed (bytes32) + /// + /// # Returns + /// * `()` on success, or an EVM error reverts the call #[precompile::public("commitWeights(uint16,bytes32)")] #[precompile::payable] pub fn commit_weights( @@ -101,6 +139,22 @@ where ) } + /// Reveal previously committed weights and set them for the calling neuron. + /// + /// Dispatches `reveal_weights`. Verifies the reveal matches a prior + /// `commitWeights` commitment for the current reveal epoch, then sets the + /// weights and consumes the commitment. The revealed tuple must hash (under the + /// same scheme used to build the commit) to the stored commit hash. + /// + /// # Arguments + /// * `netuid` - The subnet identifier (uint16) + /// * `uids` - Destination UIDs the weights apply to (uint16[]) + /// * `values` - Weight values, one per destination UID (uint16[]) + /// * `salt` - Salts, one per destination UID, binding the commit (uint16[]) + /// * `version_key` - Neuron version key, must match the committed value (uint64) + /// + /// # Returns + /// * `()` on success, or an EVM error reverts the call #[precompile::public("revealWeights(uint16,uint16[],uint16[],uint16[],uint64)")] #[precompile::payable] pub fn reveal_weights( @@ -125,6 +179,20 @@ where ) } + /// Register a hotkey on a subnet by burning TAO from the caller coldkey. + /// + /// Dispatches `burned_register`. The EVM caller is used as the owning coldkey; + /// `hotkey` is the neuron hotkey to register. The subnet's current registration + /// burn is charged to the caller; on success the hotkey is assigned the next UID + /// on the subnet and the coldkey becomes its owner. + /// + /// # Arguments + /// * `netuid` - The subnet identifier (uint16) + /// * `hotkey` - The hotkey account ID to register (bytes32) + /// + /// # Returns + /// * `()` on success, or an EVM error reverts the call (e.g. insufficient + /// balance to cover the burn, registration disabled, or subnet full) #[precompile::public("burnedRegister(uint16,bytes32)")] #[precompile::payable] fn burned_register( @@ -142,6 +210,21 @@ where handle.try_dispatch_runtime_call::(call, RawOrigin::Signed(coldkey)) } + /// Register a hotkey on a subnet with a maximum acceptable burn price. + /// + /// Dispatches `register_limit`. Like `burnedRegister`, but the registration only + /// proceeds if the subnet's current burn is less than or equal to `limit_price`, + /// so a surging burn cannot over-charge the caller. The EVM caller is the owning + /// coldkey; `hotkey` is the neuron hotkey to register. + /// + /// # Arguments + /// * `netuid` - The subnet identifier (uint16) + /// * `hotkey` - The hotkey account ID to register (bytes32) + /// * `limit_price` - Maximum burn, in RAO, the caller is willing to pay (uint64) + /// + /// # Returns + /// * `()` on success, or an EVM error reverts the call (e.g. current burn + /// exceeds `limit_price`, insufficient balance, registration disabled) #[precompile::public("registerLimit(uint16,bytes32,uint64)")] #[precompile::payable] fn register_limit( @@ -161,6 +244,24 @@ where handle.try_dispatch_runtime_call::(call, RawOrigin::Signed(coldkey)) } + /// Publish the calling neuron's Axon endpoint metadata for a subnet. + /// + /// Dispatches `serve_axon`. Stores the network location of the neuron's Axon + /// (its query/forward RPC server) so validators and other neurons on the subnet + /// can discover and reach it. + /// + /// # Arguments + /// * `netuid` - The subnet identifier (uint16) + /// * `version` - Axon protocol version (uint32) + /// * `ip` - IPv4/IPv6 address as a packed integer (uint128) + /// * `port` - TCP port (uint16) + /// * `ip_type` - Address family: 4 for IPv4, 6 for IPv6 (uint8) + /// * `protocol` - Transport protocol (uint8) + /// * `placeholder1` - Reserved field (uint8) + /// * `placeholder2` - Reserved field (uint8) + /// + /// # Returns + /// * `()` on success, or an EVM error reverts the call #[precompile::public("serveAxon(uint16,uint32,uint128,uint16,uint8,uint8,uint8,uint8)")] #[precompile::payable] #[allow(clippy::too_many_arguments)] @@ -192,6 +293,25 @@ where ) } + /// Publish the calling neuron's Axon endpoint metadata together with a TLS certificate. + /// + /// Dispatches `serve_axon_tls`. Like `serveAxon`, and additionally stores a TLS + /// certificate so the Axon can be reached over a mutually-authenticated TLS + /// connection. + /// + /// # Arguments + /// * `netuid` - The subnet identifier (uint16) + /// * `version` - Axon protocol version (uint32) + /// * `ip` - IPv4/IPv6 address as a packed integer (uint128) + /// * `port` - TCP port (uint16) + /// * `ip_type` - Address family: 4 for IPv4, 6 for IPv6 (uint8) + /// * `protocol` - Transport protocol (uint8) + /// * `placeholder1` - Reserved field (uint8) + /// * `placeholder2` - Reserved field (uint8) + /// * `certificate` - TLS certificate bytes (bytes) + /// + /// # Returns + /// * `()` on success, or an EVM error reverts the call #[precompile::public( "serveAxonTls(uint16,uint32,uint128,uint16,uint8,uint8,uint8,uint8,bytes)" )] @@ -227,6 +347,20 @@ where ) } + /// Publish the calling neuron's Prometheus metrics endpoint metadata for a subnet. + /// + /// Dispatches `serve_prometheus`. Stores the network location of the neuron's + /// Prometheus metrics server so its operational metrics can be scraped. + /// + /// # Arguments + /// * `netuid` - The subnet identifier (uint16) + /// * `version` - Prometheus endpoint version (uint32) + /// * `ip` - IPv4/IPv6 address as a packed integer (uint128) + /// * `port` - TCP port (uint16) + /// * `ip_type` - Address family: 4 for IPv4, 6 for IPv6 (uint8) + /// + /// # Returns + /// * `()` on success, or an EVM error reverts the call #[precompile::public("servePrometheus(uint16,uint32,uint128,uint16,uint8)")] #[precompile::payable] #[allow(clippy::too_many_arguments)] From 3b9f59946f73e357edceb10e407975ee7d643ef8 Mon Sep 17 00:00:00 2001 From: Loom Agent Date: Mon, 13 Jul 2026 15:42:37 +0000 Subject: [PATCH 2/3] test(subtensor): allow deprecated storage in last-tx-block migration test The typed-units work deprecated LastTxBlockDelegateTake, but the migrate_last_tx_block_delegate_take test must reference the deprecated storage to verify the migration. Add #[allow(deprecated)] so the workspace clippy -D warnings gate is green. --- pallets/subtensor/src/tests/migration.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/pallets/subtensor/src/tests/migration.rs b/pallets/subtensor/src/tests/migration.rs index 8e81447fbc..85eb1290c8 100644 --- a/pallets/subtensor/src/tests/migration.rs +++ b/pallets/subtensor/src/tests/migration.rs @@ -1253,6 +1253,7 @@ fn test_per_u16_encodes_identically_to_u16() { assert_eq!(PerU16::zero().encode(), 0u16.encode()); } +#[allow(deprecated)] #[test] fn test_migrate_last_tx_block_delegate_take() { new_test_ext(1).execute_with(|| { From f75bffafecfe41166c6c239e3070297dcee63995 Mon Sep 17 00:00:00 2001 From: unarbos Date: Tue, 14 Jul 2026 10:46:34 -0600 Subject: [PATCH 3/3] docs(precompiles): correct payable, version_key, and registration notes --- precompiles/src/neuron.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/precompiles/src/neuron.rs b/precompiles/src/neuron.rs index b901baa780..8a7eac497f 100644 --- a/precompiles/src/neuron.rs +++ b/precompiles/src/neuron.rs @@ -17,8 +17,8 @@ use crate::{PrecompileExt, PrecompileHandleExt}; /// signed runtime call on behalf of the EVM caller (its mapped Substrate account), /// so the caller pays the underlying extrinsic weight and is subject to the same /// authorization rules (e.g. the caller coldkey must own the addressed hotkey). -/// All methods are `payable` so attached EVM value is forwarded as the dispatch -/// origin's deposit. +/// All methods are marked `payable` so calls carrying EVM value do not revert, +/// but none of these methods consume the attached value. pub struct NeuronPrecompile(PhantomData); impl PrecompileExt for NeuronPrecompile @@ -80,8 +80,8 @@ where /// * `netuid` - The subnet identifier (uint16) /// * `dests` - Destination UIDs the weights apply to (uint16[]) /// * `weights` - Weight values, one per destination UID (uint16[]) - /// * `version_key` - Neuron version key; rejected if it does not match the - /// neuron's current version (uint64) + /// * `version_key` - Weights version key; rejected if it is lower than the + /// subnet's configured weights version key (uint64) /// /// # Returns /// * `()` on success, or an EVM error reverts the call @@ -183,8 +183,9 @@ where /// /// Dispatches `burned_register`. The EVM caller is used as the owning coldkey; /// `hotkey` is the neuron hotkey to register. The subnet's current registration - /// burn is charged to the caller; on success the hotkey is assigned the next UID - /// on the subnet and the coldkey becomes its owner. + /// burn is charged to the caller; on success the hotkey is assigned a UID on + /// the subnet (pruning the lowest-scoring neuron if the subnet is full) and the + /// coldkey becomes its owner. /// /// # Arguments /// * `netuid` - The subnet identifier (uint16) @@ -192,7 +193,7 @@ where /// /// # Returns /// * `()` on success, or an EVM error reverts the call (e.g. insufficient - /// balance to cover the burn, registration disabled, or subnet full) + /// balance to cover the burn, registration disabled, or no UID available) #[precompile::public("burnedRegister(uint16,bytes32)")] #[precompile::payable] fn burned_register(