
Thanks to Léo Mercier for sharing the initial article on X. We’ve repurposed it here into a blog post format:
In Bittensor, subnet de-registration occurs when a network reaches its subnet capacity and requires pruning. This process ensures the protection of both alpha holders (stakers) and subnet owners. When a subnet is pruned, its state is dissolved fairly: stakers receive their proportional share of the subnet’s TAO pot based on effective α value, directly credited to their coldkey balances. Active α-in/α-out positions are cleared, with α burned and liquidity pools reset.
Subnet owners have their emissions valued in TAO, offset against their original lock, and any remaining balance refunded. This allows stakers to exit with equitable rewards, owners to recover unused locks post-emissions, and the netuid to be recycled for new registrations.
How Subnet Pruning is Triggered
Subnet pruning activates upon reaching the SubnetLimit (default: 128 non-root subnets). The process involves:
- Excluding subnets protected by the NetworkImmunityPeriod.
- Selecting the subnet with the lowest price EMA (exponential moving average of α/τ price signal) among eligible ones.
- If EMAs tie, choosing the subnet with the earliest registration timestamp.
This ensures only underperforming or older subnets are targeted for de-registration.
Mechanics in the Code
The implementation integrates pruning into the registration flow:
- Subnet Cap and Trigger: A SubnetLimit caps non-root subnets. During registration, if the limit is met, the system identifies a prune candidate via
get_network_to_prune()
or RPCget_subnet_to_prune
. If none is available, registration fails withSubnetLimitReached
. - Registration Flow with Pruning: Standard checks (e.g., rate limits, lock affordability—now
CannotAffordLockCost)
precede pruning. If pruning occurs,do_dissolve_network(prune_netuid)
executes before finalizing the new subnet, reusing the freed netuid. - Dissolution Process (
do_dissolve_network
):- Swap/Liquidity: Closes all LP positions, refunds TAO principal, burns α, clears ticks/positions, and disables liquidity.
- Alpha/Stake Accounting: Computes owner emissions in TAO (via sim_swap or price multiplication), distributes TAO pot pro-rata to stakers (using largest-remainder rounding), clears α-in/α-out states, and refunds remaining lock to owner (lock_cost minus emissions, minimum zero). Zeros subnet’s locked balance.
- Commitments and Storage: Purges netuid state via
CommitmentsInterface::purge_netuid
, clearing commitments, bonds, revealed data, used space, and timelocked indices. - Identity/Metadata: Removes subnet identity and resets flags/storage for new initialization.
These steps ensure a clean dissolution and immediate recycling.
Administrative Controls and Surface Area
Root-level controls include:
sudo_set_subnet_limit(max_subnets)
to adjust the cap, emittingSubnetLimitSet(u16)
.root_dissolve_network(netuid)
for forced dissolution.- Runtime API/RPC:
get_subnet_to_prune()
viasubnetInfo_getSubnetToPrune
for querying prune candidates.
This provides governance over network capacity and manual interventions.
Migrations and Constants
On upgrade, a migration sets NetworkImmunityPeriod
to 1,296,000 and aligns SubnetLimit
with the default. Tests adjust limits to prevent unintended pruning during bulk registrations.
Events and Errors
- Events:
SubnetLimitSet(u16)
, alongside existingNetworkRemoved
,NetworkAdded
, etc. - Errors:
SubnetLimitReached
,CannotAffordLockCost
, and standard registration/dissolution errors.
These notifications aid in monitoring and debugging.
Net Effect and Mental Model
At full capacity, new registrations automatically prune and recycle subnets: LPs close, stakers receive TAO payouts, α is burned/cleared, owners get refunds minus emissions, commitments are wiped, and the netuid reissues to the new subnet. This maintains network efficiency while fairly compensating participants.
Be the first to comment