1
//! General collection of types.
2
//!
3
//! This module serves as a collection of types useful for the operation of a
4
//! directory server that are not related to the database, in which case they
5
//! belong to the respective [`crate::database`] module.
6

            
7
use tor_netdoc::{
8
    doc::{
9
        authcert::AuthCertKeyIds,
10
        netstatus::{ConsensusFlavor, md, plain},
11
    },
12
    parse2::{NetdocParseable, NetdocParseableUnverified},
13
};
14

            
15
/// Generic trait representing a flavored verified consensus.
16
///
17
/// Similar to [`FlavoredConsensusUnverified`] and obtained from it.
18
pub(crate) trait FlavoredConsensusBody: Clone {}
19

            
20
/// Generic trait representing the signatures of a consensus.
21
///
22
/// Similar to [`FlavoredConsensusUnverified`] and obtained from it.
23
pub(crate) trait FlavoredConsensusSignatures: Clone {
24
    /// Returns the [`AuthCertKeyIds`] of all authority certificates in the signatures.
25
    // TODO DIRMIRROR: Obtain this from the respective error variant returned by
26
    // .can_verify().
27
    // TODO: The respective implementations are repetitive, can we do better?
28
    fn signatories(&self) -> Vec<AuthCertKeyIds>;
29
}
30

            
31
/// Generic trait representing a flavored unverified consensus.
32
///
33
/// Required because in certain parts of the code, the exact flavor of the
34
/// consensus does not matter.
35
///
36
/// See [`FlavoredConsensusBody`] for the verified variant of it.
37
pub(crate) trait FlavoredConsensusUnverified:
38
    NetdocParseableUnverified<Body: FlavoredConsensusBody, Signatures: FlavoredConsensusSignatures>
39
    + NetdocParseable
40
    + Clone
41
{
42
    /// Returns the [`ConsensusFlavor`] of this type.
43
    fn flavor() -> ConsensusFlavor;
44

            
45
    /// Returns the signatures contained inside.
46
    ///
47
    /// It corresponds to accessing the publicly available T::sigs which is
48
    /// guaranteed to be present due to derive logic.
49
    ///
50
    /// Functionally equivalent to accessing the signatures through
51
    /// [`NetdocParseableUnverified::inspect_unverified()`], yet it tries to
52
    /// provide a safer semantic around it.
53
8
    fn sigs(&self) -> &Self::Signatures {
54
8
        &self.inspect_unverified().1.sigs
55
8
    }
56
}
57

            
58
impl FlavoredConsensusBody for plain::NetworkStatus {}
59

            
60
impl FlavoredConsensusBody for md::NetworkStatus {}
61

            
62
impl FlavoredConsensusSignatures for plain::NetworkStatusSignatures {
63
8
    fn signatories(&self) -> Vec<AuthCertKeyIds> {
64
8
        self.directory_signature
65
8
            .iter()
66
8
            .map(|sig| sig.key_ids)
67
8
            .collect()
68
8
    }
69
}
70

            
71
impl FlavoredConsensusSignatures for md::NetworkStatusSignatures {
72
    fn signatories(&self) -> Vec<AuthCertKeyIds> {
73
        self.directory_signature
74
            .iter()
75
            .map(|sig| sig.key_ids)
76
            .collect()
77
    }
78
}
79

            
80
impl FlavoredConsensusUnverified for plain::NetworkStatusUnverified {
81
42
    fn flavor() -> ConsensusFlavor {
82
42
        ConsensusFlavor::Plain
83
42
    }
84
}
85

            
86
impl FlavoredConsensusUnverified for md::NetworkStatusUnverified {
87
6
    fn flavor() -> ConsensusFlavor {
88
6
        ConsensusFlavor::Microdesc
89
6
    }
90
}