Skip to main content

p3_challenger/fs/
error.rs

1//! Errors returned by the transcript machinery.
2
3use alloc::boxed::Box;
4
5use thiserror::Error;
6
7use crate::fs::pattern::Interaction;
8
9/// Failures that can arise while validating a pattern or reading a proof.
10///
11/// Every variant is reachable.
12///
13/// Divergence between the recorded pattern and the code replaying it is a
14/// programming bug, not malformed input, so it panics with a diff instead of
15/// landing here.
16#[derive(Clone, Debug, Error, PartialEq, Eq)]
17pub enum TranscriptError {
18    /// An end marker was found with no matching opener in the sequence.
19    #[error(transparent)]
20    MissingBegin(Box<MissingBeginInfo>),
21
22    /// A nested step uses a kind incompatible with the surrounding sub-protocol.
23    #[error(transparent)]
24    InvalidKind(Box<InvalidKindInfo>),
25
26    /// A closer does not match the most recent opener.
27    #[error(transparent)]
28    MismatchedBeginEnd(Box<MismatchedBeginEndInfo>),
29
30    /// An opener was never closed before the sequence ended.
31    #[error(transparent)]
32    MissingEnd(Box<MissingEndInfo>),
33
34    /// Verifier-side parsing of the prover's serialized output failed.
35    #[error("bad proof shape: {reason}")]
36    BadProofShape {
37        /// Short reason describing the parse failure.
38        reason: &'static str,
39    },
40}
41
42/// Payload describing an end marker that has no matching opener.
43#[derive(Clone, Debug, Error, PartialEq, Eq)]
44#[error("missing begin for {end} at position {position}")]
45pub struct MissingBeginInfo {
46    /// Index of the orphan end-of-block interaction inside the recorded sequence.
47    pub position: usize,
48    /// The interaction that lacked a matching opener.
49    pub end: Interaction,
50}
51
52/// Payload describing a nested step whose kind is incompatible with its container.
53///
54/// Raised for a leaf and for a nested opener alike.
55#[derive(Clone, Debug, Error, PartialEq, Eq)]
56#[error(
57    "invalid kind {interaction} at {interaction_position} for sub-protocol {begin} \
58     opened at {begin_position}"
59)]
60pub struct InvalidKindInfo {
61    /// Index of the surrounding sub-protocol opener inside the recorded sequence.
62    pub begin_position: usize,
63    /// The sub-protocol opener whose declared kind is being violated.
64    pub begin: Interaction,
65    /// Index of the offending nested interaction.
66    pub interaction_position: usize,
67    /// The offending nested interaction: an atomic step or a nested opener.
68    pub interaction: Interaction,
69}
70
71/// Payload describing a closer that does not match its opener.
72#[derive(Clone, Debug, Error, PartialEq, Eq)]
73#[error("mismatched begin {begin} at {begin_position} versus end {end} at {end_position}")]
74pub struct MismatchedBeginEndInfo {
75    /// Index of the opener inside the recorded sequence.
76    pub begin_position: usize,
77    /// The opener that this closer was expected to match.
78    pub begin: Interaction,
79    /// Index of the closer inside the recorded sequence.
80    pub end_position: usize,
81    /// The closer that failed to match.
82    pub end: Interaction,
83}
84
85/// Payload describing a sub-protocol that was opened but never closed.
86#[derive(Clone, Debug, Error, PartialEq, Eq)]
87#[error("missing end for {begin} opened at position {position}")]
88pub struct MissingEndInfo {
89    /// Index of the opener inside the recorded sequence.
90    pub position: usize,
91    /// The opener that was left unclosed.
92    pub begin: Interaction,
93}