fix: bring production hotfixes into main; algorithm 3 empty-epoch burn - #313
Merged
Merged
Conversation
Two changes, both needed to run a validator whose hotkey is an exported Polkadot keystore and whose subnet has no miners yet. # The hotkey file decides how it is read `bittensor_wallet.Wallet` derives a hotkey from the BIP-39 mnemonic in `secretPhrase` and overwrites `privateKey`, `publicKey` and `ss58Address` with whatever that phrase produces. A keystore key is a 64-byte expanded secret and no mnemonic produces it. Measured against the wallet library: a file carrying only `privateKey` raises `KeyFileError: Invalid phrase`, and a file carrying a valid phrase beside a foreign `privateKey` silently reloads the phrase's key. A keystore lives at the path a mnemonic wallet already uses, so the command line does not change and the deploy gate keeps auditing the surface it audited. `carries_private_key` reads the file: a `secretPhrase` means the wallet library owns it, a usable `privateKey` without one means this loader does. The loader builds only what the submit path asks of a wallet and refuses a public or symlinked file, a key that is neither 32 nor 64 bytes, a non-sr25519 `cryptoType`, and a key whose public half does not match the ss58 it declares. # The consensus seed is checked only where it is read `consensus_seed()` ran unconditionally. That seed signs cross-validator root statements and dissents, which exist only under `--peer-consensus`. A gateway-backed validator therefore failed at startup over a value it would never read. The check now runs only with `--peer-consensus`. # The zero-miner burn carries the declared allocation With no miner claiming anything, the vector was padded across arbitrary uids at equal weight, which said nothing about the challenge document: bounty and proof burned alike. The burn now carries the declared fractions, so the proof share is what burns when nothing is claimed. The chain's minimum-weight count is still met; only the mass changed. Verified: 55 tests pass; each guard checked by reintroducing its defect and watching the test fail; ruff, mypy, check_repo and check_deploy clean; against a real 64-byte operator key the loader derives its declared ss58 and signs a 64-byte signature `sr25519.verify` accepts. Still unproven: no weight submitted to a live subnet from a private-key wallet, and no bundle with a non-zero miner set aggregated here. Nine tests in proof/, test_master and test_network_e2e fail on origin/main here and are untouched. Co-Authored-By: Claude Code <noreply@anthropic.com>
The zero-miner burn fix spreads only the declared shares. Under algorithm 3 every share scales with its claimed score, so an epoch nobody scored in declares no mass and sealing failed; that epoch now burns in full. The e2e weight check compares normalized weights, as the chain does. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
- Hotkey exposes crypto_type (sr25519), which the substrate signer reads first - a hotkey file whose secretPhrase does not derive its declared ss58Address is refused instead of silently signing as another account (btcli files carry both) - --wallet-name and --wallet-hotkey are required Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Contributor
Author
|
The outside-diff findings (missing Greptile (@greptileai) please re-review. |
Mathis (echobt)
added a commit
that referenced
this pull request
Sep 26, 2026
main (#313) already carries this branch's privateKey keystore (with the secretPhrase/ss58Address check and crypto_type), the algorithm 3 empty-epoch burn, and the master background-failure logging. Conflicts resolved to main's side; the duplicate zero-miner burn is dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR brings the fixes that only live on the production master into
main, and fixes one conflict they have with algorithm 3.Today the master (
cortex-deploy,/opt/cortex) runs thefix/hotkeybranch (af44660) plus an uncommitted change tosrc/cortex/master.py. Neither exists onmain, so deployingmain, which is needed for the challenge supervisor and OpenType, would silently drop them. This PR:privateKey, and a zero-miner epoch burns only the declared shares.master.py: the end of a completed epoch is found even when the chain has pruned the state at the remembered start block. On mainnet, epoch 25267 had stopped sealing because of this.no challenge carries an emission share, and sealing failed. That epoch now burns the whole vector. The e2e test compares normalized weights, as the chain does.The trust-root edits in the production working tree (
config/*.toml,.sig,owner.pubkey, an unsigned template) are not included. They are operator material handled by the offline ceremony.Tests
ruff format,ruff checkand the repository contracts pass.pytest: 1100 passed.test_v3_with_no_score_burns_everything.🤖 Generated with Claude Code
No outstanding findings block merging.
Summary
This PR includes private-key validator hotkey loading, historical epoch-end lookup, and empty-epoch burn handling. The three previously reported validator issues are fixed in the current code.
Reviews (2) · Last reviewed commit: "fix(validator): signable private-key hot..."