Skip to content

Commit 45b3411

Browse files
committed
feat: major cleanup and security hardening
Security fixes: - Protect sudo_key in merge_from() from peer sync attacks - Preserve sudo_key in ForceStateUpdate action - Add comprehensive sudo security tests Code cleanup: - Remove unused dependencies (mockall, wiremock, rstest, tokio-test) - Remove unused schnorrkel from core (sp-core provides sr25519) - Fix dependency version mismatches (sentry, base64, reqwest) - Standardize workspace dependencies Structural improvements: - Remove 5 unused script crates from workspace - Add AGENTS.md files for key modules (p2p-consensus, core, validator-node, tests) - Update root AGENTS.md with security patterns - Add security documentation Clippy fixes: - Fix deprecated ChallengeConfig -> ChallengeRecord - Fix needless_borrows_for_generic_args - Fix unnecessary_to_owned - Fix to_string in format args - Remove unused macOS config in .cargo/config.toml All 189 tests pass.
1 parent ba21d10 commit 45b3411

File tree

34 files changed

+818
-4743
lines changed

34 files changed

+818
-4743
lines changed

.cargo/config.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,3 @@ PLATFORM_LINKER_RUSTFLAGS = { value = "${PLATFORM_LINKER_RUSTFLAGS}", force = fa
3636
PLATFORM_LINKER_RUSTFLAGS_DARWIN = { value = "${PLATFORM_LINKER_RUSTFLAGS_DARWIN}", force = false }
3737
RUSTFLAGS = { value = "${RUSTFLAGS} ${PLATFORM_NIGHTLY_RUSTFLAGS} ${PLATFORM_FAST_LINKER_RUSTFLAGS} ${PLATFORM_LINKER_RUSTFLAGS}", force = true }
3838

39-
[target.'cfg(target_os = "macos")'.env]
40-
RUSTFLAGS = { value = "${RUSTFLAGS} ${PLATFORM_NIGHTLY_RUSTFLAGS} ${PLATFORM_FAST_LINKER_RUSTFLAGS_DARWIN} ${PLATFORM_LINKER_RUSTFLAGS_DARWIN}", force = true }

.sisyphus/plans/subtensor-connection-retry.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ Wave FINAL (After ALL tasks - verification):
119119

120120
## TODOs
121121

122-
- [ ] 1. Add retry configuration to SubtensorClient
122+
- [x] 1. Add retry configuration to SubtensorClient
123123

124124
**What to do**:
125125
- Add `RetryConfig` struct to client.rs with `max_retries` and `retry_delay_ms`
@@ -161,7 +161,7 @@ Wave FINAL (After ALL tasks - verification):
161161
Evidence: .sisyphus/evidence/task-01-check.log
162162
```
163163

164-
- [ ] 2. Add with_retry() method for generic operations
164+
- [x] 2. Add with_retry() method for generic operations
165165

166166
**What to do**:
167167
- Add async `with_retry<F, T>(&mut self, operation: F) -> Result<T>` method
@@ -228,7 +228,7 @@ Wave FINAL (After ALL tasks - verification):
228228
Evidence: .sisyphus/evidence/task-02-check.log
229229
```
230230

231-
- [ ] 3. Wrap WeightSubmitter methods with retry
231+
- [x] 3. Wrap WeightSubmitter methods with retry
232232

233233
**What to do**:
234234
- Refactor `submit_direct()` to use retry
@@ -286,7 +286,7 @@ Wave FINAL (After ALL tasks - verification):
286286
Evidence: .sisyphus/evidence/task-03-build.log
287287
```
288288

289-
- [ ] 4. Wrap MechanismWeightManager methods with retry
289+
- [x] 4. Wrap MechanismWeightManager methods with retry
290290

291291
**What to do**:
292292
- Refactor `submit_mechanism_direct()` to use retry
@@ -314,7 +314,7 @@ Wave FINAL (After ALL tasks - verification):
314314
- [ ] All mechanism weight methods use retry
315315
- [ ] `cargo test -p platform-bittensor --lib` passes
316316

317-
- [ ] 5. Wrap ValidatorSync with retry
317+
- [x] 5. Wrap ValidatorSync with retry
318318

319319
**What to do**:
320320
- Modify `sync()` method to use retry for `sync_metagraph()` call
@@ -341,13 +341,13 @@ Wave FINAL (After ALL tasks - verification):
341341

342342
## Final Verification Wave
343343

344-
- [ ] F1. Add retry scenario tests
344+
- [x] F1. Add retry scenario tests
345345
Add unit tests that simulate connection failures and verify retry behavior.
346346

347-
- [ ] F2. Run full test suite
347+
- [x] F2. Run full test suite
348348
Verify no regressions: `cargo test --workspace --all-features`
349349

350-
- [ ] F3. Integration verification
350+
- [x] F3. Integration verification
351351
Manual verification that weight submission recovers from simulated disconnects.
352352

353353
---
@@ -368,9 +368,9 @@ cargo test --workspace --all-features # Expected: all tests pass
368368
```
369369

370370
### Final Checklist
371-
- [ ] RetryConfig added to SubtensorClient
372-
- [ ] with_retry() method implemented with exponential backoff
373-
- [ ] WeightSubmitter methods wrapped with retry
374-
- [ ] MechanismWeightManager methods wrapped with retry
375-
- [ ] ValidatorSync wrapped with retry
376-
- [ ] Tests for retry scenarios added
371+
- [x] RetryConfig added to SubtensorClient
372+
- [x] with_retry() method implemented with exponential backoff
373+
- [x] WeightSubmitter methods wrapped with retry
374+
- [x] MechanismWeightManager methods wrapped with retry
375+
- [x] ValidatorSync wrapped with retry
376+
- [x] Tests for retry scenarios added

AGENTS.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,81 @@ Platform is fully decentralized—validators communicate directly via P2P withou
202202
See the main README for deployment instructions.
203203

204204
For challenge-specific questions, refer to the appropriate challenge crate or repository.
205+
206+
---
207+
208+
## Security Patterns (CRITICAL)
209+
210+
### sudo_key Protection
211+
212+
**INVARIANT**: The `sudo_key` field in `ChainState` CANNOT be changed via:
213+
- Peer state synchronization (`merge_from()`)
214+
- ForceStateUpdate action
215+
- Direct state manipulation
216+
217+
**Implementation** (`core/state.rs`):
218+
```rust
219+
// merge_from() preserves local sudo_key
220+
let local_sudo_key = self.sudo_key.clone();
221+
// ... merge other fields ...
222+
self.sudo_key = local_sudo_key; // RESTORE
223+
224+
// ForceStateUpdate also preserves sudo_key
225+
*self = state.clone();
226+
self.sudo_key = local_sudo_key; // SECURITY
227+
```
228+
229+
### Authorization Check Pattern
230+
231+
All privileged operations require `is_sudo()` verification:
232+
```rust
233+
// consensus.rs lines 221, 363
234+
if change_type == StateChangeType::ConfigUpdate {
235+
let is_sudo = self.state_manager.read(|s| s.is_sudo(&proposer));
236+
if !is_sudo {
237+
return Err(ConsensusError::InvalidProposal(...));
238+
}
239+
}
240+
```
241+
242+
### CRITICAL Warning Pattern
243+
244+
"CRITICAL: must use chain state, not system time" appears in:
245+
- `vendor/bittensor-rs/src/crv4/mod.rs`
246+
- `vendor/bittensor-rs/src/subtensor.rs`
247+
- `crates/bittensor-integration/src/weights.rs`
248+
249+
Prevents clock skew manipulation attacks.
250+
251+
---
252+
253+
## Test Patterns
254+
255+
**Integration Tests** (`tests/`):
256+
- Separate workspace member (`platform-e2e-tests`)
257+
- Fixture helpers: `create_chain_state()`, `create_five_validators()`
258+
- `tempfile::tempdir()` for storage isolation
259+
- `MockChallenge` pattern for challenge testing
260+
261+
**Unit Tests** (inline):
262+
- `#[cfg(test)] mod tests` at file end
263+
- `use super::*` for parent access
264+
- `#[tokio::test]` for async
265+
266+
---
267+
268+
## Commands Quick Reference
269+
270+
```bash
271+
# Development
272+
cargo build --release # Full build
273+
cargo test --workspace # All unit tests
274+
cargo clippy --all-targets # Lint check
275+
276+
# Integration (requires Docker)
277+
cargo test -p platform-e2e-tests --test integration_test
278+
279+
# Single crate
280+
cargo test -p platform-core
281+
cargo test -p platform-p2p-consensus
282+
```

0 commit comments

Comments
 (0)