Skip to content

chore: Fix drep handling - #703

Merged
scarmuega merged 1 commit into
mainfrom
chore/minibf-drepstate
Sep 19, 2025
Merged

chore: Fix drep handling#703
scarmuega merged 1 commit into
mainfrom
chore/minibf-drepstate

Conversation

@gonzalezzfelipe

@gonzalezzfelipe gonzalezzfelipe commented Sep 19, 2025

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features
    • Added tracking of DRep activity, recording the last active slot for each DRep to improve governance visibility.
  • Improvements
    • Standardized DRep identification using a stable DRep ID for more consistent registration and unregistration handling.
    • Streamlined certificate processing to automatically record DRep activity on relevant events.
  • Refactor
    • Simplified internal keying and storage mechanisms for DReps, improving data consistency and paving the way for better performance.

@coderabbitai

coderabbitai Bot commented Sep 19, 2025

Copy link
Copy Markdown

Walkthrough

Adds DRepActivity as a new Cardano delta and wires it into CardanoDelta. Refactors DRep identity to use explicit drep_id (Vec) instead of StakeCredential, updates registration/unregistration deltas, keying, and BlockVisitor to emit DRepActivity and appropriate reg/unreg deltas derived from certificates.

Changes

Cohort / File(s) Summary
Delta integration
crates/cardano/src/model.rs
Adds CardanoDelta::DRepActivity(DRepActivity); implements From via delta_from!; extends key/apply/undo dispatch to handle DRepActivity by delegating to its methods.
DRep identity refactor & activity tracking
crates/cardano/src/roll/dreps.rs
Switches DRep identity to drep_id: Vec; adds helper mappings (cred_to_id, drep_to_id, cert_to_id) and prefixes; introduces DRepActivity delta tracking last_active_slot with undo; updates DRepRegistration/DRepUnRegistration structs, constructors, and key() to use drep_id; revises BlockVisitor::visit_cert to derive drep_id from cert, emit DRepActivity, and then emit reg/unreg deltas; removes minicbor-based keying.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Chain
  participant Visitor as BlockVisitor
  participant Cert as Certificate
  participant Mapper as cert_to_id / drep_to_id
  participant Store as Delta System

  Chain->>Visitor: visit_cert(cert, slot)
  Visitor->>Mapper: derive drep_id from cert
  Mapper-->>Visitor: drep_id (Vec<u8>)
  Note over Visitor,Store: New/changed flow: always emit activity
  Visitor->>Store: emit DRepActivity{ drep_id, slot }
  alt RegDRepCert
    Visitor->>Store: emit DRepRegistration{ drep_id, slot, deposit, anchor }
  else UnRegDRepCert
    Visitor->>Store: emit DRepUnRegistration{ drep_id, deposit }
  else Other cert
    Note over Visitor: No reg/unreg delta
  end
  Store->>Store: apply deltas (update last_active_slot, reg/unreg states)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

I thump my paws: new IDs bloom,
DReps stand tall with bytes that zoom.
Activity ticks with every slot,
Registrations tie the knot.
Unregs hop off, quiet and spry—
Deltas dance as blocks roll by.
Carrots logged; consistency high.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 "chore: Fix drep handling" is directly related to the changes in this PR (DRep identity refactor and the new DRepActivity delta) so it correctly indicates the affected area, but it is somewhat broad and could be more specific about the key changes to help future readers.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/minibf-drepstate

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

@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 (1)
crates/cardano/src/roll/dreps.rs (1)

35-48: Consider adding documentation for the cert_to_id function.

This function is central to DRep identity resolution but lacks documentation explaining its purpose and the None return cases.

