Skip to content

Releases: hanlinai/engy

v0.4.1 — a rejected extrinsic was being recorded as a success

Choose a tag to compare

@crabbytt crabbytt released this 21 Jul 17:49
af5fb39

v0.4.1 — a rejected extrinsic was being recorded as a success

UPGRADE IF YOU ARE ON 0.4.0. A validator on 0.4.0 that logged
set_weights(...) -> True may have submitted nothing at all.

bittensor 10.x returns an ExtrinsicResponse from set_weights. It mimics a
tuple but is not one, and defines no bool, so every rejection read as
success: state advanced, the loop waited out a full resubmit interval before
retrying, and no weights reached the chain while the container stayed
healthy.

Seen in production against a hotkey with no validator permit - the log said
True while its on-chain weights stayed empty and last_update never moved.

The rejection reason is now logged with it:

[chain] set_weights(1 uids) -> False (No validator permit)

Introduced in 0.4.0 with the bittensor 9 -> 10 upgrade.

If you ran 0.4.0, check last_update and your weights on chain rather than
trusting the log.

v0.4.0 — the image can now reach the chain

Choose a tag to compare

@crabbytt crabbytt released this 21 Jul 14:42
342ee2d

v0.4.0 — the image can now reach the chain

UPGRADE IMMEDIATELY. Every previous 0.x image sets no weights at all: it
fetches and verifies correctly, then fails at [chain] open failed on every
tick, while the container reports healthy the whole time.

Cause: bittensor 9.x pins scalecodec but leaves async-substrate-interface
open at the top, and asi 2.0 replaced scalecodec with cyscale claiming the
same namespace - so the two refuse to coexist and bittensor raises at
import. No configuration of bittensor 9.x works against the current finney
runtime. Moved to bittensor 10.5, which completed that migration and bounds
asi itself, and dropped substrate-interface, which was the last thing
pulling scalecodec back in.

Verified in a clean install against live finney: 256 hotkeys read from
netuid 53 and a burn vector resolving to uid 229.

Known issue, not fixed here: the pinned Watchtower image speaks a Docker API
version newer daemons refuse, and crash-loops. If your Watchtower is
restarting, this release will not reach you automatically - pull it by hand:

docker compose --env-file .env.validator -f docker/docker-compose.validator.yml pull
docker compose --env-file .env.validator -f docker/docker-compose.validator.yml up -d

v0.3.1 — visible liveness, and two 0.3.0 defects

Choose a tag to compare

@crabbytt crabbytt released this 21 Jul 13:31
08be557

v0.3.1 — visible liveness, and two 0.3.0 defects

UPGRADE IF YOU ARE ON 0.3.0. Two of these are startup/connectivity defects.

  • The Docker entrypoint still required ENGY_SN53_API and
    ENGY_SN53_MASTER_HOTKEY, so a container configured per 0.3.0's own
    documentation - wallet only - refused to start. Fixed; those two are
    optional everywhere now.

  • The provider renamed /weights/latest to /epoch/latest with no alias.
    0.3.0 requests the old path and gets 404 on every poll. Staging already
    serves only the new path; production has not been redeployed yet.

  • Every tick now logs. The two skipped:too-soon paths were silent, and with
    a 300s poll and a ~24min resubmit interval four ticks in five skip, so a
    healthy validator and a wedged one looked identical to anyone tailing the
    logs. Each skip now reports which epoch is already submitted and how long
    until the next resubmit.

Required configuration is still just your wallet:

ENGY_SN53_WALLET=<your wallet name>
ENGY_SN53_WALLET_HOTKEY=<your hotkey name>

v0.3.0 — configuration matches what an operator knows

Choose a tag to compare

@crabbytt crabbytt released this 21 Jul 12:39
b9a361e

v0.3.0 — configuration matches what an operator knows

Required configuration is now just your bittensor wallet:

ENGY_SN53_WALLET=<your wallet name>
ENGY_SN53_WALLET_HOTKEY=<your hotkey name>

ENGY_SN53_API and ENGY_SN53_MASTER_HOTKEY are protocol constants, identical
for everyone on the subnet, and now default in code. Override them together
only to point at a non-production deployment - the master hotkey signs only
for the provider that holds it, so a mismatched pair rejects every payload.

BREAKING for one case: the wallet names no longer default to bittensor's
"default" naming. A deployment that relied on that now fails at startup
instead of signing with whatever wallet happens to carry that name. Set both
explicitly.

Everything in the v0.2.0 notes still applies, including the reason to upgrade
from 0.1.0.

v0.2.1 — correct the expected burn target

Choose a tag to compare

@crabbytt crabbytt released this 21 Jul 12:01
f1230bf

v0.2.1 — correct the expected burn target

v0.2.0 pinned the chain's SubnetOwnerHotkey (5F2HTUq..., uid 161) as the
expected burn recipient. That was inferred from chain state rather than
confirmed against the provider's configuration, and it is wrong: the
provider's owner_hotkey is 5DXSBCC... (uid 229), the same key that signs
epoch results.

Effect on 0.2.0: a warning line on every burn naming a correct payload as
suspect. Weights were still submitted — the check warns rather than rejects,
so the wrong value cost a misleading log rather than a fleet-wide refusal to
submit.

No other changes. Everything in the v0.2.0 notes still applies, including the
reason to upgrade from 0.1.0.

v0.2.0 — resubmit scheduling, epoch decoupling

Choose a tag to compare

@crabbytt crabbytt released this 21 Jul 11:54
f548bf2

v0.2.0 — resubmit scheduling, epoch decoupling

FIXES A LIVE OUTAGE. 0.1.0 pinned EPOCH_S=604800 and a genesis timestamp
locally and required the payload's epoch to equal current-1. Neither matched
production (epoch_s=86400) or staging (3600), so every payload was rejected as
stale-epoch — with no error, no non-zero exit and a healthy heartbeat. Anyone
running 0.1.0 is setting no weights at all. Upgrade.

Changes:

  • Weights are resubmitted every 120 blocks for the whole epoch instead of once.
    A validator that submits once per epoch passes activity_cutoff (~16.7h) long
    before a daily epoch closes and drops out of Yuma consensus. 120 rather than
    100 because SN53's on-chain weights_rate_limit is exactly 100, and our anchor
    is the block read before submitting while the chain's is the block the
    extrinsic executed in — always later.

  • The validator is no longer epoch-aware. EPOCH_S, epoch_index() and
    ENGY_SN53_GENESIS_TS are gone; the provider owns the timeline. Replay is
    bounded by a monotonic guard on local state instead.

  • The last submitted vector is cached and resubmitted during a provider
    outage, so an outage past activity_cutoff cannot take the validator off
    chain. Unbounded in time by design: the chain keeps the last weights either
    way, so stopping costs only our own dividends.

  • A burn paying out to an unexpected owner hotkey is flagged (warning, never a
    rejection), and a fully-unregistered vector now names its likely cause
    instead of reading as a chain error.

  • Poll interval 600s -> 300s.

Operator notes:

  • ENGY_SN53_GENESIS_TS is no longer read. Leaving it set is harmless.
  • Required config is now just ENGY_SN53_API and ENGY_SN53_MASTER_HOTKEY.
  • ENGY_SN53_RESUBMIT_BLOCKS overrides the 120-block cadence if a subnet's
    weights_rate_limit ever exceeds it.

Known gap: prod genesis is 2026-07-22 00:00 UTC and the first epoch finalizes
25h later, while activity_cutoff is ~16.7h. Validators running from genesis
have nothing to submit until then. The fix is provider-side and tracked
separately.