rialo-types 0.4.1

Rialo Types
Documentation
// Copyright (c) Subzero Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

//! Wire type for submitting a snapshot attestation to the network.
//!
//! A [`SnapshotAttestationSubmission`] bundles a [`SnapshotRecord`] with a
//! single validator's [`SnapshotAttestation`] (signature over that record).
//! The blockpool validates digest consistency on receipt before forwarding the
//! attestation to the snapshot-attestation tracker for quorum accumulation.

use serde::{Deserialize, Serialize};
use thiserror::Error;

use super::record::{SnapshotAttestation, SnapshotRecord};

/// Errors from [`SnapshotAttestationSubmission::validate_digest_consistency`].
#[derive(Debug, Error, Clone, PartialEq, Eq)]
pub enum SnapshotAttestationSubmissionError {
    #[error("snapshot_attestation.record_digest does not match snapshot_record.record_digest()")]
    DigestMismatch,
}

/// Bundles a [`SnapshotRecord`] with its [`SnapshotAttestation`](super::record::SnapshotAttestation) for consensus submission.
///
/// Submitted as `AdminTransaction::SnapshotAttestationSubmission` through the mempool.
/// The record is included so that receiving validators can independently verify
/// the attestation by recomputing the record digest.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct SnapshotAttestationSubmission {
    /// The snapshot record being attested.
    snapshot_record: SnapshotRecord,

    /// The validator's signed attestation over the record digest.
    snapshot_attestation: SnapshotAttestation,
}

impl SnapshotAttestationSubmission {
    pub fn new(snapshot_record: SnapshotRecord, snapshot_attestation: SnapshotAttestation) -> Self {
        Self {
            snapshot_record,
            snapshot_attestation,
        }
    }

    pub fn snapshot_record(&self) -> &SnapshotRecord {
        &self.snapshot_record
    }

    pub fn snapshot_attestation(&self) -> &SnapshotAttestation {
        &self.snapshot_attestation
    }

    /// Validates that the attestation's record_digest matches the record.
    ///
    /// Call this at trust boundaries (deserialization, RPC ingress) before
    /// further processing.
    pub fn validate_digest_consistency(&self) -> Result<(), SnapshotAttestationSubmissionError> {
        if *self.snapshot_attestation.record_digest() == self.snapshot_record.record_digest() {
            Ok(())
        } else {
            Err(SnapshotAttestationSubmissionError::DigestMismatch)
        }
    }
}