Skip to main content

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 blockDays past graceDecay factorEffective emission share
001.00100%
101.00100%
301.00100% (last grace day)
740.8080%
14110.4545%
23200.2525% (floor reached)
30270.2525% (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.