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
15pub 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 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}