snarkvm_ledger_authority/
lib.rs

1// Copyright 2024 Aleo Network Foundation
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7
8// http://www.apache.org/licenses/LICENSE-2.0
9
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#![forbid(unsafe_code)]
17#![warn(clippy::cast_possible_truncation)]
18
19mod bytes;
20mod serialize;
21mod string;
22
23use console::{
24    account::{Address, PrivateKey, Signature},
25    network::Network,
26    prelude::{
27        Debug,
28        Deserialize,
29        DeserializeExt,
30        Deserializer,
31        Display,
32        Error,
33        Formatter,
34        FromBytes,
35        FromBytesDeserializer,
36        FromStr,
37        IoResult,
38        Read,
39        Serialize,
40        SerializeStruct,
41        Serializer,
42        ToBytes,
43        ToBytesSerializer,
44        Write,
45        de,
46        error,
47        fmt,
48        ser,
49    },
50    types::Field,
51};
52use narwhal_subdag::Subdag;
53
54use anyhow::Result;
55use rand::{CryptoRng, Rng};
56
57#[derive(Clone, PartialEq, Eq)]
58pub enum Authority<N: Network> {
59    Beacon(Signature<N>),
60    Quorum(Subdag<N>),
61}
62
63impl<N: Network> Authority<N> {
64    /// Initializes a new beacon authority.
65    pub fn new_beacon<R: Rng + CryptoRng>(
66        private_key: &PrivateKey<N>,
67        block_hash: Field<N>,
68        rng: &mut R,
69    ) -> Result<Self> {
70        // Sign the block hash.
71        let signature = private_key.sign(&[block_hash], rng)?;
72        // Return the beacon authority.
73        Ok(Self::Beacon(signature))
74    }
75
76    /// Initializes a new quorum authority.
77    pub fn new_quorum(subdag: Subdag<N>) -> Self {
78        Self::Quorum(subdag)
79    }
80}
81
82impl<N: Network> Authority<N> {
83    /// Initializes a new beacon authority from the given signature.
84    pub const fn from_beacon(signature: Signature<N>) -> Self {
85        Self::Beacon(signature)
86    }
87
88    /// Initializes a new quorum authority.
89    pub const fn from_quorum(subdag: Subdag<N>) -> Self {
90        Self::Quorum(subdag)
91    }
92}
93
94impl<N: Network> Authority<N> {
95    /// Returns `true` if the authority is a beacon.
96    pub const fn is_beacon(&self) -> bool {
97        matches!(self, Self::Beacon(_))
98    }
99
100    /// Returns `true` if the authority is a quorum.
101    pub const fn is_quorum(&self) -> bool {
102        matches!(self, Self::Quorum(_))
103    }
104}
105
106impl<N: Network> Authority<N> {
107    /// Returns address of the authority.
108    /// If the authority is a beacon, the address of the signer is returned.
109    /// If the authority is a quorum, the address of the leader is returned.
110    pub fn to_address(&self) -> Address<N> {
111        match self {
112            Self::Beacon(signature) => signature.to_address(),
113            Self::Quorum(subdag) => subdag.leader_address(),
114        }
115    }
116}
117
118#[cfg(any(test, feature = "test-helpers"))]
119pub mod test_helpers {
120    use super::*;
121    use console::prelude::{TestRng, Uniform};
122
123    pub type CurrentNetwork = console::network::MainnetV0;
124
125    /// Returns a sample beacon authority.
126    pub fn sample_beacon_authority(rng: &mut TestRng) -> Authority<CurrentNetwork> {
127        Authority::new_beacon(&PrivateKey::new(rng).unwrap(), Field::rand(rng), rng).unwrap()
128    }
129
130    /// Returns a sample quorum authority.
131    pub fn sample_quorum_authority(rng: &mut TestRng) -> Authority<CurrentNetwork> {
132        // Return the quorum authority.
133        Authority::new_quorum(narwhal_subdag::test_helpers::sample_subdag(rng))
134    }
135
136    /// Returns a list of sample authorities.
137    pub fn sample_authorities(rng: &mut TestRng) -> Vec<Authority<CurrentNetwork>> {
138        vec![sample_beacon_authority(rng), sample_quorum_authority(rng)]
139    }
140}