near_primitives/genesis/
block.rs

1use crate::block::{
2    Block, BlockHeader, BlockHeaderInnerLite, BlockHeaderInnerRest, BlockHeaderV1, BlockV1, Chunks,
3    compute_bp_hash_from_validator_stakes,
4};
5use crate::block_body::{BlockBody, BlockBodyV1};
6use crate::sharding::ShardChunkHeader;
7use crate::types::EpochId;
8use crate::types::validator_stake::ValidatorStake;
9use near_crypto::{KeyType, Signature};
10use near_primitives_core::hash::CryptoHash;
11use near_primitives_core::types::{Balance, BlockHeight, MerkleHash, ProtocolVersion};
12use near_primitives_core::version::PROD_GENESIS_PROTOCOL_VERSION;
13use near_time::Utc;
14
15/// Returns genesis block for given genesis date and state root.
16pub fn genesis_block(
17    genesis_protocol_version: ProtocolVersion,
18    chunks: Vec<ShardChunkHeader>,
19    timestamp: Utc,
20    height: BlockHeight,
21    initial_gas_price: Balance,
22    initial_total_supply: Balance,
23    validator_stakes: &Vec<ValidatorStake>,
24) -> Block {
25    assert!(genesis_protocol_version > PROD_GENESIS_PROTOCOL_VERSION);
26    let chunk_endorsements = vec![];
27    for chunk in &chunks {
28        assert_eq!(chunk.height_included(), height);
29    }
30    let vrf_value = near_crypto::vrf::Value([0; 32]);
31    let vrf_proof = near_crypto::vrf::Proof([0; 64]);
32    // We always use use_versioned_bp_hash_format after BlockHeaderV3 feature
33    let next_bp_hash = compute_bp_hash_from_validator_stakes(validator_stakes, true);
34    let chunks_wrapper = Chunks::from_chunk_headers(&chunks, height);
35    let state_root = chunks_wrapper.compute_state_root();
36    let prev_chunk_outgoing_receipts_root =
37        chunks_wrapper.compute_chunk_prev_outgoing_receipts_root();
38    let chunk_headers_root = chunks_wrapper.compute_chunk_headers_root().0;
39    let chunk_tx_root = chunks_wrapper.compute_chunk_tx_root();
40    let body = BlockBody::new(chunks, vrf_value, vrf_proof, chunk_endorsements);
41    let header = BlockHeader::genesis(
42        genesis_protocol_version,
43        height,
44        state_root,
45        body.compute_hash(),
46        prev_chunk_outgoing_receipts_root,
47        chunk_headers_root,
48        chunk_tx_root,
49        body.chunks().len() as u64,
50        timestamp,
51        initial_gas_price,
52        initial_total_supply,
53        next_bp_hash,
54    );
55
56    Block::new_block(header, body)
57}
58
59pub fn prod_genesis_block(
60    chunks: Vec<ShardChunkHeader>,
61    timestamp: Utc,
62    height: BlockHeight,
63    initial_gas_price: Balance,
64    initial_total_supply: Balance,
65    validator_stakes: &Vec<ValidatorStake>,
66) -> Block {
67    let next_bp_hash = compute_bp_hash_from_validator_stakes(validator_stakes, false);
68    #[allow(deprecated)]
69    let body = BlockBody::V1(BlockBodyV1 {
70        chunks: chunks.clone(),
71        challenges: vec![],
72        vrf_value: near_crypto::vrf::Value([0; 32]),
73        vrf_proof: near_crypto::vrf::Proof([0; 64]),
74    });
75
76    let chunk_wrapper = Chunks::from_chunk_headers(&chunks, height);
77    let state_root = chunk_wrapper.compute_state_root();
78    let prev_chunk_outgoing_receipts_root =
79        chunk_wrapper.compute_chunk_prev_outgoing_receipts_root();
80    let chunk_headers_root = chunk_wrapper.compute_chunk_headers_root().0;
81    let chunk_tx_root = chunk_wrapper.compute_chunk_tx_root();
82
83    let header = BlockHeader::prod_genesis(
84        height,
85        state_root,
86        prev_chunk_outgoing_receipts_root,
87        chunk_headers_root,
88        chunk_tx_root,
89        timestamp,
90        initial_gas_price,
91        initial_total_supply,
92        next_bp_hash,
93    );
94
95    let chunks = chunks
96        .into_iter()
97        .map(|chunk| match chunk {
98            ShardChunkHeader::V1(header) => header,
99            _ => panic!("Unexpected chunk version in prod genesis"),
100        })
101        .collect();
102
103    #[allow(deprecated)]
104    Block::BlockV1(BlockV1 {
105        header,
106        chunks,
107        challenges: vec![],
108        vrf_value: *body.vrf_value(),
109        vrf_proof: *body.vrf_proof(),
110    })
111}
112
113impl BlockHeader {
114    pub fn prod_genesis(
115        height: BlockHeight,
116        state_root: MerkleHash,
117        prev_chunk_outgoing_receipts_root: MerkleHash,
118        chunk_headers_root: MerkleHash,
119        chunk_tx_root: MerkleHash,
120        timestamp: Utc,
121        initial_gas_price: Balance,
122        initial_total_supply: Balance,
123        next_bp_hash: CryptoHash,
124    ) -> Self {
125        let inner_lite = BlockHeaderInnerLite {
126            height,
127            epoch_id: EpochId::default(),
128            next_epoch_id: EpochId::default(),
129            prev_state_root: state_root,
130            prev_outcome_root: CryptoHash::default(),
131            timestamp: timestamp.unix_timestamp_nanos() as u64,
132            next_bp_hash,
133            block_merkle_root: CryptoHash::default(),
134        };
135
136        #[allow(deprecated)]
137        let inner_rest = BlockHeaderInnerRest {
138            prev_chunk_outgoing_receipts_root,
139            chunk_headers_root,
140            chunk_tx_root,
141            chunks_included: 0,
142            challenges_root: CryptoHash::default(),
143            random_value: CryptoHash::default(),
144            prev_validator_proposals: vec![],
145            chunk_mask: vec![],
146            next_gas_price: initial_gas_price,
147            total_supply: initial_total_supply,
148            challenges_result: vec![],
149            last_final_block: CryptoHash::default(),
150            last_ds_final_block: CryptoHash::default(),
151            approvals: vec![],
152            latest_protocol_version: PROD_GENESIS_PROTOCOL_VERSION,
153        };
154        let hash = BlockHeader::compute_hash(
155            CryptoHash::default(),
156            &borsh::to_vec(&inner_lite).expect("Failed to serialize"),
157            &borsh::to_vec(&inner_rest).expect("Failed to serialize"),
158        );
159        Self::BlockHeaderV1(BlockHeaderV1 {
160            prev_hash: CryptoHash::default(),
161            inner_lite,
162            inner_rest,
163            signature: Signature::empty(KeyType::ED25519),
164            hash,
165        })
166    }
167}