Emission suppression via root validator voting#2420
Emission suppression via root validator voting#2420ppolewicz wants to merge 18 commits intodevnet-readyfrom
Conversation
- Add EmissionSuppression<T> storage map (NetUid -> U64F64) for stake-weighted suppression fraction per subnet - Add normalize_shares() helper to re-normalize shares to sum to 1.0 - Add apply_emission_suppression() to zero shares of suppressed subnets (suppression > 0.5) and re-normalize remaining shares - Call apply_emission_suppression in get_subnet_block_emissions after get_shares - Clean up EmissionSuppression in remove_network Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add EmissionSuppressionOverride<T> storage map (NetUid -> Option<bool>) for root override of suppression per subnet - Modify apply_emission_suppression to check override first: Some(true) forces suppression, Some(false) forces unsuppression, None falls back to vote-based EmissionSuppression value - Add sudo_set_emission_suppression_override extrinsic (call_index 133) - Clean up EmissionSuppressionOverride in remove_network Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add EmissionSuppressionVote<T> storage double map (NetUid, AccountId -> bool) for per-coldkey votes on subnet emission suppression - Add vote_emission_suppression extrinsic (call_index 134): requires signed coldkey owning root-registered hotkey with stake >= threshold - Add collect_emission_suppression_votes() called per-subnet on epoch: iterates root validators, accumulates stake-weighted votes, updates EmissionSuppression fraction - Add transfer_emission_suppression_votes in do_swap_coldkey for coldkey swap migration - Clean up EmissionSuppressionVote in remove_network - New errors: CannotVoteOnRootSubnet, NotEnoughStakeToVote - New event: EmissionSuppressionVoteCast Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
13 test scenarios covering: - Share zeroing and renormalization with majority suppression - No effect when suppression is below 50% - Root override force suppress/unsuppress - Override=None falls back to votes - Vote requires root registration and minimum stake - Vote clearing removes suppression - Votes collected only on epoch - Coldkey swap migrates votes - Network dissolution clears all suppression state - Share renormalization across 3 subnets - Unstaked TAO not counted in suppression denominator Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add KeepRootSellPressureOnSuppressedSubnets<T> storage (default true): controls whether root validators receive alpha dividends from suppressed subnets - Add sudo_set_keep_root_sell_pressure_on_suppressed_subnets extrinsic (call_index 135) - Modify emit_to_subnets: when flag is false and subnet is suppressed, root_alpha is zeroed and all validator alpha goes to subnet validators - Add is_subnet_emission_suppressed() helper to deduplicate suppression check logic - Refactor apply_emission_suppression to use the new helper - Add 3 tests (14-16): root alpha on suppressed subnet with flag on/off, and unsuppressed subnet unaffected by flag Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add events for sudo_set_emission_suppression_override and sudo_set_keep_root_sell_pressure_on_suppressed_subnets - Fix missing read in sudo_set_emission_suppression_override weight - Add early return guard in collect_emission_suppression_votes for root - Fail coldkey swap if destination already has emission suppression votes (new error: DestinationColdkeyHasExistingVotes) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- test_vote_on_root_subnet_rejected: CannotVoteOnRootSubnet error - test_vote_explicit_false: Some(false) stored, produces 0 suppression - test_all_subnets_suppressed: all shares zeroed, zero total emission - test_coldkey_swap_blocked_by_existing_votes: swap fails with error - test_multi_hotkey_coldkey_vote_weight: 3 hotkeys, weight = sum stakes - test_sudo_override_emits_event: EmissionSuppressionOverrideSet event - test_sudo_sell_pressure_emits_event: KeepRootSellPressureSet event - test_collect_votes_skips_root: ROOT no-op guard Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2dc0894 to
752f5c3
Compare
c6158be to
11b0d5f
Compare
…hip workflow Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nedHotkeys, R-9 root guard, R-11 cache netuids, R-12 call_index order, R-13 saturating fold, R-14 narrow lints, R-16 allow vote cleanup - R-1: Move DestinationColdkeyHasExistingVotes check to top of do_swap_coldkey before any mutations; make transfer_emission_suppression_votes infallible - R-2: Increase vote_emission_suppression weight from reads(5) to reads(131) to account for up to 64 hotkeys at 2 reads each plus 3 base reads - R-5: Use OwnedHotkeys instead of StakingHotkeys for vote eligibility so only hotkeys owned by the coldkey qualify - R-9: Add root subnet guard to sudo_set_emission_suppression_override - R-11: Cache get_all_subnet_netuids in transfer_emission_suppression_votes - R-12: Reorder extrinsics so call indices appear in ascending order (132-135) - R-13: Replace .sum() with saturating_add fold in test - R-14: Remove blanket #![allow(unused)] from test file - R-16: Skip stake threshold check when clearing a vote (suppress=None) so deregistered coldkeys can clean up stale entries Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix compiler warnings for unused variables by prefixing them with underscores. All tests pass successfully. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…bnetsMode enum Introduce a 3-mode enum (Disable/Enable/Recycle) to control how root alpha dividends are handled on emission-suppressed subnets. Recycle mode (new default) swaps root alpha to TAO via AMM and burns it, creating sell pressure without benefiting root validators. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…king - Use add_dynamic_network to properly initialize AMM for swap tests - Add record_tao_outflow call after swap_alpha_for_tao in recycle path - Check SubnetTAO decrease instead of SubnetMovingPrice (needs epoch) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…dec indices, R-10 doc fix - R-1: Add else fallback to recycle alpha when swap_alpha_for_tao fails in Recycle mode, preventing orphaned tokens - R-3: Cache is_subnet_emission_suppressed result to avoid double storage read per subnet per block - R-8: Add explicit #[codec(index)] annotations to enum variants for migration safety - R-10: Fix misleading doc comment on Disable variant Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ression * origin/devnet-ready: (81 commits) Bump spec version Update subtensor pallet weights Spec bump auto-update benchmark weights Bump spec version Add precompile integration tests Fix subnet_buyback benchmark Fix build errors Add freeze struct to TickIndex and PositionId More user liquidity cleanup Cleanup test_claim_root_coinbase_distribution test Remove unused user liquidity code Add current_alpha_price_all swap RPC, add slippage to sim_swap_tao_for_alpha and sim_swap_alpha_for_tao More balancer docs Balancer documentation Spec bump Add get_base_needed_for_quote method to balancer (for alpha fees) Add logging for errors in disable_lp Fix add_liquidity signature Bump spec version ...
…add constant, fix weight
R-1: Disable mode now actually recycles root_alpha to PendingValidatorEmission
instead of zeroing it before computation. Validators get explicitly more.
R-7: Extract EMISSION_SUPPRESSION_THRESHOLD constant (0.5) to avoid magic number.
R-9: Rename suppression_mode → root_sell_pressure_mode for clarity.
R-12: Fix weight for sudo_set_emission_suppression_override: reads(1) → reads(2).
Adds test_disable_mode_recycles_root_alpha_to_validators which verifies that
Disable mode validators receive more than Enable mode by exactly the root
alpha amount.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Code Review Fixes (136c1a4)Addressed findings from automated code review after merging R-1: Disable mode now actually recycles root alpha to validatorsPreviously, Disable mode zeroed R-7: Extract suppression threshold constantReplaced magic number R-9: Clarify variable namingRenamed R-12: Fix weight estimation
New test
|
Summary
Adds a mechanism for root validators to vote to suppress TAO emissions from subnets they believe are not operating in the network's interest. When more than half of the stake-weighted root validators vote to suppress a subnet, its emission share is zeroed and redistributed proportionally to the remaining subnets.
Key features
sudo_set_emission_suppression_override) allows root to force-suppress or force-unsuppress any subnet, bypassing the vote outcome.KeepRootSellPressureOnSuppressedSubnets, defaulttrue) controls whether root validators still receive alpha dividends from suppressed subnets. When disabled, all alpha goes to subnet validators instead — removing root sell pressure on the suppressed subnet's token.New extrinsics
sudo_set_emission_suppression_overridevote_emission_suppressionsudo_set_keep_root_sell_pressure_on_suppressed_subnetsNew storage items
EmissionSuppression<NetUid → U64F64>— current suppression ratio per subnetEmissionSuppressionOverride<NetUid → Option<bool>>— root override per subnetEmissionSuppressionVote<(NetUid, AccountId) → Option<bool>>— per-coldkey vote per subnetKeepRootSellPressureOnSuppressedSubnets<bool>— global flag (default true)Tests
24 test scenarios covering:
Test plan
cargo test -p pallet-subtensor --lib)cargo clippy --workspace --all-features --all-targetscleanscripts/fix_rust.shclean🤖 Generated with Claude Code