fix(minibf): Correctly handle drep_id and include nonce in parameters - #706
Conversation
WalkthroughAdds DRepState::new(drep_id) and uses it for on-demand DRep creation in roll handlers; passes an optional nonce from EpochState into epoch parameter models; refines DRep "active" computation in governance; consolidates a public import list formatting in sweep compute. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Delta as Roll Delta
participant Store as DRep Store
participant Model as DRepState
Note over Delta,Store: On apply/undo, ensure DRep exists
Delta->>Store: get(drep_id)
alt missing
Store->>Store: get_or_insert_with(|| DRepState::new(drep_id))
Store-->>Delta: &mut DRepState
else present
Store-->>Delta: &mut DRepState
end
Delta->>Model: mutate fields (initial_slot, voting_power, retired, last_active_slot)
Delta-->>Store: done
sequenceDiagram
autonumber
actor Client
participant API as /epochs/latest/parameters
participant State as StateStore
participant Epoch as EpochState
participant Builder as ParametersModelBuilder
participant Resp as EpochParamContent
Client->>API: GET latest parameters
API->>State: read_entity_typed<EpochState>(EPOCH_KEY_SET)
State-->>API: EpochState (may contain active nonce)
API->>Builder: build { nonce: Option<String> }
Builder->>Resp: IntoModel (nonce.unwrap_or_default())
API-->>Client: 200 OK (parameters with nonce)
sequenceDiagram
autonumber
actor Client
participant API as Governance Endpoint
participant Ctx as Context (pparams, chain state)
participant Builder as DrepModelBuilder
Client->>API: Request DRep model
API->>Ctx: fetch pparams, last_active_epoch, compute retiring_epoch
API->>Builder: into_model(...)
alt special-case drep_id
Builder-->>API: active = true
else computed
Builder-->>API: active = (last_active_epoch <= retiring_epoch)
end
API-->>Client: DRep model
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
crates/cardano/src/roll/dreps.rs (1)
118-121: Prefer expect(...) over unwrap() in undo path.Avoid silent panics; fail with context if invariants are broken.
Apply this diff:
- entity.voting_power = self.prev_voting_power.unwrap(); + entity.voting_power = self + .prev_voting_power + .expect("DRepUnRegistration.undo: prev_voting_power must be set by apply()");crates/cardano/src/sweep/compute.rs (1)
8-8: Remove unused import PoolState.Cleans a warning from CI.
Apply this diff:
- utils::epoch_first_slot, DRepState, EpochState, EraProtocol, Nonces, PParamsSet, PoolState + utils::epoch_first_slot, DRepState, EpochState, EraProtocol, Nonces, PParamsSet
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
crates/cardano/src/model.rs(1 hunks)crates/cardano/src/roll/dreps.rs(6 hunks)crates/cardano/src/sweep/compute.rs(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- crates/cardano/src/model.rs
🧰 Additional context used
🧬 Code graph analysis (1)
crates/cardano/src/sweep/compute.rs (1)
crates/cardano/src/utils.rs (1)
epoch_first_slot(27-29)
🪛 GitHub Check: Check Build
crates/cardano/src/roll/dreps.rs
[failure] 61-61:
no field drep_id on type &mut DRepRegistration
[failure] 73-73:
no field drep_id on type &DRepRegistration
[failure] 107-107:
no field drep_id on type &mut DRepUnRegistration
[failure] 118-118:
no field drep_id on type &DRepUnRegistration
[failure] 149-149:
no field drep_id on type &mut DRepActivity
[failure] 159-159:
no field drep_id on type &DRepActivity
crates/cardano/src/sweep/compute.rs
[warning] 8-8:
unused import: PoolState
🪛 GitHub Actions: CI
crates/cardano/src/roll/dreps.rs
[error] 61-61: no field drep_id on type &mut DRepRegistration
|
|
||
| fn apply(&mut self, entity: &mut Option<DRepState>) { | ||
| let entity = entity.get_or_insert_default(); | ||
| let entity = entity.get_or_insert_with(|| DRepState::new(self.drep_id.clone())); |
There was a problem hiding this comment.
🧩 Analysis chain
Fix: use drep_to_entity_key(..) instead of nonexistent self.drep_id (build is red).
These deltas don’t have a drep_id field. Use the computed key from the contained DRep. This also ensures DRepState::new receives the correct identifier.
Apply this diff:
@@
- let entity = entity.get_or_insert_with(|| DRepState::new(self.drep_id.clone()));
+ let entity = entity.get_or_insert_with(|| DRepState::new(drep_to_entity_key(self.drep.clone())));
@@
- let entity = entity.get_or_insert_with(|| DRepState::new(self.drep_id.clone()));
+ let entity = entity.get_or_insert_with(|| DRepState::new(drep_to_entity_key(self.drep.clone())));
@@
- let entity = entity.get_or_insert_with(|| DRepState::new(self.drep_id.clone()));
+ let entity = entity.get_or_insert_with(|| DRepState::new(drep_to_entity_key(self.drep.clone())));
@@
- let entity = entity.get_or_insert_with(|| DRepState::new(self.drep_id.clone()));
+ let entity = entity.get_or_insert_with(|| DRepState::new(drep_to_entity_key(self.drep.clone())));
@@
- let entity = entity.get_or_insert_with(|| DRepState::new(self.drep_id.clone()));
+ let entity = entity.get_or_insert_with(|| DRepState::new(drep_to_entity_key(self.drep.clone())));
@@
- let entity = entity.get_or_insert_with(|| DRepState::new(self.drep_id.clone()));
+ let entity = entity.get_or_insert_with(|| DRepState::new(drep_to_entity_key(self.drep.clone())));Run to confirm no remaining references to drep_id on these deltas:
Also applies to: 73-73, 107-107, 118-118, 149-149, 159-159
🏁 Script executed:
#!/bin/bash
rg -nP --type=rust -C2 '\bself\.drep_id\b' || true
rg -nP --type=rust 'DRepState::new\('Length of output: 4216
Fix: replace self.drep_id.clone() with drep_to_entity_key(self.drep.clone()) — build is red
Deltas don't have a drep_id field; use the computed key from the contained DRep so DRepState::new gets the correct identifier.
Apply this diff:
@@
- let entity = entity.get_or_insert_with(|| DRepState::new(self.drep_id.clone()));
+ let entity = entity.get_or_insert_with(|| DRepState::new(drep_to_entity_key(self.drep.clone())));
@@
- let entity = entity.get_or_insert_with(|| DRepState::new(self.drep_id.clone()));
+ let entity = entity.get_or_insert_with(|| DRepState::new(drep_to_entity_key(self.drep.clone())));
@@
- let entity = entity.get_or_insert_with(|| DRepState::new(self.drep_id.clone()));
+ let entity = entity.get_or_insert_with(|| DRepState::new(drep_to_entity_key(self.drep.clone())));
@@
- let entity = entity.get_or_insert_with(|| DRepState::new(self.drep_id.clone()));
+ let entity = entity.get_or_insert_with(|| DRepState::new(drep_to_entity_key(self.drep.clone())));
@@
- let entity = entity.get_or_insert_with(|| DRepState::new(self.drep_id.clone()));
+ let entity = entity.get_or_insert_with(|| DRepState::new(drep_to_entity_key(self.drep.clone())));
@@
- let entity = entity.get_or_insert_with(|| DRepState::new(self.drep_id.clone()));
+ let entity = entity.get_or_insert_with(|| DRepState::new(drep_to_entity_key(self.drep.clone())));Applies to: crates/cardano/src/roll/dreps.rs lines 61, 73, 107, 118, 149, 159.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| let entity = entity.get_or_insert_with(|| DRepState::new(self.drep_id.clone())); | |
| let entity = entity.get_or_insert_with(|| DRepState::new(drep_to_entity_key(self.drep.clone()))); | |
| let entity = entity.get_or_insert_with(|| DRepState::new(drep_to_entity_key(self.drep.clone()))); | |
| let entity = entity.get_or_insert_with(|| DRepState::new(drep_to_entity_key(self.drep.clone()))); | |
| let entity = entity.get_or_insert_with(|| DRepState::new(drep_to_entity_key(self.drep.clone()))); | |
| let entity = entity.get_or_insert_with(|| DRepState::new(drep_to_entity_key(self.drep.clone()))); | |
| let entity = entity.get_or_insert_with(|| DRepState::new(drep_to_entity_key(self.drep.clone()))); |
🧰 Tools
🪛 GitHub Check: Check Build
[failure] 61-61:
no field drep_id on type &mut DRepRegistration
🪛 GitHub Actions: CI
[error] 61-61: no field drep_id on type &mut DRepRegistration
🤖 Prompt for AI Agents
In crates/cardano/src/roll/dreps.rs around lines 61, 73, 107, 118, 149, and 159,
the code incorrectly references self.drep_id (which doesn't exist on Deltas);
replace those uses with drep_to_entity_key(self.drep.clone()) so DRepState::new
and any entity-key lookups receive the computed key from the contained DRep.
Update each occurrence to call drep_to_entity_key(self.drep.clone()) and ensure
the value passed is the entity key where previously self.drep_id.clone() was
used.
Summary by CodeRabbit
New Features
Bug Fixes