snarkvm_ledger_block/
genesis.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
16use super::*;
17
18impl<N: Network> Block<N> {
19    /// Specifies the number of genesis transactions.
20    pub const NUM_GENESIS_TRANSACTIONS: usize = 4;
21
22    /// Returns `true` if the block is a genesis block.
23    pub fn is_genesis(&self) -> Result<bool> {
24        if !self.header.is_genesis()? {
25            return Ok(false);
26        }
27
28        ensure!(self.previous_hash == N::BlockHash::default(), "Invalid previous hash");
29        ensure!(self.authority.is_beacon(), "Invalid block authority");
30        ensure!(self.solutions.is_empty(), "Invalid solutins");
31        ensure!(self.transactions.num_rejected() == 0, "Invalid number of rejected transactions");
32        ensure!(self.aborted_transaction_ids.is_empty(), "Genesis block must not contain aborted transactions");
33
34        // Perform additional checks in production
35        #[cfg(not(any(test, feature = "test")))]
36        {
37            ensure!(self.ratifications.len() == 1, "Invalid number of ratifications");
38            ensure!(
39                self.transactions.num_accepted() == Self::NUM_GENESIS_TRANSACTIONS,
40                "Invalid number of accepted transactions"
41            );
42            ensure!(
43                self.transactions.num_finalize() == 2 * Self::NUM_GENESIS_TRANSACTIONS,
44                "Invalid number of finalized transactions"
45            );
46        }
47
48        Ok(true)
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55    use console::network::MainnetV0;
56
57    type CurrentNetwork = MainnetV0;
58
59    #[test]
60    fn test_genesis() {
61        // Load the genesis block.
62        let genesis_block = Block::<CurrentNetwork>::read_le(CurrentNetwork::genesis_bytes()).unwrap();
63        assert!(genesis_block.is_genesis().unwrap());
64    }
65}