+/// Extracts the DRep ID from a certificate if it contains DRep-related information.
+/// Returns None for certificates that don't involve DReps.
 fn cert_to_id(cert: &MultiEraCert) -> Option<Vec<u8>> {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3bb0468 and bd9eeca.

📒 Files selected for processing (2)
  • crates/cardano/src/model.rs (6 hunks)
  • crates/cardano/src/roll/dreps.rs (7 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Check Build
🔇 Additional comments (5)
crates/cardano/src/model.rs (1)

35-35: LGTM! DRepActivity integration looks complete.

The DRepActivity delta has been properly integrated into the CardanoDelta enum with all the necessary boilerplate:

  • Import added at line 35
  • Enum variant added at line 961
  • From trait implementation via delta_from! macro at line 1013
  • Key, apply, and undo delegation properly handled in lines 1034, 1056, 1077

Also applies to: 961-961, 1013-1013, 1034-1034, 1056-1056, 1077-1077

crates/cardano/src/roll/dreps.rs (4)

144-183: LGTM! Clean implementation of DRepActivity delta.

The DRepActivity struct properly tracks last active slot changes with appropriate undo capability. The implementation follows the same pattern as other deltas in the codebase.


195-213: Efficient activity tracking for all DRep-related certificates.

Good design choice to emit DRepActivity for all certificates that reference a DRep, ensuring activity is tracked even for non-registration operations like voting delegations.


15-17: Reserve a distinct prefix for invented DRep IDs — avoid vec![0]/vec![1]

crates/cardano/src/roll/dreps.rs maps Abstain => vec![0] and NoConfidence => vec![1] (see test-vectors: crates/test-vectors/src/build.rs:220–221). Verify that real DRep IDs can never be the single bytes 0x00/0x01 (i.e., are always encoded with DREP_KEY_PREFIX/DREP_SCRIPT_PREFIX + key bytes); if not, switch these to a reserved prefix/marker (e.g., 0xFF or DREP_RESERVED_PREFIX) to prevent collisions.


52-52: Verify migration/compatibility for drep_id key change

  • Breaking change: replacing credential-based keys with direct drep_id (drep_id: Vec) will affect persisted data/serialization.
  • Repo scan results: no migration scripts or DRepState (de)serialization impls were found; matches for "migration|upgrade|backward" were in src/serve/o7s_unix/chainsync.rs, src/relay/chainsync.rs, src/bin/dolos/init.rs, crates/test-vectors/src/epochs.sql, crates/minibf/src/routes/health.rs (appear unrelated). ast-grep found no impl for DRepState; no tests for DRepState/DRepRegistration surfaced.
  • Action required: add a migration/upgrade path or compatibility layer, update serialization/deserialization and tests, or explicitly confirm and document that no persisted data depends on the previous credential-based key format.

Affected: crates/cardano/src/roll/dreps.rs — drep_id: Vec (lines ~52, 62-64, 77).

Comment on lines +168 to +176
fn apply(&mut self, entity: &mut Option<DRepState>) {
let entity = entity.get_or_insert_default();

// save undo info
self.previous_last_active_slot = entity.last_active_slot;

// apply changes
entity.last_active_slot = Some(self.slot);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

🧩 Analysis chain

Consider initializing drep_id in the entity.

When applying DRepActivity, the entity is created with default values if it doesn't exist. However, the drep_id field in the entity is not being set from the delta's drep_id.


🏁 Script executed:

#!/bin/bash
# Check if drep_id is set elsewhere when creating DRepState
echo "Checking where drep_id is initialized in DRepState..."
ast-grep --pattern 'impl $_ for DRepRegistration {
  $$$
  fn apply($$$) {
    $$$
  }
  $$$
}'

# Check the DRepState structure definition
echo -e "\nChecking DRepState structure..."
rg -A 10 "struct DRepState" --type rust

Length of output: 2922


Initialize entity.drep_id when creating a DRepState

Both DRepRegistration::apply (crates/cardano/src/roll/dreps.rs:76–90) and DRepActivity::apply (crates/cardano/src/roll/dreps.rs:168–176) call entity.get_or_insert_default() but never set entity.drep_id; DRepState defines pub drep_id: Vec in crates/cardano/src/model.rs — set it when inserting the default (e.g. entity.drep_id = self.drep_id.clone()).

🤖 Prompt for AI Agents
In crates/cardano/src/roll/dreps.rs around lines 76–90 and 168–176, both
DRepRegistration::apply and DRepActivity::apply call
entity.get_or_insert_default() but never populate the DRepState.drep_id field;
update each apply to set entity.drep_id = self.drep_id.clone() immediately after
inserting the default (i.e., when get_or_insert_default() returns the newly
inserted state) so the drep_id is initialized correctly on creation.

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