Skip to content

Conversation

@shd
Copy link
Collaborator

@shd shd commented Dec 5, 2025

Description

  • Governance ledger check infrastructure implemented;
  • All errors! made validation errors;
  • Some additional checks added;
  • Added utils.rs with helper macros/functions for validator developer

Related Issue(s)

Fixes #[#404] (#404)

How was this tested?

  • No error!'s in files (except I/O error! on non-validation path)
  • Manual tests with project (stops in case of errors with consensus added, validates without errors)

Checklist

    • My code builds and passes local tests
  • I added/updated tests for my changes, where applicable
  • I updated documentation (if applicable)
    • CI is green for this PR

Impact / Side effects

Reviewer notes / Areas to focus

Added common/utils.rs for validation help.

@shd shd requested a review from sandtreader December 5, 2025 14:55
Copy link
Collaborator

@sandtreader sandtreader left a comment

Choose a reason for hiding this comment

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

This is a great pattern to do this error promotion across the board - thanks!

Some comments on naming - nothing substantive so go ahead and merge if it's holding anything up.

}

pub fn conway() -> Self {
Self { major: 9, minor: 0 }
Copy link
Collaborator

Choose a reason for hiding this comment

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

This could be confusing - Conway is (at least) protocol versions 9 (Chang) and 10 (Plomin) and could well include 11 soon. It would be better to call this chang() I think.

macro_rules! declare_cardano_reader {
($name:ident, $msg_constructor:ident, $msg_type:ty) => {
async fn $name(s: &mut Box<dyn Subscription<Message>>) -> Result<(BlockInfo, $msg_type)> {
info!("Waiting in topic {}", stringify!($msg_constructor));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Unlikely we'd want this in production :-)

Copy link
Collaborator

Choose a reason for hiding this comment

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

There's a standing joke about files called 'utils' ;-) The validation bits could move to validation.rs, maybe the remaining macro in messaging.rs or some such?

/// See Haskell Node, Cardano.Ledger.BaseTypes: Cardano/Src/Ledger/BaseTypes.hs
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
pub enum MismatchRelation {
RelEq,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Style point - is the Rel prefix needed given it's always qualified with MismatchRelation anyway?

/// See Haskell Node, Cardano.Ledger.BaseTypes: Cardano/Src/Ledger/BaseTypes.hs
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
pub enum Mismatch<T: Debug + Display> {
Supplied(T, MismatchRelation),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why does Supplied have a relation too? I'm assuming we're representing "we got X but expected REL Y".

Also confused why it's an enum - maybe naming is strange? Let's not import Haskell weirdness if we can avoid it!

try_join_all(validator_topics.iter().map(|topic| context.subscribe(topic))).await?;

// True if we expect validation to be performed by the nodes
let do_validation = !validator_subscriptions.is_empty();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice!

let prev = self.proposals.insert(proc.gov_action_id.clone(), (epoch, proc.clone()));
if let Some(prev) = prev {
return Err(anyhow!(
outcomes.push_anyhow(anyhow!(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there no specific governance error we could generate here? It seems like you have done in most cases.

let (blk_p, params) = Self::read_parameters(&mut protocol_s).await?;
if blk_g != blk_p {
error!(
outcomes.push_anyhow(anyhow!(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Interesting... I hadn't thought of promoting this kind of internal error, but it is the safe thing to do - nothing can be valid if we're screwed up internally.

(Conway "GOV" rule)

```
data ConwayGovPredFailure era
Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like there are a lot more errors defined here than we can currently generate - need a ticket to add checks on these (in time).

Copy link
Collaborator

@golddydev golddydev left a comment

Choose a reason for hiding this comment

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

ValidationOutcome approach is nice 👍🏼
Willl use that with UTxO validation

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.

4 participants