Skip to content

fix(minibf): Correctly handle drep_id and include nonce in parameters - #706

Merged
scarmuega merged 2 commits into
mainfrom
fix/minor-minibf-fixes
Sep 21, 2025
Merged

fix(minibf): Correctly handle drep_id and include nonce in parameters#706
scarmuega merged 2 commits into
mainfrom
fix/minor-minibf-fixes

Conversation

@gonzalezzfelipe

@gonzalezzfelipe gonzalezzfelipe commented Sep 20, 2025

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Latest parameters responses now include a nonce when available; by-number parameter responses omit it.
  • Bug Fixes

    • DRep “active” status is computed more accurately using inactivity periods and special-case handling, improving governance views.
    • DRep state is now initialized consistently when missing, reducing edge-case discrepancies in displayed DRep information.

@coderabbitai

coderabbitai Bot commented Sep 20, 2025

Copy link
Copy Markdown

Walkthrough

Adds 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

Cohort / File(s) Summary
DRepState constructor
crates/cardano/src/model.rs
Added inherent constructor pub fn new(drep_id: Vec<u8>) -> Self that initializes drep_id, initial_slot: None, voting_power: 0, last_active_slot: None, and retired: false.
DRep state initialization in roll handlers
crates/cardano/src/roll/dreps.rs
Replaced get_or_insert_default() with `get_or_insert_with(
Sweep import formatting
crates/cardano/src/sweep/compute.rs
Consolidated the public import list onto a single line (no semantic change to imported identifiers).
Epoch parameters: nonce plumbing
crates/minibf/src/routes/epochs/mapping.rs, crates/minibf/src/routes/epochs/mod.rs
Added pub nonce: Option<String> to ParametersModelBuilder<'a>; latest parameters endpoint reads EpochState from StateStore, extracts an active nonce (as Option<String>) and passes it to builder; by-number path passes None.
Governance DRep active computation
crates/minibf/src/routes/governance.rs
Reworked calculation of the active flag: preserves special-case drep_id handling, otherwise computes last_active_epoch and retiring_epoch (using pparams.drep_inactivity_period) and sets active based on their comparison; rest of model fields preserved.

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
Loading
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)
Loading
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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • scarmuega

Poem

I nibble code between each hop,
A nonce now joins the epoch's crop.
Dreps awaken by their name,
Newborn states avoiding shame.
I thump for bugs and then I stop—🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title accurately and concisely describes the two primary changes in the changeset: correcting drep_id handling (new DRepState::new and updated get_or_insert_with usage) and including nonce in minibf parameters. It is specific, relevant to the files changed, and understandable at a glance.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/minor-minibf-fixes

Comment @coderabbitai help to get the list of available commands and usage tips.

@scarmuega
scarmuega merged commit 73016ea into main Sep 21, 2025
7 of 9 checks passed
@scarmuega
scarmuega deleted the fix/minor-minibf-fixes branch September 21, 2025 17:09

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between cf50661 and 7df7964.

📒 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()));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

🧩 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.

Suggested change
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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants