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