From 22366e8876edcf751a50ac391652f17ab030db9f Mon Sep 17 00:00:00 2001 From: grubbhook Date: Tue, 17 Mar 2026 11:34:57 +0000 Subject: [PATCH 1/5] =?UTF-8?q?Update=20--hotkey=20=E2=86=92=20--hotkey-na?= =?UTF-8?q?me=20in=20reg.sh=20and=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to the hotkey flag rename: update reg.sh and two doc files that referenced the global --hotkey flag by its old name. Co-Authored-By: Claude Sonnet 4.6 --- docs/llm.txt | 2 +- docs/tutorials/validator-guide.md | 2 +- reg.sh | 35 +++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100755 reg.sh diff --git a/docs/llm.txt b/docs/llm.txt index 7f84488..596a64b 100644 --- a/docs/llm.txt +++ b/docs/llm.txt @@ -77,7 +77,7 @@ List admin params → agcli admin list --output json | `--network NET` | `AGCLI_NETWORK` | finney\|test\|local\|archive | | `--endpoint URL` | `AGCLI_ENDPOINT` | Custom WS endpoint | | `-w NAME` | `AGCLI_WALLET` | Wallet name | -| `--hotkey NAME` | `AGCLI_HOTKEY` | Hotkey name | +| `--hotkey-name NAME` | `AGCLI_HOTKEY` | Hotkey name | | `--wallet-dir DIR` | `AGCLI_WALLET_DIR` | Wallet dir | | `--proxy SS58` | `AGCLI_PROXY` | Proxy account | | `--live [SECS]` | — | Live polling (default 12s) | diff --git a/docs/tutorials/validator-guide.md b/docs/tutorials/validator-guide.md index 6aef2d5..f6dadac 100644 --- a/docs/tutorials/validator-guide.md +++ b/docs/tutorials/validator-guide.md @@ -15,7 +15,7 @@ Validators evaluate miners by setting weights, which determines emission distrib agcli wallet create --name validator # Create a hotkey (operational key — used for on-chain validator operations) -agcli wallet create-hotkey --name validator --hotkey default +agcli wallet create-hotkey --name validator --hotkey-name default ``` ### 2. Fund Your Coldkey diff --git a/reg.sh b/reg.sh new file mode 100755 index 0000000..7afed57 --- /dev/null +++ b/reg.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +set -euo pipefail + +WALLET="${1:-}" +HOTKEY="${2:-}" +NETUID="${3:-}" +PASSWORD="${4:-}" +WALLET_DIR="${AGCLI_WALLET_DIR:-/root/.bittensor/wallets}" + +if [[ -z "$WALLET" ]]; then + read -r -p "Wallet name: " WALLET +fi + +if [[ -z "$HOTKEY" ]]; then + read -r -p "Hotkey name: " HOTKEY +fi + +if [[ -z "$NETUID" ]]; then + read -r -p "Netuid: " NETUID +fi + +if [[ -z "$PASSWORD" ]]; then + read -r -s -p "Password: " PASSWORD + echo +fi + +export AGCLI_PASSWORD="$PASSWORD" + +while true; do + agcli --wallet-dir "$WALLET_DIR" \ + --wallet "$WALLET" \ + --hotkey-name "$HOTKEY" \ + subnet register-neuron --netuid "$NETUID" --yes && break + sleep 1 +done \ No newline at end of file From 15a66522938afebffeaa4ca16e543fc0c7bd047a Mon Sep 17 00:00:00 2001 From: grubbhook Date: Wed, 18 Mar 2026 02:17:15 +0000 Subject: [PATCH 2/5] Add short flag aliases for global CLI args -e --endpoint, -d --wallet-dir, -H --hotkey-name, -o --output (-n/-w/-v/-y were already present; -h is reserved for --help) Co-Authored-By: Claude Sonnet 4.6 --- src/cli/mod.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 76b6ac3..a7fe861 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -54,12 +54,13 @@ pub struct Cli { pub network: String, /// Custom chain endpoint (overrides --network) - #[arg(long, global = true, env = "AGCLI_ENDPOINT")] + #[arg(long, short = 'e', global = true, env = "AGCLI_ENDPOINT")] pub endpoint: Option, /// Wallet directory #[arg( long, + short = 'd', global = true, default_value = "~/.bittensor/wallets", env = "AGCLI_WALLET_DIR" @@ -77,11 +78,17 @@ pub struct Cli { pub wallet: String, /// Hotkey name (file under wallet's hotkeys/ directory) - #[arg(long, global = true, default_value = "default", env = "AGCLI_HOTKEY")] + #[arg( + long, + short = 'H', + global = true, + default_value = "default", + env = "AGCLI_HOTKEY" + )] pub hotkey_name: String, /// Output format - #[arg(long, global = true, default_value = "table", value_enum)] + #[arg(long, short = 'o', global = true, default_value = "table", value_enum)] pub output: OutputFormat, /// Enable live polling mode (interval in seconds, default 12) From 3b610527680996ac43ca46c1b8725a593920ff00 Mon Sep 17 00:00:00 2001 From: grubbhook Date: Wed, 18 Mar 2026 03:05:24 +0000 Subject: [PATCH 3/5] =?UTF-8?q?Fix=20false=20failure:=20switch=20wait=5Ffo?= =?UTF-8?q?r=5Ffinalized=5Fsuccess=20=E2=86=92=20in-best-block=20poll?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit wait_for_finalized_success() requires GRANDPA finality which takes 36-72s on Bittensor (3-6 blocks × 12s), blowing past the 30s timeout even when the extrinsic was already successfully included in a block. Replace with a manual poll loop that resolves on TxStatus::InBestBlock (or InFinalizedBlock, whichever arrives first), then calls wait_for_success() to check for dispatch errors. In-block confirmation is sufficient to guarantee staking/transfer success — GRANDPA finality follows automatically. The 30s timeout is now appropriate: one block takes ~12s so 30s gives ample headroom without the false-failure behaviour. Fixes: transaction timed out after 30s despite successful on-chain inclusion Co-Authored-By: Claude Sonnet 4.6 --- src/chain/mod.rs | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/src/chain/mod.rs b/src/chain/mod.rs index b8ce301..8c5ce95 100644 --- a/src/chain/mod.rs +++ b/src/chain/mod.rs @@ -8,7 +8,7 @@ use anyhow::{Context, Result}; use sp_core::sr25519; use subxt::backend::legacy::rpc_methods::LegacyRpcMethods; use subxt::backend::rpc::RpcClient; -use subxt::tx::PairSigner; +use subxt::tx::{PairSigner, TxStatus}; use subxt::OnlineClient; use crate::queries::query_cache::QueryCache; @@ -346,7 +346,7 @@ impl Client { // Retry submission on transient errors (connection drop before tx reaches node). // Once submitted, we do NOT retry — the finalization wait is non-idempotent. let inner = &self.inner; - let progress = retry_on_transient("sign_submit", RPC_RETRIES, || async { + let mut progress = retry_on_transient("sign_submit", RPC_RETRIES, || async { match inner .tx() .sign_and_submit_then_watch_default(tx, &signer) @@ -365,28 +365,53 @@ impl Client { } }) .await?; - spinner.set_message("Waiting for finalization..."); - tracing::debug!("Extrinsic submitted, waiting for finalization"); - let result = tokio::time::timeout( - std::time::Duration::from_secs(30), - progress.wait_for_finalized_success(), - ) + spinner.set_message("Waiting for inclusion..."); + tracing::debug!("Extrinsic submitted, waiting for in-block inclusion"); + let in_block = tokio::time::timeout(std::time::Duration::from_secs(30), async { + loop { + match progress.next().await { + Some(Ok(TxStatus::InBestBlock(b) | TxStatus::InFinalizedBlock(b))) => { + return Ok(b); + } + Some(Ok(TxStatus::Error { message })) => { + return Err(subxt::Error::Other(message)); + } + Some(Ok(TxStatus::Invalid { message })) => { + return Err(subxt::Error::Other(message)); + } + Some(Ok(TxStatus::Dropped { message })) => { + return Err(subxt::Error::Other(message)); + } + Some(Ok(_)) => continue, + Some(Err(e)) => return Err(e), + None => { + return Err(subxt::Error::Other( + "Transaction stream ended before inclusion".to_string(), + )) + } + } + } + }) .await .map_err(|_| { spinner.finish_and_clear(); anyhow::anyhow!( - "Transaction timed out after 30s waiting for finalization. \ + "Transaction timed out after 30s waiting for block inclusion. \ The extrinsic may have been dropped from the pool \ (insufficient balance, invalid state, or node not producing blocks)." ) })? .map_err(|e| { + spinner.finish_and_clear(); + anyhow::anyhow!("{}", e) + })?; + let result = in_block.wait_for_success().await.map_err(|e| { spinner.finish_and_clear(); format_dispatch_error(e) })?; let hash = format!("{:?}", result.extrinsic_hash()); spinner.finish_and_clear(); - tracing::info!(tx_hash = %hash, elapsed_ms = start.elapsed().as_millis() as u64, "Extrinsic finalized"); + tracing::info!(tx_hash = %hash, elapsed_ms = start.elapsed().as_millis() as u64, "Extrinsic included in block"); Ok(hash) } From 464215e951feda65488b869f9a26796e17fa7953 Mon Sep 17 00:00:00 2001 From: grubbhook Date: Wed, 18 Mar 2026 03:20:50 +0000 Subject: [PATCH 4/5] Add -a/--amount and -u/--netuid short flags to stake subcommands Co-Authored-By: Claude Sonnet 4.6 --- src/cli/mod.rs | 184 ++++++++++++++++++++++++------------------------- 1 file changed, 92 insertions(+), 92 deletions(-) diff --git a/src/cli/mod.rs b/src/cli/mod.rs index a7fe861..2742931 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -182,7 +182,7 @@ pub enum Commands { #[arg(long)] dest: String, /// Amount of TAO to send - #[arg(long)] + #[arg(long, short = 'a')] amount: f64, }, @@ -388,7 +388,7 @@ pub enum CommitmentCommands { /// Set commitment data for a miner on a subnet (publishes endpoint info) Set { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Commitment data as key:value pairs (e.g., "endpoint:http://...,version:1.0") #[arg(long)] @@ -397,7 +397,7 @@ pub enum CommitmentCommands { /// Get commitment for a specific hotkey on a subnet Get { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Hotkey SS58 address #[arg(long)] @@ -406,7 +406,7 @@ pub enum CommitmentCommands { /// List all commitments on a subnet List { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, }, } @@ -421,7 +421,7 @@ pub enum SubscribeCommands { #[arg(long, default_value = "all")] filter: String, /// Filter by subnet UID (only show events mentioning this netuid) - #[arg(long)] + #[arg(long, short = 'u')] netuid: Option, /// Filter by account SS58 (only show events involving this address) #[arg(long)] @@ -546,10 +546,10 @@ pub enum StakeCommands { /// Add stake to a hotkey on a subnet Add { /// Amount of TAO to stake - #[arg(long)] + #[arg(long, short = 'a')] amount: f64, /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Hotkey SS58 (defaults to wallet hotkey) #[arg(long)] @@ -561,10 +561,10 @@ pub enum StakeCommands { /// Remove stake from a hotkey on a subnet Remove { /// Amount to unstake - #[arg(long)] + #[arg(long, short = 'a')] amount: f64, /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Hotkey SS58 #[arg(long)] @@ -585,7 +585,7 @@ pub enum StakeCommands { /// Move stake between subnets Move { /// Amount of alpha to move - #[arg(long)] + #[arg(long, short = 'a')] amount: f64, /// Source subnet #[arg(long)] @@ -600,10 +600,10 @@ pub enum StakeCommands { /// Swap stake between hotkeys on same subnet Swap { /// Amount - #[arg(long)] + #[arg(long, short = 'a')] amount: f64, /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Source hotkey #[arg(long)] @@ -624,16 +624,16 @@ pub enum StakeCommands { #[arg(long)] hotkey: Option, /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, }, /// Add stake with a limit price AddLimit { /// Amount of TAO - #[arg(long)] + #[arg(long, short = 'a')] amount: f64, /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Limit price #[arg(long)] @@ -648,10 +648,10 @@ pub enum StakeCommands { /// Remove stake with limit price RemoveLimit { /// Amount of alpha - #[arg(long)] + #[arg(long, short = 'a')] amount: f64, /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Limit price #[arg(long)] @@ -669,7 +669,7 @@ pub enum StakeCommands { #[arg(long)] take: f64, /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Hotkey SS58 #[arg(long)] @@ -678,7 +678,7 @@ pub enum StakeCommands { /// Set children for hotkey SetChildren { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Children as "proportion:hotkey_ss58" pairs, comma-separated #[arg(long)] @@ -687,10 +687,10 @@ pub enum StakeCommands { /// Recycle alpha tokens back to TAO RecycleAlpha { /// Amount of alpha to recycle - #[arg(long)] + #[arg(long, short = 'a')] amount: f64, /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Hotkey SS58 #[arg(long)] @@ -705,10 +705,10 @@ pub enum StakeCommands { /// Burn alpha tokens permanently (reduce supply) BurnAlpha { /// Amount of alpha to burn - #[arg(long)] + #[arg(long, short = 'a')] amount: f64, /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Hotkey SS58 #[arg(long)] @@ -717,7 +717,7 @@ pub enum StakeCommands { /// Swap stake between subnets with a limit price SwapLimit { /// Amount of alpha to swap - #[arg(long)] + #[arg(long, short = 'a')] amount: f64, /// Source subnet #[arg(long)] @@ -738,7 +738,7 @@ pub enum StakeCommands { /// Set auto-stake hotkey for a subnet (rewards auto-compound to this hotkey) SetAuto { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Hotkey SS58 to auto-stake to #[arg(long)] @@ -774,7 +774,7 @@ pub enum StakeCommands { #[arg(long)] dest: String, /// Amount of TAO to transfer - #[arg(long)] + #[arg(long, short = 'a')] amount: f64, /// Source subnet UID #[arg(long)] @@ -789,10 +789,10 @@ pub enum StakeCommands { /// Full staking wizard (interactive or non-interactive with flags) Wizard { /// Subnet UID (skip interactive subnet selection) - #[arg(long)] + #[arg(long, short = 'u')] netuid: Option, /// Amount of TAO to stake (skip interactive amount input) - #[arg(long)] + #[arg(long, short = 'a')] amount: Option, /// Hotkey SS58 (skip interactive hotkey selection) #[arg(long)] @@ -811,7 +811,7 @@ pub enum SubnetCommands { /// Show detailed info for a subnet Show { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Query at a specific block number (historical wayback) #[arg(long)] @@ -820,13 +820,13 @@ pub enum SubnetCommands { /// Show subnet hyperparameters Hyperparams { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, }, /// Show metagraph for a subnet (full or single UID) Metagraph { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Show only a specific neuron UID #[arg(long)] @@ -844,7 +844,7 @@ pub enum SubnetCommands { /// Load a cached metagraph snapshot from disk CacheLoad { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Block number to load (default: latest) #[arg(long)] @@ -853,13 +853,13 @@ pub enum SubnetCommands { /// List cached metagraph snapshots for a subnet CacheList { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, }, /// Diff two metagraph snapshots (current vs cached, or two cached blocks) CacheDiff { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// First block number (older, default: latest cached) #[arg(long)] @@ -871,7 +871,7 @@ pub enum SubnetCommands { /// Prune old cached metagraph snapshots CachePrune { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Number of snapshots to keep (default: 10) #[arg(long, default_value = "10")] @@ -880,7 +880,7 @@ pub enum SubnetCommands { /// Probe axon health for neurons on a subnet Probe { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Only probe specific UIDs (comma-separated) #[arg(long)] @@ -897,13 +897,13 @@ pub enum SubnetCommands { /// Register a neuron on a subnet (burn) RegisterNeuron { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, }, /// Register via POW Pow { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Number of threads #[arg(long, default_value = "4")] @@ -912,13 +912,13 @@ pub enum SubnetCommands { /// Dissolve a subnet (owner only) Dissolve { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, }, /// Live watch: tempo countdown, rate limits, commit-reveal status Watch { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Polling interval in seconds (default 12) #[arg(long, default_value = "12")] @@ -927,13 +927,13 @@ pub enum SubnetCommands { /// AMM liquidity dashboard: pool depth, slippage at common trade sizes Liquidity { /// Subnet UID (omit for all subnets) - #[arg(long)] + #[arg(long, short = 'u')] netuid: Option, }, /// Monitor a subnet: track registrations, weight changes, emission shifts, anomalies Monitor { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Polling interval in seconds (default 24 = ~2 blocks) #[arg(long, default_value = "24")] @@ -945,25 +945,25 @@ pub enum SubnetCommands { /// Show subnet health: all miners, status, weights vs consensus Health { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, }, /// Show who's earning what, projected next epoch Emissions { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, }, /// Show current registration cost + recent trend Cost { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, }, /// Show pending weight commits on a subnet (commit-reveal status) Commits { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Filter by hotkey SS58 address (default: show all) #[arg(long)] @@ -972,7 +972,7 @@ pub enum SubnetCommands { /// Set a subnet hyperparameter (subnet owner only) SetParam { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Parameter name (e.g., tempo, max_allowed_uids, min_burn). Use --param list to see all. #[arg(long)] @@ -984,7 +984,7 @@ pub enum SubnetCommands { /// Set subnet token symbol (subnet owner only) SetSymbol { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Token symbol (e.g. "ALPHA", "SN1") #[arg(long)] @@ -993,13 +993,13 @@ pub enum SubnetCommands { /// Show emission split across mechanisms for a subnet EmissionSplit { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, }, /// Trim UIDs to a specified max on your subnet (subnet owner only) Trim { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Maximum number of UIDs to keep #[arg(long)] @@ -1008,25 +1008,25 @@ pub enum SubnetCommands { /// Check if a subnet's emission schedule can be started CheckStart { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, }, /// Start a subnet's emission schedule (subnet owner only) Start { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, }, /// Show mechanism count for a subnet MechanismCount { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, }, /// Set mechanism count for a subnet (subnet owner only) SetMechanismCount { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Number of mechanisms #[arg(long)] @@ -1035,7 +1035,7 @@ pub enum SubnetCommands { /// Set emission split weights across mechanisms (subnet owner only) SetEmissionSplit { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Emission weights as comma-separated u16 values (e.g. "50,50" or "70,30") #[arg(long)] @@ -1044,7 +1044,7 @@ pub enum SubnetCommands { /// Snipe a registration slot — subscribe to blocks and register the instant a slot opens Snipe { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Maximum burn cost in TAO you're willing to pay (default: no limit) #[arg(long)] @@ -1069,7 +1069,7 @@ pub enum WeightCommands { /// Set weights on a subnet Set { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Weights as "uid:weight" pairs, comma-separated. /// Use "-" to read from stdin, or "@path" to read from a JSON file. @@ -1086,7 +1086,7 @@ pub enum WeightCommands { /// Commit weights (for commit-reveal enabled subnets) Commit { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Weights as "uid:weight" pairs #[arg(long)] @@ -1098,7 +1098,7 @@ pub enum WeightCommands { /// Reveal previously committed weights Reveal { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Weights as "uid:weight" pairs #[arg(long)] @@ -1113,7 +1113,7 @@ pub enum WeightCommands { /// Show on-chain weights set by validators on a subnet Show { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Show only weights set by this hotkey #[arg(long)] @@ -1125,13 +1125,13 @@ pub enum WeightCommands { /// Check commit status for your hotkey on a subnet Status { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, }, /// Atomic commit-reveal: commit weights, wait for reveal window, then auto-reveal CommitReveal { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Weights as "uid:weight" pairs, comma-separated. /// Use "-" to read from stdin, or "@path" to read from a JSON file. @@ -1203,7 +1203,7 @@ pub enum ViewCommands { /// Show neuron details Neuron { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Neuron UID #[arg(long)] @@ -1227,7 +1227,7 @@ pub enum ViewCommands { /// Show top validators by stake across subnets Validators { /// Subnet UID (omit for all subnets) - #[arg(long)] + #[arg(long, short = 'u')] netuid: Option, /// Max number of validators to show #[arg(long, default_value = "50")] @@ -1257,7 +1257,7 @@ pub enum ViewCommands { /// Subnet analytics (emission rates, top miners/validators, stats) SubnetAnalytics { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, }, /// Staking analytics (APY estimates, emission projections) @@ -1269,7 +1269,7 @@ pub enum ViewCommands { /// Simulate a TAO→Alpha swap (see how much alpha you'd get) SwapSim { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Amount of TAO to swap #[arg(long)] @@ -1287,7 +1287,7 @@ pub enum ViewCommands { /// Show metagraph with optional diff against a previous block Metagraph { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Compare against this block number (shows only changed neurons) #[arg(long)] @@ -1299,7 +1299,7 @@ pub enum ViewCommands { /// Look up axon endpoint for a specific UID or hotkey Axon { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Neuron UID #[arg(long)] @@ -1311,7 +1311,7 @@ pub enum ViewCommands { /// Subnet health: neuron count, active %, axon reachability Health { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// TCP-probe each axon to check reachability (slower but thorough) #[arg(long)] @@ -1323,7 +1323,7 @@ pub enum ViewCommands { /// Per-UID emission breakdown for a subnet Emissions { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Show only top N UIDs by emission #[arg(long)] @@ -1357,7 +1357,7 @@ pub enum IdentityCommands { /// Set subnet identity (subnet owner only) SetSubnet { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Subnet name #[arg(long)] @@ -1376,7 +1376,7 @@ pub enum ServeCommands { /// Set axon endpoint (IP, port, protocol) for a subnet Axon { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// IP address (IPv4) #[arg(long)] @@ -1394,7 +1394,7 @@ pub enum ServeCommands { /// Reset axon information for a neuron (clears serving endpoint) Reset { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, }, /// Batch update axon endpoints from a JSON file @@ -1873,7 +1873,7 @@ pub enum CrowdloanCommands { #[arg(long)] crowdloan_id: u32, /// Amount of TAO to contribute - #[arg(long)] + #[arg(long, short = 'a')] amount: f64, }, /// Withdraw contribution from an active crowdloan @@ -1948,7 +1948,7 @@ pub enum LiquidityCommands { /// Add a liquidity position to a subnet's AMM pool Add { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Lower price bound (TAO per Alpha) #[arg(long)] @@ -1966,7 +1966,7 @@ pub enum LiquidityCommands { /// Remove a liquidity position entirely Remove { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Position ID #[arg(long)] @@ -1978,7 +1978,7 @@ pub enum LiquidityCommands { /// Modify liquidity in an existing position Modify { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Position ID #[arg(long)] @@ -1993,7 +1993,7 @@ pub enum LiquidityCommands { /// Toggle user liquidity for a subnet (subnet owner only) Toggle { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Enable user liquidity #[arg(long)] @@ -2039,7 +2039,7 @@ pub enum DiffCommands { /// Compare subnet state between two blocks Subnet { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// First block number #[arg(long)] @@ -2060,7 +2060,7 @@ pub enum DiffCommands { /// Compare metagraph neurons between two blocks (shows changed neurons only) Metagraph { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// First block number #[arg(long)] @@ -2076,7 +2076,7 @@ pub enum UtilsCommands { /// Convert between TAO/RAO, or TAO/Alpha (requires --netuid for Alpha) Convert { /// Amount to convert - #[arg(long)] + #[arg(long, short = 'a')] amount: Option, /// Convert from TAO to RAO (default: RAO to TAO) #[arg(long)] @@ -2088,7 +2088,7 @@ pub enum UtilsCommands { #[arg(long)] alpha: Option, /// Subnet UID (required for TAO↔Alpha conversion) - #[arg(long)] + #[arg(long, short = 'u')] netuid: Option, }, /// Benchmark latency to network endpoints @@ -2210,7 +2210,7 @@ pub enum AdminCommands { /// Set tempo (blocks per epoch) SetTempo { /// Subnet UID - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, /// Tempo value #[arg(long)] @@ -2221,7 +2221,7 @@ pub enum AdminCommands { }, /// Set max allowed validators SetMaxValidators { - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, #[arg(long)] max: u16, @@ -2230,7 +2230,7 @@ pub enum AdminCommands { }, /// Set max allowed UIDs SetMaxUids { - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, #[arg(long)] max: u16, @@ -2239,7 +2239,7 @@ pub enum AdminCommands { }, /// Set immunity period SetImmunityPeriod { - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, #[arg(long)] period: u16, @@ -2248,7 +2248,7 @@ pub enum AdminCommands { }, /// Set minimum allowed weights SetMinWeights { - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, #[arg(long)] min: u16, @@ -2257,7 +2257,7 @@ pub enum AdminCommands { }, /// Set max weight limit SetMaxWeightLimit { - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, #[arg(long)] limit: u16, @@ -2266,7 +2266,7 @@ pub enum AdminCommands { }, /// Set weights rate limit (0 = unlimited) SetWeightsRateLimit { - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, #[arg(long)] limit: u64, @@ -2275,7 +2275,7 @@ pub enum AdminCommands { }, /// Enable/disable commit-reveal weights SetCommitReveal { - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, #[arg(long)] enabled: bool, @@ -2284,7 +2284,7 @@ pub enum AdminCommands { }, /// Set POW difficulty SetDifficulty { - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, #[arg(long)] difficulty: u64, @@ -2293,7 +2293,7 @@ pub enum AdminCommands { }, /// Set activity cutoff SetActivityCutoff { - #[arg(long)] + #[arg(long, short = 'u')] netuid: u16, #[arg(long)] cutoff: u16, From abd3d00880501b3e6aa38dfcae91c53ec88ca7b0 Mon Sep 17 00:00:00 2001 From: grubbhook Date: Thu, 19 Mar 2026 01:53:06 +0000 Subject: [PATCH 5/5] Fix concurrent_writes_no_corruption: unique tmp file per write All threads shared the same .{key}-{pid}.tmp path, causing concurrent writes to corrupt the temp file before rename. Add a global atomic counter so each put() call gets a distinct tmp path. Co-Authored-By: Claude Sonnet 4.6 --- src/queries/disk_cache.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/queries/disk_cache.rs b/src/queries/disk_cache.rs index f9c16ce..2eef939 100644 --- a/src/queries/disk_cache.rs +++ b/src/queries/disk_cache.rs @@ -74,8 +74,11 @@ pub fn put(key: &str, data: &T) -> Result<()> { }; let json = serde_json::to_string(&entry).context("Failed to serialize cache entry")?; - // Atomic write: temp file in same dir, then rename - let tmp = dir.join(format!(".{}-{}.tmp", key, std::process::id())); + // Atomic write: temp file in same dir, then rename. + // Include a per-write counter so concurrent threads don't share the same tmp path. + static TMP_COUNTER: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0); + let tmp_id = TMP_COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + let tmp = dir.join(format!(".{}-{}-{}.tmp", key, std::process::id(), tmp_id)); std::fs::write(&tmp, json.as_bytes()) .with_context(|| format!("Failed to write cache temp file: {}", tmp.display()))?;