dig_epoch/types/verification.rs
1//! # `types::verification` — verification-related data types
2//!
3//! **Introduced by:** `STR-002` — Module hierarchy (SPEC §13).
4//!
5//! **Future owner:**
6//! [`TYP-006`](../../../docs/requirements/domains/epoch_types/specs/TYP-006.md)
7//! — verification-related data structures:
8//!
9//! - `EpochCheckpointData` with `hash()` and `test_coin_id()`
10//! - `EpochBlockLink`
11//!
12//! **Spec reference:** [`SPEC.md` §7](../../../docs/resources/SPEC.md) —
13//! verification.
14//!
15//! ## Relationship to `src/verification.rs`
16//!
17//! This module owns the **type surface** of verification. The **free
18//! functions** that compute verification artefacts (epoch block Merkle
19//! root, inclusion proofs, withdrawals Merkle-set root, checkpoint signing
20//! material) live in [`crate::verification`] per STR-002's Implementation
21//! Notes. Both modules must exist simultaneously with distinct
22//! responsibilities.
23//!
24//! ## Status at STR-002
25//!
26//! Empty aside from the [`STR_002_MODULE_PRESENT`] sentinel.
27
28/// Sentinel marker proving the module exists and is reachable at
29/// `dig_epoch::types::verification::STR_002_MODULE_PRESENT`.
30///
31/// Exercised by the STR-002 integration test — see
32/// [`tests/crate_structure/str_002_test.rs`](../../../tests/crate_structure/str_002_test.rs).
33#[doc(hidden)]
34pub const STR_002_MODULE_PRESENT: () = ();
35
36use chia_protocol::Bytes32;
37use chia_sha2::Sha256;
38use serde::{Deserialize, Serialize};
39
40use crate::error::EpochError;
41
42// -----------------------------------------------------------------------------
43// TYP-006 — EpochBlockLink
44// -----------------------------------------------------------------------------
45
46/// Parent-to-child relationship between consecutive blocks within an epoch.
47///
48/// Spec ref: SPEC §3.13 / TYP-006.
49#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct EpochBlockLink {
51 /// Hash of the parent block.
52 pub parent_hash: Bytes32,
53 /// Hash of the current block.
54 pub block_hash: Bytes32,
55}
56
57// -----------------------------------------------------------------------------
58// VER-004 — EpochCheckpointData
59// -----------------------------------------------------------------------------
60
61/// Minimum data needed to identify and verify an epoch checkpoint.
62///
63/// Binds `network_id` to the other fields to prevent cross-network replay.
64///
65/// Spec ref: SPEC §7.4 / VER-004.
66#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
67pub struct EpochCheckpointData {
68 /// Network identifier (prevents cross-network replay).
69 pub network_id: Bytes32,
70 /// Epoch number this checkpoint summarizes.
71 pub epoch: u64,
72 /// Ordered Merkle root over epoch block hashes (VER-001).
73 pub block_root: Bytes32,
74 /// Post-epoch L2 state root.
75 pub state_root: Bytes32,
76 /// Order-independent Merkle set root over epoch withdrawals (VER-003).
77 pub withdrawals_root: Bytes32,
78 /// Hash of the underlying [`dig_block::Checkpoint`] struct.
79 pub checkpoint_hash: Bytes32,
80}
81
82impl EpochCheckpointData {
83 /// SHA-256 over `network_id || epoch_le || block_root || state_root ||
84 /// withdrawals_root || checkpoint_hash`.
85 pub fn signing_digest(&self) -> Bytes32 {
86 let mut h = Sha256::new();
87 h.update(self.network_id.as_ref());
88 h.update(self.epoch.to_le_bytes());
89 h.update(self.block_root.as_ref());
90 h.update(self.state_root.as_ref());
91 h.update(self.withdrawals_root.as_ref());
92 h.update(self.checkpoint_hash.as_ref());
93 Bytes32::new(h.finalize())
94 }
95
96 /// Serializes with bincode. Infallible for well-formed structs.
97 pub fn to_bytes(&self) -> Vec<u8> {
98 bincode::serialize(self).expect("EpochCheckpointData serialization should never fail")
99 }
100
101 /// Deserializes from bincode bytes, returning `EpochError::InvalidData` on failure.
102 pub fn from_bytes(bytes: &[u8]) -> Result<Self, EpochError> {
103 bincode::deserialize(bytes).map_err(|e| EpochError::InvalidData(e.to_string()))
104 }
105}
106
107/// Validator-facing signing material: [`EpochCheckpointData`] plus the
108/// competition score and the exact bytes to sign.
109///
110/// Spec ref: SPEC §7.5 / VER-004.
111#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
112pub struct EpochCheckpointSignMaterial {
113 /// Core checkpoint data (network-bound).
114 pub checkpoint: EpochCheckpointData,
115 /// Competition score = `stake_percentage * block_count` (CKP-004).
116 pub score: u64,
117 /// BLS signing digest (hash of `checkpoint`).
118 pub signing_digest: Bytes32,
119}