dubp_documents/certification/
v10.rs1use crate::*;
19
20#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
21pub struct CompactCertificationDocumentV10 {
23 pub issuer: ed25519::PublicKey,
25 pub target: ed25519::PublicKey,
27 pub block_number: BlockNumber,
29 pub signature: ed25519::Signature,
31}
32
33impl CompactTextDocument for CompactCertificationDocumentV10 {
34 fn as_compact_text(&self) -> String {
35 format!(
36 "{issuer}:{target}:{block_number}:{signature}",
37 issuer = self.issuer,
38 target = self.target,
39 block_number = self.block_number.0,
40 signature = self.signature,
41 )
42 }
43}
44
45#[derive(Clone, Debug, Deserialize, Hash, Serialize, PartialEq, Eq)]
46pub struct CompactCertificationDocumentV10Stringified {
48 pub issuer: String,
50 pub target: String,
52 pub block_number: u64,
54 pub signature: String,
56}
57
58impl ToStringObject for CompactCertificationDocumentV10 {
59 type StringObject = CompactCertificationDocumentV10Stringified;
60 fn to_string_object(&self) -> CompactCertificationDocumentV10Stringified {
62 CompactCertificationDocumentV10Stringified {
63 issuer: format!("{}", self.issuer),
64 target: format!("{}", self.target),
65 block_number: u64::from(self.block_number.0),
66 signature: format!("{}", self.signature),
67 }
68 }
69}
70
71#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
75pub struct CertificationDocumentV10 {
76 text: String,
80
81 currency: String,
83 issuer: ed25519::PublicKey,
85 target: ed25519::PublicKey,
87 identity_username: String,
89 identity_blockstamp: Blockstamp,
91 identity_sig: ed25519::Signature,
93 blockstamp: Blockstamp,
95 signature: ed25519::Signature,
97}
98
99#[derive(Clone, Debug, Deserialize, Hash, Serialize, PartialEq, Eq)]
100pub struct CertificationDocumentV10Stringified {
102 currency: String,
104 issuer: String,
106 target: String,
108 identity_username: String,
110 identity_blockstamp: String,
112 identity_sig: String,
114 blockstamp: String,
116 signature: String,
118}
119
120impl ToStringObject for CertificationDocumentV10 {
121 type StringObject = CertificationDocumentV10Stringified;
122 fn to_string_object(&self) -> CertificationDocumentV10Stringified {
124 CertificationDocumentV10Stringified {
125 currency: self.currency.clone(),
126 issuer: self.issuer.to_base58(),
127 target: format!("{}", self.target),
128 identity_username: self.identity_username.clone(),
129 identity_blockstamp: format!("{}", self.identity_blockstamp),
130 blockstamp: format!("{}", self.blockstamp),
131 identity_sig: format!("{}", self.identity_sig),
132 signature: format!("{}", self.signature),
133 }
134 }
135}
136
137impl CertificationDocumentV10 {
138 pub fn identity_username(&self) -> &str {
140 &self.identity_username
141 }
142
143 pub fn source(&self) -> &ed25519::PublicKey {
145 &self.issuer
146 }
147
148 pub fn target(&self) -> &ed25519::PublicKey {
150 &self.target
151 }
152}
153
154impl Document for CertificationDocumentV10 {
155 type PublicKey = ed25519::PublicKey;
156
157 fn version(&self) -> usize {
158 10
159 }
160
161 fn currency(&self) -> &str {
162 &self.currency
163 }
164
165 fn blockstamp(&self) -> Blockstamp {
166 self.blockstamp
167 }
168
169 fn issuers(&self) -> SmallVec<[Self::PublicKey; 1]> {
170 svec![self.issuer]
171 }
172
173 fn signatures(&self) -> SmallVec<[<Self::PublicKey as PublicKey>::Signature; 1]> {
174 svec![self.signature]
175 }
176
177 fn as_bytes(&self) -> BeefCow<[u8]> {
178 BeefCow::borrowed(self.as_text().as_bytes())
179 }
180}
181
182impl TextDocument for CertificationDocumentV10 {
183 type CompactTextDocument_ = CompactCertificationDocumentV10;
184
185 fn as_text(&self) -> &str {
186 &self.text
187 }
188
189 fn to_compact_document(&self) -> Cow<Self::CompactTextDocument_> {
190 Cow::Owned(CompactCertificationDocumentV10 {
191 issuer: self.issuer,
192 target: self.target,
193 block_number: self.blockstamp().number,
194 signature: self.signatures()[0],
195 })
196 }
197}
198
199#[derive(Debug, Copy, Clone)]
201pub struct CertificationDocumentV10Builder<'a> {
202 pub currency: &'a str,
204 pub issuer: ed25519::PublicKey,
206 pub blockstamp: Blockstamp,
208 pub target: ed25519::PublicKey,
210 pub identity_username: &'a str,
212 pub identity_blockstamp: Blockstamp,
214 pub identity_sig: ed25519::Signature,
216}
217
218impl<'a> TextDocumentBuilder for CertificationDocumentV10Builder<'a> {
219 type Document = CertificationDocumentV10;
220 type Signator = ed25519::Signator;
221
222 fn build_with_text_and_sigs(
223 self,
224 text: String,
225 signatures: SmallVec<
226 [<<Self::Document as Document>::PublicKey as PublicKey>::Signature; 1],
227 >,
228 ) -> CertificationDocumentV10 {
229 CertificationDocumentV10 {
230 text,
231 currency: self.currency.to_string(),
232 issuer: self.issuer,
233 blockstamp: self.blockstamp,
234 target: self.target,
235 identity_username: self.identity_username.to_string(),
236 identity_blockstamp: self.identity_blockstamp,
237 identity_sig: self.identity_sig,
238 signature: signatures[0],
239 }
240 }
241
242 fn generate_text(&self) -> String {
243 format!(
244 "Version: 10
245Type: Certification
246Currency: {currency}
247Issuer: {issuer}
248IdtyIssuer: {target}
249IdtyUniqueID: {idty_uid}
250IdtyTimestamp: {idty_blockstamp}
251IdtySignature: {idty_sig}
252CertTimestamp: {blockstamp}
253",
254 currency = self.currency,
255 issuer = self.issuer,
256 target = self.target,
257 idty_uid = self.identity_username,
258 idty_blockstamp = self.identity_blockstamp,
259 idty_sig = self.identity_sig,
260 blockstamp = self.blockstamp,
261 )
262 }
263}
264
265#[cfg(test)]
266mod tests {
267 use super::*;
268 use smallvec::smallvec;
269 use std::str::FromStr;
270 use unwrap::unwrap;
271
272 #[test]
273 fn generate_real_certification_document() {
274 let seed = unwrap!(
275 Seed32::from_base58("4tNQ7d9pj2Da5wUVoW9mFn7JjuPoowF977au8DdhEjVR"),
276 "fail to build Seed32"
277 );
278 let keypair = ed25519::KeyPairFromSeed32Generator::generate(seed);
279 let pubkey = keypair.public_key();
280 let signator = keypair.generate_signator();
281
282 let sig = unwrap!(ed25519::Signature::from_base64(
283 "sYbaZp3pP9F/CveT1LPiJXECTBHlNurDXqmBo71N7JX/rvmHw6m/sid9bGdIa8cUq+vDD4DMB/F7r7As1p4rAg==",
284 ), "Fail to build Signature");
285
286 let target = unwrap!(
287 ed25519::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV"),
288 "Fail to build PublicKey"
289 );
290
291 let identity_blockstamp = unwrap!(
292 Blockstamp::from_str(
293 "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
294 ),
295 "Fail to build Blockstamp"
296 );
297
298 let identity_sig = unwrap!(ed25519::Signature::from_base64(
299 "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==",
300 ), "Fail to build Signature");
301
302 let blockstamp = unwrap!(
303 Blockstamp::from_str(
304 "36-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B865",
305 ),
306 "Fail to build Blockstamp"
307 );
308
309 let builder = CertificationDocumentV10Builder {
310 currency: "duniter_unit_test_currency",
311 issuer: pubkey,
312 target,
313 identity_username: "tic",
314 identity_blockstamp,
315 identity_sig,
316 blockstamp,
317 };
318
319 assert!(builder
320 .build_with_signature(smallvec![sig])
321 .verify_signatures()
322 .is_ok());
323
324 assert!(builder
325 .build_and_sign(vec![signator])
326 .verify_signatures()
327 .is_ok());
328 }
329}