Documentation Index
Fetch the complete documentation index at: https://docs.bitrecs.ai/llms.txt
Use this file to discover all available pages before exploring further.
Bitrecs V2 applies a time-based decay factor to the emissions a winning miner receives. The intent is to encourage miners to iterate and improve their artifacts over time: a fresh submission earns full emissions, while an artifact that has been sitting unchanged for weeks gradually sees its share decrease. The decay is applied at the moment set_weights is called, using the miner’s first registered block as the start of their tenure.
How decay is calculated
The calculate_decay_factor function in scoring/engine.py converts block numbers to elapsed time and applies the decay curve:
# scoring/engine.py
def calculate_decay_factor(
first_block: int,
current_block: int,
block_time_seconds: int = 12,
) -> float:
if first_block <= 0 or first_block >= current_block:
return 1.0
time_elapsed_seconds = (current_block - first_block) * block_time_seconds
grace_period_seconds = GRACE_PERIOD_DAYS * 24 * 3600 # 3 days
if time_elapsed_seconds <= grace_period_seconds:
return 1.0
days_past_grace = (time_elapsed_seconds - grace_period_seconds) / (24 * 3600)
decay_factor = max(DECAY_FLOOR, 1.0 - DECAY_FACTOR * days_past_grace)
return decay_factor
Constants
# scoring/constants.py
GRACE_PERIOD_DAYS = 3 # no decay for the first 3 days
DECAY_FACTOR = 0.05 # 5% reduction per day after the grace period
DECAY_FLOOR = 0.25 # emissions never fall below 25% of full value
Block time is assumed to be 12 seconds. At 7,200 blocks per day, 3 days corresponds to approximately 21,600 blocks past the miner’s first registered block.
Example decay values
| Days since first block | Days past grace | Decay factor | Effective emission share |
|---|
| 0 | 0 | 1.00 | 100% |
| 1 | 0 | 1.00 | 100% |
| 3 | 0 | 1.00 | 100% (last grace day) |
| 7 | 4 | 0.80 | 80% |
| 14 | 11 | 0.45 | 45% |
| 23 | 20 | 0.25 | 25% (floor reached) |
| 30 | 27 | 0.25 | 25% (floor, clamped) |
The floor kicks in at 15 days past the grace period (day 18 total). After that point, a miner’s emission share stays fixed at 25% until they submit a new artifact with a more recent first block.
How decay applies to onchain weights
Inside set_weights_onchain, the decay factor scales the miner’s portion of total weight. The remainder is directed to the burn address (UID 0):
# scoring/engine.py
decay_factor = calculate_decay_factor(first_block, current_block)
miner_weight = MINER_EMISSION_PORTION * decay_factor
burn_weight = 1 - miner_weight
uids = [0, weight_receiving_uid]
weights = [burn_weight, miner_weight]
When MINER_EMISSION_PORTION = 0.0, the entire weight goes to the burn address regardless of the decay factor. Decay only becomes meaningful once MINER_EMISSION_PORTION is set to a positive value.
Burn-only mode
When MINER_EMISSION_PORTION = 0.0, the engine short-circuits to set_weights_burn_only, which skips the full scoring pipeline for weight-setting purposes and directs 100% to UID 0:
# scoring/engine.py
if set_weights and MINER_EMISSION_PORTION <= 0:
return await set_weights_burn_only(current_set_id, validator_hotkey, netuid)
The scoring pipeline (screeners, Pareto frontier, WTA) still executes and logs results in burn-only mode; only the final set_weights call is redirected.