Skip to main content

zakura_network/zakura/header_sync/
error.rs

1use super::*;
2
3/// Errors that prevent the header-sync reactor from starting.
4#[derive(Debug, Error)]
5pub enum HeaderSyncStartError {
6    /// The configured anchor is neither genesis nor a hash-matching checkpoint.
7    #[error("invalid Zakura header-sync anchor at height {anchor:?}")]
8    InvalidAnchor {
9        /// Rejected anchor.
10        anchor: (block::Height, block::Hash),
11    },
12
13    /// The configured anchor is ahead of the durable verified body/history-tree base.
14    #[error(
15        "Zakura header-sync anchor height {anchor_height:?} is above the verified block tip \
16         {verified_block_tip:?}"
17    )]
18    AnchorAboveVerifiedBlockTip {
19        /// Rejected anchor height.
20        anchor_height: block::Height,
21        /// Durable verified body/history-tree base.
22        verified_block_tip: block::Height,
23    },
24
25    /// Only one anchor field was configured.
26    #[error("Zakura header-sync anchor_height and anchor_hash must be configured together")]
27    IncompleteAnchor,
28}
29
30/// Structured wire and stateless-validation errors for versioned header sync.
31#[derive(Debug, Error)]
32pub enum HeaderSyncWireError {
33    /// A payload or peer-controlled count exceeded its cap.
34    #[error("Zakura header-sync payload length {actual} exceeds cap {max}")]
35    OversizedPayload {
36        /// Actual payload length.
37        actual: usize,
38        /// Maximum allowed payload length.
39        max: usize,
40    },
41
42    /// A decoded header count exceeded its contract.
43    #[error("Zakura header-sync header count {actual} exceeds cap {max}")]
44    HeaderCountLimit {
45        /// Actual header count.
46        actual: usize,
47        /// Maximum allowed header count.
48        max: usize,
49    },
50
51    /// A locally constructed `Headers` message had a different number of size hints.
52    #[error("Zakura header-sync Headers body-size count {body_sizes} does not match header count {headers}")]
53    BodySizeCountMismatch {
54        /// Header count.
55        headers: usize,
56        /// Body-size hint count.
57        body_sizes: usize,
58    },
59
60    /// A locally constructed or inbound `Headers` message did not carry exactly one root per header.
61    #[error("Zakura header-sync Headers tree-aux root count {roots} does not match header count {headers}")]
62    TreeAuxRootCountMismatch {
63        /// Header count.
64        headers: usize,
65        /// Tree-aux root count.
66        roots: usize,
67    },
68
69    /// An inbound `Headers` response carried a root for the wrong height.
70    #[error(
71        "Zakura header-sync Headers tree-aux root height {root_height:?} does not match \
72         expected height {expected_height:?} at offset {offset} \
73         (first={first_root_height:?}, last={last_root_height:?})"
74    )]
75    TreeAuxRootHeightMismatch {
76        /// Zero-based root offset within the response.
77        offset: usize,
78        /// Expected root height.
79        expected_height: block::Height,
80        /// Actual root height.
81        root_height: block::Height,
82        /// First encoded root height.
83        first_root_height: block::Height,
84        /// Last encoded root height.
85        last_root_height: block::Height,
86    },
87
88    /// A boolean marker field used a value other than 0 or 1.
89    #[error("Zakura header-sync {field} marker has invalid value {value}")]
90    InvalidBoolMarker {
91        /// Marker field name.
92        field: &'static str,
93        /// Invalid marker value.
94        value: u8,
95    },
96
97    /// A peer returned tree-aux roots for a request that opted out.
98    #[error("Zakura header-sync Headers included tree-aux roots for an opt-out request")]
99    UnrequestedTreeAuxRoots,
100
101    /// An inbound `Headers` response did not match an in-flight request.
102    #[error("unsolicited Zakura header-sync Headers response")]
103    UnsolicitedHeaders,
104
105    /// A request-id capable header-sync message was missing its request ID.
106    #[error("Zakura header-sync v7 {message} message is missing a request ID")]
107    MissingRequestId {
108        /// Message that required the ID.
109        message: &'static str,
110    },
111
112    /// A `GetHeaders` request asked for zero headers.
113    #[error("Zakura header-sync GetHeaders count must be non-zero")]
114    ZeroHeaderRequestCount,
115
116    /// A height exceeded Zebra's supported height range.
117    #[error("Zakura header-sync height {0} exceeds supported range")]
118    HeightOutOfRange(u32),
119
120    /// A payload used an unknown header-sync message discriminator.
121    #[error("unknown Zakura header-sync message type {0}")]
122    UnknownMessageType(u8),
123
124    /// A frame used a message type that does not fit header sync's u8 discriminator.
125    #[error("unknown Zakura header-sync frame message type {0}")]
126    UnknownFrameMessageType(u16),
127
128    /// Frame flags are reserved in header sync.
129    #[error("unsupported Zakura header-sync frame flags {0}")]
130    UnsupportedFlags(u16),
131
132    /// Frame and payload message types disagreed.
133    #[error("Zakura header-sync frame type {frame} disagrees with payload type {payload}")]
134    MismatchedFrameMessageType {
135        /// Outer frame message type.
136        frame: u16,
137        /// Inner payload message type.
138        payload: u8,
139    },
140
141    /// A decoded payload had trailing bytes.
142    #[error("trailing bytes in Zakura header-sync payload")]
143    TrailingBytes,
144
145    /// Adjacent headers did not hash-link.
146    #[error("non-contiguous Zakura header-sync header run")]
147    NonContiguousHeaders,
148
149    /// The first header in a range did not link to its anchor.
150    #[error("first Zakura header-sync range header does not link to anchor")]
151    FirstHeaderDoesNotLink,
152
153    /// Equihash solution size did not match the active network.
154    #[error("Zakura header-sync Equihash solution size does not match the active network")]
155    WrongEquihashSolutionSize,
156
157    /// The compact difficulty threshold did not expand to a valid target.
158    #[error("invalid Zakura header-sync compact difficulty threshold")]
159    InvalidDifficultyThreshold,
160
161    /// The header hash failed the context-free difficulty filter.
162    #[error("Zakura header-sync hash {hash:?} exceeds difficulty threshold {threshold:?}")]
163    DifficultyFilter {
164        /// Header hash.
165        hash: block::Hash,
166        /// Expanded threshold from the header.
167        threshold: ExpandedDifficulty,
168    },
169
170    /// A numeric conversion failed while handling bounded data.
171    #[error("numeric overflow while encoding Zakura header-sync {0}")]
172    NumericOverflow(&'static str),
173
174    /// An I/O error while encoding or decoding.
175    #[error("Zakura header-sync wire I/O error: {0}")]
176    Io(#[from] io::Error),
177
178    /// Zcash serialization failed.
179    #[error("Zakura header-sync Zcash serialization error: {0}")]
180    Serialization(#[from] SerializationError),
181
182    /// Header time was too far in the future.
183    #[error(transparent)]
184    Time(#[from] BlockTimeError),
185
186    /// Equihash verification failed.
187    #[error(transparent)]
188    Equihash(#[from] equihash::Error),
189
190    /// The blocking validation task failed.
191    #[error("Zakura header-sync blocking validation task failed: {0}")]
192    BlockingTask(#[from] JoinError),
193}