use super::*;
impl<N: Network> Header<N> {
pub fn genesis(
ratifications: &Ratifications<N>,
transactions: &Transactions<N>,
ratified_finalize_operations: Vec<FinalizeOperation<N>>,
) -> Result<Self> {
#[cfg(not(debug_assertions))]
ensure!(!ratifications.is_empty(), "The genesis block must not contain ratifications");
#[cfg(not(debug_assertions))]
ensure!(ratifications.len() == 1, "The genesis block must not contain 1 ratification");
#[cfg(not(debug_assertions))]
ensure!(!ratified_finalize_operations.is_empty(), "The genesis block must contain ratify-finalize operations");
let previous_state_root = Into::<N::StateRoot>::into(Field::zero());
let transactions_root = transactions.to_transactions_root()?;
let finalize_root = transactions.to_finalize_root(ratified_finalize_operations)?;
let ratifications_root = ratifications.to_ratifications_root()?;
let solutions_root = Field::zero();
let subdag_root = Field::zero();
let metadata = Metadata::genesis()?;
Self::from(
previous_state_root,
transactions_root,
finalize_root,
ratifications_root,
solutions_root,
subdag_root,
metadata,
)
}
pub fn is_genesis(&self) -> bool {
*self.previous_state_root == Field::zero()
&& self.transactions_root != Field::zero()
&& self.finalize_root != Field::zero()
&& self.ratifications_root != Field::zero()
&& self.solutions_root == Field::zero()
&& self.subdag_root == Field::zero()
&& self.metadata.is_genesis()
}
}
#[cfg(test)]
mod tests {
use super::*;
use console::network::Testnet3;
type CurrentNetwork = Testnet3;
fn get_expected_size<N: Network>() -> usize {
(Field::<N>::size_in_bytes() * 6)
+ 1 + 8 + 4 + 16 + 16 + 8 + 8 + 8 + 8 + 8
+ 1 + 2
}
#[test]
fn test_genesis_header_size() {
let rng = &mut TestRng::default();
let expected_size = get_expected_size::<CurrentNetwork>();
let genesis_header = crate::header::test_helpers::sample_block_header(rng);
assert_eq!(expected_size, genesis_header.to_bytes_le().unwrap().len());
}
#[test]
fn test_genesis_header() {
let rng = &mut TestRng::default();
let header = crate::header::test_helpers::sample_block_header(rng);
assert!(header.is_genesis());
assert_eq!(*header.previous_state_root(), Field::zero());
assert_eq!(header.solutions_root(), Field::zero());
assert_eq!(header.subdag_root(), Field::zero());
assert_eq!(header.network(), CurrentNetwork::ID);
assert_eq!(header.round(), 0);
assert_eq!(header.height(), 0);
assert_eq!(header.cumulative_weight(), 0);
assert_eq!(header.coinbase_target(), CurrentNetwork::GENESIS_COINBASE_TARGET);
assert_eq!(header.proof_target(), CurrentNetwork::GENESIS_PROOF_TARGET);
assert_eq!(header.last_coinbase_target(), CurrentNetwork::GENESIS_COINBASE_TARGET);
assert_eq!(header.last_coinbase_timestamp(), CurrentNetwork::GENESIS_TIMESTAMP);
assert_eq!(header.timestamp(), CurrentNetwork::GENESIS_TIMESTAMP);
assert_ne!(header.transactions_root(), Field::zero());
assert_ne!(header.finalize_root(), Field::zero());
assert_ne!(header.ratifications_root(), Field::zero());
}
}