snarkvm_ledger_authority/
lib.rs

1// Copyright (c) 2019-2025 Provable Inc.
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
19extern crate snarkvm_console as console;
20
21mod bytes;
22mod serialize;
23mod string;
24
25use console::{
26    account::{Address, PrivateKey, Signature},
27    network::Network,
28    prelude::{
29        Debug,
30        Deserialize,
31        DeserializeExt,
32        Deserializer,
33        Display,
34        Error,
35        Formatter,
36        FromBytes,
37        FromBytesDeserializer,
38        FromStr,
39        IoResult,
40        Read,
41        Serialize,
42        SerializeStruct,
43        Serializer,
44        ToBytes,
45        ToBytesSerializer,
46        Write,
47        de,
48        error,
49        fmt,
50        ser,
51    },
52    types::Field,
53};
54use snarkvm_ledger_narwhal_subdag::Subdag;
55
56use anyhow::Result;
57use rand::{CryptoRng, Rng};
58
59#[derive(Clone, PartialEq, Eq)]
60pub enum Authority<N: Network> {
61    Beacon(Signature<N>),
62    Quorum(Subdag<N>),
63}
64
65impl<N: Network> Authority<N> {
66    /// Initializes a new beacon authority.
67    pub fn new_beacon<R: Rng + CryptoRng>(
68        private_key: &PrivateKey<N>,
69        block_hash: Field<N>,
70        rng: &mut R,
71    ) -> Result<Self> {
72        // Sign the block hash.
73        let signature = private_key.sign(&[block_hash], rng)?;
74        // Return the beacon authority.
75        Ok(Self::Beacon(signature))
76    }
77
78    /// Initializes a new quorum authority.
79    pub fn new_quorum(subdag: Subdag<N>) -> Self {
80        Self::Quorum(subdag)
81    }
82}
83
84impl<N: Network> Authority<N> {
85    /// Initializes a new beacon authority from the given signature.
86    pub const fn from_beacon(signature: Signature<N>) -> Self {
87        Self::Beacon(signature)
88    }
89
90    /// Initializes a new quorum authority.
91    pub const fn from_quorum(subdag: Subdag<N>) -> Self {
92        Self::Quorum(subdag)
93    }
94}
95
96impl<N: Network> Authority<N> {
97    /// Returns `true` if the authority is a beacon.
98    pub const fn is_beacon(&self) -> bool {
99        matches!(self, Self::Beacon(_))
100    }
101
102    /// Returns `true` if the authority is a quorum.
103    pub const fn is_quorum(&self) -> bool {
104        matches!(self, Self::Quorum(_))
105    }
106}
107
108impl<N: Network> Authority<N> {
109    /// Returns address of the authority.
110    /// If the authority is a beacon, the address of the signer is returned.
111    /// If the authority is a quorum, the address of the leader is returned.
112    pub fn to_address(&self) -> Address<N> {
113        match self {
114            Self::Beacon(signature) => signature.to_address(),
115            Self::Quorum(subdag) => subdag.leader_address(),
116        }
117    }
118}
119
120#[cfg(any(test, feature = "test-helpers"))]
121pub mod test_helpers {
122    use super::*;
123    use console::prelude::{TestRng, Uniform};
124
125    pub type CurrentNetwork = console::network::MainnetV0;
126
127    /// Returns a sample beacon authority.
128    pub fn sample_beacon_authority(rng: &mut TestRng) -> Authority<CurrentNetwork> {
129        Authority::new_beacon(&PrivateKey::new(rng).unwrap(), Field::rand(rng), rng).unwrap()
130    }
131
132    /// Returns a sample quorum authority.
133    pub fn sample_quorum_authority(rng: &mut TestRng) -> Authority<CurrentNetwork> {
134        // Return the quorum authority.
135        Authority::new_quorum(snarkvm_ledger_narwhal_subdag::test_helpers::sample_subdag(rng))
136    }
137
138    /// Returns a list of sample authorities.
139    pub fn sample_authorities(rng: &mut TestRng) -> Vec<Authority<CurrentNetwork>> {
140        vec![sample_beacon_authority(rng), sample_quorum_authority(rng)]
141    }
142}