refactor(blockchain): consolidate XMSS preparation window advance logic#388
Conversation
Greptile SummaryThis PR removes duplicated XMSS key-advance loops from
Confidence Score: 4/5The signing paths are logic-equivalent to the code they replace; the only real delta is that The refactor correctly unifies control flow and the error-propagation wiring through both crates/blockchain/src/key_manager.rs — the
|
| Filename | Overview |
|---|---|
| crates/blockchain/src/key_manager.rs | Consolidates duplicate XMSS advance loops into a single advance_key helper that now returns Result; advance_keys_to swallows errors with inspect_err; tracing switches to elapsed = ?duration. The warn logs in advance_keys_to omit structured validator_id/slot fields. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[sign_with_attestation_key / sign_with_proposal_key] --> B[advance_key]
C[advance_keys_to loop] --> B
B --> D{is_prepared_for slot?}
D -- yes --> E[return Ok]
D -- no --> F[log Advancing...]
F --> G[while !is_prepared_for]
G --> H[advance_preparation]
H --> I{interval changed?}
I -- no --> J[return Err SigningError]
I -- yes --> G
G -- prepared --> K[log Advanced + elapsed]
K --> L[return Ok]
J --> M{caller}
M -- sign_with_*_key --> N[propagate ? to caller]
M -- advance_keys_to --> O[inspect_err: warn log, discard]
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
crates/blockchain/src/key_manager.rs:55-60
The `warn!` calls inside `inspect_err` only capture the error string; `validator_id` and `slot` are embedded in the formatted message but are no longer emitted as structured tracing fields. Before this PR, the exhaustion warning included them as first-class fields (`warn!(validator_id, slot, "...")`), making it easy to filter logs by validator or slot. With `%err` alone, that filtering is lost.
```suggestion
let _ = advance_key(*validator_id, &mut key_pair.attestation_key, slot).inspect_err(
|err| warn!(validator_id, slot, %err, "Failed to advance attestation key preparation window"),
);
let _ = advance_key(*validator_id, &mut key_pair.proposal_key, slot).inspect_err(
|err| warn!(validator_id, slot, %err, "Failed to advance proposal key preparation window"),
);
```
Reviews (1): Last reviewed commit: "Cleanup: advance_key method in sign_with..." | Re-trigger Greptile
🗒️ Description / Motivation
This PR addresses review comments from #332.
sign_with_attestation_keyandsign_with_proposal_keyhad inline copies of the same advance loop that lives in theadvance_keyhelper. This PR routes them through the helper so there's a single implementation.Also switches the tracing field for elapsed durations from
elapsed_ms = ... as u64toelapsed = ?durationso theDuration'sDebugimpl is used.What Changed
crates/blockchain/src/key_manager.rsadvance_keynow returnsResult<(), KeyManagerError>and returns the sameSigningError("XMSS key exhausted...")the inline loops previously produced.sign_with_attestation_keyandsign_with_proposal_keyreplace their inline advance loops withadvance_key(...)?.advance_keys_toswallows the newResultviainspect_errso one exhausted key doesn't abort iteration; logs awarnper failure.elapsed_ms = ... as u64fields →elapsed = ?start.elapsed().Correctness / Behavior Guarantees
is_prepared_forcheck, sameadvance_preparationloop, same exhaustion detection, same returned error string."XMSS key exhausted...").validator_idandslotare still in the message.1.234s) instead of a raw millisecond count.Tests Added / Run
make fmtcleanmake lintcleanmake testpassesThe refactor is logic-preserving, so the existing
signature_spectestsandforkchoice_spectestscontinue to exercise the signing paths through the newadvance_keyindirection.Related Issues / PRs
✅ Verification Checklist
make fmtmake lintmake test