use super::*;
use snarkvm_utilities::ensure_equals;
const GENESIS_ROUND: u64 = 0;
const GENESIS_HEIGHT: u32 = 0;
const GENESIS_CUMULATIVE_WEIGHT: u128 = 0;
const GENESIS_CUMULATIVE_PROOF_TARGET: u128 = 0;
impl<N: Network> Metadata<N> {
pub fn genesis() -> Result<Self> {
Self::new(
N::ID,
GENESIS_ROUND,
GENESIS_HEIGHT,
GENESIS_CUMULATIVE_WEIGHT,
GENESIS_CUMULATIVE_PROOF_TARGET,
N::GENESIS_COINBASE_TARGET,
N::GENESIS_PROOF_TARGET,
N::GENESIS_COINBASE_TARGET,
N::GENESIS_TIMESTAMP,
N::GENESIS_TIMESTAMP,
)
.with_context(|| "Failed to create genesis block")
}
pub fn is_genesis(&self) -> Result<bool> {
if self.round != 0u64 {
return Ok(false);
}
ensure!(self.network == N::ID, "Invalid network ID");
ensure!(self.round == GENESIS_ROUND, "Genesis block not at genesis round");
ensure!(self.height == GENESIS_HEIGHT, "Genesis block not at genesis height");
ensure_equals!(self.cumulative_weight, GENESIS_CUMULATIVE_WEIGHT, "Invalid cumulative weight");
ensure_equals!(
self.cumulative_proof_target,
GENESIS_CUMULATIVE_PROOF_TARGET,
"Invalid cumulative proof target"
);
ensure_equals!(self.timestamp, N::GENESIS_TIMESTAMP, "Invalid timestamp");
ensure_equals!(self.last_coinbase_timestamp, N::GENESIS_TIMESTAMP, "Invalid last coinbase timestamp");
ensure_equals!(self.coinbase_target, N::GENESIS_COINBASE_TARGET, "Invalid coinbase target for genesis block");
ensure_equals!(
self.last_coinbase_target,
N::GENESIS_COINBASE_TARGET,
"Invalid last coinbase target for genesis block"
);
ensure_equals!(self.proof_target, N::GENESIS_PROOF_TARGET, "Invalid proof target for genesis block");
Ok(true)
}
}
#[cfg(test)]
mod tests {
use super::*;
use console::network::MainnetV0;
type CurrentNetwork = MainnetV0;
fn get_expected_size() -> usize {
1 + 8 + 4 + 16 + 16 + 8 + 8 + 8 + 8 + 8
+ 2
}
#[test]
fn test_genesis_metadata_size() {
let rng = &mut TestRng::default();
let expected_size = get_expected_size();
let genesis_metadata = crate::header::metadata::test_helpers::sample_block_metadata(rng);
assert_eq!(expected_size, genesis_metadata.to_bytes_le().unwrap().len());
}
#[test]
fn test_genesis_metadata() {
let rng = &mut TestRng::default();
let metadata = crate::header::metadata::test_helpers::sample_block_metadata(rng);
assert!(metadata.is_genesis().unwrap());
assert_eq!(metadata.network(), CurrentNetwork::ID);
assert_eq!(metadata.round(), 0);
assert_eq!(metadata.height(), 0);
assert_eq!(metadata.cumulative_weight(), 0);
assert_eq!(metadata.cumulative_proof_target(), 0);
assert_eq!(metadata.coinbase_target(), CurrentNetwork::GENESIS_COINBASE_TARGET);
assert_eq!(metadata.proof_target(), CurrentNetwork::GENESIS_PROOF_TARGET);
assert_eq!(metadata.last_coinbase_target(), CurrentNetwork::GENESIS_COINBASE_TARGET);
assert_eq!(metadata.last_coinbase_timestamp(), CurrentNetwork::GENESIS_TIMESTAMP);
assert_eq!(metadata.timestamp(), CurrentNetwork::GENESIS_TIMESTAMP);
}
}