celestia_types/
fraud_proof.rs1use std::fmt;
6
7use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
8use tendermint_proto::Protobuf;
9
10pub use crate::byzantine::BadEncodingFraudProof;
11use crate::hash::Hash;
12use crate::{Error, ExtendedHeader, Result};
13
14pub trait FraudProof {
16 const TYPE: &'static str;
18
19 fn header_hash(&self) -> Hash;
21
22 fn height(&self) -> u64;
24
25 fn validate(&self, header: &ExtendedHeader) -> Result<()>;
31}
32
33#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
38pub struct RawFraudProof {
39 proof_type: String,
40 #[serde(with = "tendermint_proto::serializers::bytes::base64string")]
41 data: Vec<u8>,
42}
43
44#[derive(Clone, Debug, PartialEq, Deserialize)]
46#[serde(try_from = "RawFraudProof", into = "RawFraudProof")]
47#[non_exhaustive]
48pub enum Proof {
49 BadEncoding(BadEncodingFraudProof),
53}
54
55impl Proof {
56 pub fn proof_type(&self) -> ProofType {
58 match self {
59 Proof::BadEncoding(_) => ProofType::BadEncoding,
60 }
61 }
62}
63
64#[derive(Clone, Copy, Debug)]
66pub enum ProofType {
67 BadEncoding,
69}
70
71impl ProofType {
72 pub fn to_str(&self) -> &'static str {
74 match self {
75 ProofType::BadEncoding => BadEncodingFraudProof::TYPE,
76 }
77 }
78}
79
80impl Serialize for ProofType {
81 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
82 where
83 S: Serializer,
84 {
85 self.to_str().serialize(serializer)
86 }
87}
88
89impl<'de> Deserialize<'de> for ProofType {
90 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
91 where
92 D: Deserializer<'de>,
93 {
94 struct ProofTypeVisitor;
95
96 impl<'de> de::Visitor<'de> for ProofTypeVisitor {
97 type Value = ProofType;
98
99 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
100 formatter.write_str("a string representing proof type: 'badencoding'")
101 }
102
103 fn visit_str<E>(self, value: &str) -> Result<ProofType, E>
104 where
105 E: de::Error,
106 {
107 match value {
108 BadEncodingFraudProof::TYPE => Ok(ProofType::BadEncoding),
109 _ => Err(E::invalid_value(de::Unexpected::Str(value), &self)),
110 }
111 }
112 }
113
114 deserializer.deserialize_str(ProofTypeVisitor)
115 }
116}
117
118impl TryFrom<RawFraudProof> for Proof {
119 type Error = Error;
120
121 fn try_from(value: RawFraudProof) -> Result<Self, Self::Error> {
122 match value.proof_type.as_str() {
123 BadEncodingFraudProof::TYPE => {
124 let befp = BadEncodingFraudProof::decode_vec(&value.data)?;
125 Ok(Proof::BadEncoding(befp))
126 }
127 _ => Err(Error::UnsupportedFraudProofType(value.proof_type)),
128 }
129 }
130}
131
132impl From<&Proof> for RawFraudProof {
133 fn from(value: &Proof) -> Self {
134 match value {
135 Proof::BadEncoding(befp) => RawFraudProof {
136 proof_type: BadEncodingFraudProof::TYPE.to_owned(),
137 data: befp.clone().encode_vec(),
138 },
139 }
140 }
141}
142
143impl Serialize for Proof {
144 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
145 where
146 S: Serializer,
147 {
148 let raw: RawFraudProof = self.into();
149 raw.serialize(serializer)
150 }
151}
152
153#[cfg(test)]
154mod tests {
155 use crate::consts::appconsts::AppVersion;
156 use crate::test_utils::{ExtendedHeaderGenerator, corrupt_eds, generate_dummy_eds};
157
158 use super::*;
159
160 #[test]
161 fn befp_serde() {
162 let mut generator = ExtendedHeaderGenerator::new();
163 let mut eds = generate_dummy_eds(8, AppVersion::V2);
164 let (_, proof) = corrupt_eds(&mut generator, &mut eds);
165
166 let proof = Proof::BadEncoding(proof);
167
168 let serialized = serde_json::to_string(&proof).unwrap();
169 let deserialized: Proof = serde_json::from_str(&serialized).unwrap();
170
171 assert_eq!(deserialized, proof);
172 }
173}