1use crate::challenge::SlashedValidator;
2use crate::hash::{CryptoHash, hash};
3use crate::merkle::combine_hash;
4use crate::network::PeerId;
5use crate::stateless_validation::chunk_endorsements_bitmap::ChunkEndorsementsBitmap;
6use crate::types::validator_stake::{ValidatorStake, ValidatorStakeIter, ValidatorStakeV1};
7use crate::types::{
8 AccountId, Balance, BlockHeight, EpochId, MerkleHash, NumBlocks, ShardId,
9 SpiceChunkEndorsementStats,
10};
11use crate::validator_signer::ValidatorSigner;
12use crate::version::ProtocolVersion;
13use borsh::{BorshDeserialize, BorshSerialize};
14use near_crypto::{KeyType, PublicKey, Signature};
15use near_primitives_core::version::ProtocolFeature;
16use near_schema_checker_lib::ProtocolSchema;
17use near_time::Utc;
18
19#[derive(
20 BorshSerialize,
21 BorshDeserialize,
22 serde::Serialize,
23 Debug,
24 Clone,
25 Eq,
26 PartialEq,
27 Default,
28 ProtocolSchema,
29)]
30pub struct BlockHeaderInnerLite {
31 pub height: BlockHeight,
33 pub epoch_id: EpochId,
36 pub next_epoch_id: EpochId,
37 pub prev_state_root: MerkleHash,
39 pub prev_outcome_root: MerkleHash,
41 pub timestamp: u64,
43 pub next_bp_hash: CryptoHash,
45 pub block_merkle_root: CryptoHash,
47}
48
49#[derive(
50 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq, ProtocolSchema,
51)]
52pub struct BlockHeaderInnerRest {
53 pub prev_chunk_outgoing_receipts_root: MerkleHash,
55 pub chunk_headers_root: MerkleHash,
57 pub chunk_tx_root: MerkleHash,
59 pub chunks_included: u64,
61 #[deprecated]
63 pub challenges_root: MerkleHash,
64 pub random_value: CryptoHash,
66 pub prev_validator_proposals: Vec<ValidatorStakeV1>,
68 pub chunk_mask: Vec<bool>,
70 pub next_gas_price: Balance,
72 pub total_supply: Balance,
74 #[deprecated]
76 pub challenges_result: Vec<SlashedValidator>,
77
78 pub last_final_block: CryptoHash,
80 pub last_ds_final_block: CryptoHash,
82
83 pub approvals: Vec<Option<Box<Signature>>>,
85
86 pub latest_protocol_version: ProtocolVersion,
88}
89
90#[derive(
92 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq, ProtocolSchema,
93)]
94pub struct BlockHeaderInnerRestV2 {
95 pub prev_chunk_outgoing_receipts_root: MerkleHash,
97 pub chunk_headers_root: MerkleHash,
99 pub chunk_tx_root: MerkleHash,
101 #[deprecated]
103 pub challenges_root: MerkleHash,
104 pub random_value: CryptoHash,
106 pub prev_validator_proposals: Vec<ValidatorStakeV1>,
108 pub chunk_mask: Vec<bool>,
110 pub next_gas_price: Balance,
112 pub total_supply: Balance,
114 #[deprecated]
116 pub challenges_result: Vec<SlashedValidator>,
117
118 pub last_final_block: CryptoHash,
120 pub last_ds_final_block: CryptoHash,
122
123 pub approvals: Vec<Option<Box<Signature>>>,
125
126 pub latest_protocol_version: ProtocolVersion,
128}
129
130#[derive(
135 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq, ProtocolSchema,
136)]
137pub struct BlockHeaderInnerRestV3 {
138 pub prev_chunk_outgoing_receipts_root: MerkleHash,
140 pub chunk_headers_root: MerkleHash,
142 pub chunk_tx_root: MerkleHash,
144 #[deprecated]
146 pub challenges_root: MerkleHash,
147 pub random_value: CryptoHash,
149 pub prev_validator_proposals: Vec<ValidatorStake>,
151 pub chunk_mask: Vec<bool>,
153 pub next_gas_price: Balance,
155 pub total_supply: Balance,
157 #[deprecated]
159 pub challenges_result: Vec<SlashedValidator>,
160
161 pub last_final_block: CryptoHash,
163 pub last_ds_final_block: CryptoHash,
165
166 pub block_ordinal: NumBlocks,
168
169 pub prev_height: BlockHeight,
170
171 pub epoch_sync_data_hash: Option<CryptoHash>,
172
173 pub approvals: Vec<Option<Box<Signature>>>,
175
176 pub latest_protocol_version: ProtocolVersion,
178}
179
180#[derive(
182 BorshSerialize,
183 BorshDeserialize,
184 serde::Serialize,
185 Debug,
186 Clone,
187 Eq,
188 PartialEq,
189 Default,
190 ProtocolSchema,
191)]
192pub struct BlockHeaderInnerRestV4 {
193 pub block_body_hash: CryptoHash,
195 pub prev_chunk_outgoing_receipts_root: MerkleHash,
197 pub chunk_headers_root: MerkleHash,
199 pub chunk_tx_root: MerkleHash,
201 #[deprecated]
203 pub challenges_root: MerkleHash,
204 pub random_value: CryptoHash,
206 pub prev_validator_proposals: Vec<ValidatorStake>,
208 pub chunk_mask: Vec<bool>,
210 pub next_gas_price: Balance,
212 pub total_supply: Balance,
214 #[deprecated]
216 pub challenges_result: Vec<SlashedValidator>,
217
218 pub last_final_block: CryptoHash,
220 pub last_ds_final_block: CryptoHash,
222
223 pub block_ordinal: NumBlocks,
225
226 pub prev_height: BlockHeight,
227
228 pub epoch_sync_data_hash: Option<CryptoHash>,
229
230 pub approvals: Vec<Option<Box<Signature>>>,
232
233 pub latest_protocol_version: ProtocolVersion,
235}
236
237#[derive(
239 BorshSerialize,
240 BorshDeserialize,
241 serde::Serialize,
242 Debug,
243 Clone,
244 Eq,
245 PartialEq,
246 Default,
247 ProtocolSchema,
248)]
249pub struct BlockHeaderInnerRestV5 {
250 pub block_body_hash: CryptoHash,
252 pub prev_chunk_outgoing_receipts_root: MerkleHash,
254 pub chunk_headers_root: MerkleHash,
256 pub chunk_tx_root: MerkleHash,
258 #[deprecated]
260 pub challenges_root: MerkleHash,
261 pub random_value: CryptoHash,
263 pub prev_validator_proposals: Vec<ValidatorStake>,
265 pub chunk_mask: Vec<bool>,
267 pub next_gas_price: Balance,
269 pub total_supply: Balance,
271 #[deprecated]
273 pub challenges_result: Vec<SlashedValidator>,
274
275 pub last_final_block: CryptoHash,
277 pub last_ds_final_block: CryptoHash,
279
280 pub block_ordinal: NumBlocks,
282
283 pub prev_height: BlockHeight,
284
285 pub epoch_sync_data_hash: Option<CryptoHash>,
286
287 pub approvals: Vec<Option<Box<Signature>>>,
289
290 pub latest_protocol_version: ProtocolVersion,
292
293 pub chunk_endorsements: ChunkEndorsementsBitmap,
294}
295
296#[derive(
298 BorshSerialize,
299 BorshDeserialize,
300 serde::Serialize,
301 Debug,
302 Clone,
303 Eq,
304 PartialEq,
305 Default,
306 ProtocolSchema,
307)]
308pub struct BlockHeaderInnerRestV6 {
309 pub block_body_hash: CryptoHash,
311 pub prev_chunk_outgoing_receipts_root: MerkleHash,
313 pub chunk_headers_root: MerkleHash,
315 pub chunk_tx_root: MerkleHash,
317 pub random_value: CryptoHash,
319 pub prev_validator_proposals: Vec<ValidatorStake>,
321 pub chunk_mask: Vec<bool>,
323 pub next_gas_price: Balance,
325 pub total_supply: Balance,
327
328 pub last_final_block: CryptoHash,
330 pub last_ds_final_block: CryptoHash,
332
333 pub block_ordinal: NumBlocks,
335
336 pub prev_height: BlockHeight,
337
338 pub epoch_sync_data_hash: Option<CryptoHash>,
339
340 pub approvals: Vec<Option<Box<Signature>>>,
342
343 pub latest_protocol_version: ProtocolVersion,
345
346 pub chunk_endorsements: ChunkEndorsementsBitmap,
347
348 pub shard_split: Option<(ShardId, AccountId)>,
352}
353
354#[derive(
356 BorshSerialize,
357 BorshDeserialize,
358 serde::Serialize,
359 Debug,
360 Clone,
361 Eq,
362 PartialEq,
363 Default,
364 ProtocolSchema,
365)]
366pub struct BlockHeaderInnerRestV7 {
367 pub block_body_hash: CryptoHash,
369 pub prev_chunk_outgoing_receipts_root: MerkleHash,
371 pub chunk_headers_root: MerkleHash,
373 pub chunk_tx_root: MerkleHash,
375 pub random_value: CryptoHash,
377 pub prev_validator_proposals: Vec<ValidatorStake>,
379 pub chunk_mask: Vec<bool>,
381 pub next_gas_price: Balance,
383 pub total_supply: Balance,
385
386 pub last_final_block: CryptoHash,
388 pub last_ds_final_block: CryptoHash,
390
391 pub block_ordinal: NumBlocks,
393
394 pub prev_height: BlockHeight,
395
396 pub epoch_sync_data_hash: Option<CryptoHash>,
397
398 pub approvals: Vec<Option<Box<Signature>>>,
400
401 pub latest_protocol_version: ProtocolVersion,
403
404 pub chunk_endorsements: ChunkEndorsementsBitmap,
405
406 pub shard_split: Option<(ShardId, AccountId)>,
410
411 pub prev_last_certified_block_epoch_id: EpochId,
413
414 pub spice_chunk_endorsement_stats: Vec<SpiceChunkEndorsementStats>,
418}
419
420#[derive(
422 BorshSerialize,
423 BorshDeserialize,
424 serde::Serialize,
425 Debug,
426 Clone,
427 PartialEq,
428 Eq,
429 Hash,
430 ProtocolSchema,
431)]
432#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
433pub enum ApprovalInner {
434 Endorsement(CryptoHash),
435 Skip(BlockHeight),
436}
437
438#[derive(
440 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, PartialEq, Eq, ProtocolSchema,
441)]
442pub struct Approval {
443 pub inner: ApprovalInner,
444 pub target_height: BlockHeight,
445 pub signature: Signature,
446 pub account_id: AccountId,
447}
448
449#[derive(PartialEq, Eq, Debug)]
451pub enum ApprovalType {
452 SelfApproval,
453 PeerApproval(PeerId),
454}
455
456#[derive(
458 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, PartialEq, Eq, ProtocolSchema,
459)]
460pub struct ApprovalMessage {
461 pub approval: Approval,
462 pub target: AccountId,
463}
464
465impl ApprovalInner {
466 pub fn new(
467 parent_hash: &CryptoHash,
468 parent_height: BlockHeight,
469 target_height: BlockHeight,
470 ) -> Self {
471 if target_height == parent_height + 1 {
472 ApprovalInner::Endorsement(*parent_hash)
473 } else {
474 ApprovalInner::Skip(parent_height)
475 }
476 }
477}
478
479impl Approval {
480 pub fn new(
481 parent_hash: CryptoHash,
482 parent_height: BlockHeight,
483 target_height: BlockHeight,
484 signer: &ValidatorSigner,
485 ) -> Self {
486 let inner = ApprovalInner::new(&parent_hash, parent_height, target_height);
487
488 let signature = signer.sign_bytes(&Approval::get_data_for_sig(&inner, target_height));
489 Approval { inner, target_height, signature, account_id: signer.validator_id().clone() }
490 }
491
492 pub fn get_data_for_sig(inner: &ApprovalInner, target_height: BlockHeight) -> Vec<u8> {
493 [borsh::to_vec(&inner).unwrap().as_ref(), target_height.to_le_bytes().as_ref()].concat()
494 }
495}
496
497impl ApprovalMessage {
498 pub fn new(approval: Approval, target: AccountId) -> Self {
499 ApprovalMessage { approval, target }
500 }
501}
502
503#[derive(
504 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq, ProtocolSchema,
505)]
506#[borsh(init=init)]
507pub struct BlockHeaderV1 {
508 pub prev_hash: CryptoHash,
509
510 pub inner_lite: BlockHeaderInnerLite,
513 pub inner_rest: BlockHeaderInnerRest,
514
515 pub signature: Signature,
517
518 #[borsh(skip)]
520 pub hash: CryptoHash,
521}
522
523impl BlockHeaderV1 {
524 pub fn init(&mut self) {
525 self.hash = BlockHeader::compute_hash(
526 self.prev_hash,
527 &borsh::to_vec(&self.inner_lite).expect("Failed to serialize"),
528 &borsh::to_vec(&self.inner_rest).expect("Failed to serialize"),
529 );
530 }
531}
532
533#[derive(
535 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq, ProtocolSchema,
536)]
537#[borsh(init=init)]
538pub struct BlockHeaderV2 {
539 pub prev_hash: CryptoHash,
540
541 pub inner_lite: BlockHeaderInnerLite,
544 pub inner_rest: BlockHeaderInnerRestV2,
545
546 pub signature: Signature,
548
549 #[borsh(skip)]
551 pub hash: CryptoHash,
552}
553
554#[derive(
557 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq, ProtocolSchema,
558)]
559#[borsh(init=init)]
560pub struct BlockHeaderV3 {
561 pub prev_hash: CryptoHash,
562
563 pub inner_lite: BlockHeaderInnerLite,
566 pub inner_rest: BlockHeaderInnerRestV3,
567
568 pub signature: Signature,
570
571 #[borsh(skip)]
573 pub hash: CryptoHash,
574}
575
576#[derive(
578 BorshSerialize,
579 BorshDeserialize,
580 serde::Serialize,
581 Debug,
582 Clone,
583 Eq,
584 PartialEq,
585 Default,
586 ProtocolSchema,
587)]
588#[borsh(init=init)]
589pub struct BlockHeaderV4 {
590 pub prev_hash: CryptoHash,
591
592 pub inner_lite: BlockHeaderInnerLite,
595 pub inner_rest: BlockHeaderInnerRestV4,
596
597 pub signature: Signature,
599
600 #[borsh(skip)]
602 pub hash: CryptoHash,
603}
604
605#[derive(
607 BorshSerialize,
608 BorshDeserialize,
609 serde::Serialize,
610 Debug,
611 Clone,
612 Eq,
613 PartialEq,
614 Default,
615 ProtocolSchema,
616)]
617#[borsh(init=init)]
618pub struct BlockHeaderV5 {
619 pub prev_hash: CryptoHash,
620
621 pub inner_lite: BlockHeaderInnerLite,
624 pub inner_rest: BlockHeaderInnerRestV5,
625
626 pub signature: Signature,
628
629 #[borsh(skip)]
631 pub hash: CryptoHash,
632}
633
634#[derive(
636 BorshSerialize,
637 BorshDeserialize,
638 serde::Serialize,
639 Debug,
640 Clone,
641 Eq,
642 PartialEq,
643 Default,
644 ProtocolSchema,
645)]
646#[borsh(init=init)]
647pub struct BlockHeaderV6 {
648 pub prev_hash: CryptoHash,
649
650 pub inner_lite: BlockHeaderInnerLite,
654 pub inner_rest: BlockHeaderInnerRestV6,
655
656 pub signature: Signature,
658
659 #[borsh(skip)]
661 pub hash: CryptoHash,
662}
663
664#[derive(
666 BorshSerialize,
667 BorshDeserialize,
668 serde::Serialize,
669 Debug,
670 Clone,
671 Eq,
672 PartialEq,
673 Default,
674 ProtocolSchema,
675)]
676#[borsh(init=init)]
677pub struct BlockHeaderV7 {
678 pub prev_hash: CryptoHash,
679
680 pub inner_lite: BlockHeaderInnerLite,
684 pub inner_rest: BlockHeaderInnerRestV7,
685
686 pub signature: Signature,
688
689 #[borsh(skip)]
691 pub hash: CryptoHash,
692}
693
694impl BlockHeaderV2 {
695 pub fn init(&mut self) {
696 self.hash = BlockHeader::compute_hash(
697 self.prev_hash,
698 &borsh::to_vec(&self.inner_lite).expect("Failed to serialize"),
699 &borsh::to_vec(&self.inner_rest).expect("Failed to serialize"),
700 );
701 }
702}
703
704impl BlockHeaderV3 {
705 pub fn init(&mut self) {
706 self.hash = BlockHeader::compute_hash(
707 self.prev_hash,
708 &borsh::to_vec(&self.inner_lite).expect("Failed to serialize"),
709 &borsh::to_vec(&self.inner_rest).expect("Failed to serialize"),
710 );
711 }
712}
713
714impl BlockHeaderV4 {
715 pub fn init(&mut self) {
716 self.hash = BlockHeader::compute_hash(
717 self.prev_hash,
718 &borsh::to_vec(&self.inner_lite).expect("Failed to serialize"),
719 &borsh::to_vec(&self.inner_rest).expect("Failed to serialize"),
720 );
721 }
722}
723
724impl BlockHeaderV5 {
725 pub fn init(&mut self) {
726 self.hash = BlockHeader::compute_hash(
727 self.prev_hash,
728 &borsh::to_vec(&self.inner_lite).expect("Failed to serialize"),
729 &borsh::to_vec(&self.inner_rest).expect("Failed to serialize"),
730 );
731 }
732}
733
734impl BlockHeaderV6 {
735 pub fn init(&mut self) {
736 self.hash = BlockHeader::compute_hash(
737 self.prev_hash,
738 &borsh::to_vec(&self.inner_lite).expect("Failed to serialize"),
739 &borsh::to_vec(&self.inner_rest).expect("Failed to serialize"),
740 );
741 }
742}
743
744impl BlockHeaderV7 {
745 pub fn init(&mut self) {
746 self.hash = BlockHeader::compute_hash(
747 self.prev_hash,
748 &borsh::to_vec(&self.inner_lite).expect("Failed to serialize"),
749 &borsh::to_vec(&self.inner_rest).expect("Failed to serialize"),
750 );
751 }
752}
753
754enum SignatureSource<'a> {
756 #[allow(dead_code)]
760 Signer(&'a ValidatorSigner),
761 Signature(Signature),
763}
764
765#[derive(
768 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq, ProtocolSchema,
769)]
770pub enum BlockHeader {
771 BlockHeaderV1(BlockHeaderV1),
772 BlockHeaderV2(BlockHeaderV2),
773 BlockHeaderV3(BlockHeaderV3),
774 BlockHeaderV4(BlockHeaderV4),
775 BlockHeaderV5(BlockHeaderV5),
776 BlockHeaderV6(BlockHeaderV6),
777 BlockHeaderV7(BlockHeaderV7),
778}
779
780impl BlockHeader {
781 pub fn compute_inner_hash(inner_lite: &[u8], inner_rest: &[u8]) -> CryptoHash {
782 let hash_lite = hash(inner_lite);
783 let hash_rest = hash(inner_rest);
784 combine_hash(&hash_lite, &hash_rest)
785 }
786
787 pub fn compute_hash(prev_hash: CryptoHash, inner_lite: &[u8], inner_rest: &[u8]) -> CryptoHash {
788 let hash_inner = BlockHeader::compute_inner_hash(inner_lite, inner_rest);
789
790 combine_hash(&hash_inner, &prev_hash)
791 }
792
793 pub fn new(
795 current_protocol_version: ProtocolVersion,
796 latest_protocol_version: ProtocolVersion,
797 height: BlockHeight,
798 prev_hash: CryptoHash,
799 block_body_hash: CryptoHash,
800 prev_state_root: MerkleHash,
801 prev_chunk_outgoing_receipts_root: MerkleHash,
802 chunk_headers_root: MerkleHash,
803 chunk_tx_root: MerkleHash,
804 outcome_root: MerkleHash,
805 timestamp: u64,
806 random_value: CryptoHash,
807 prev_validator_proposals: Vec<ValidatorStake>,
808 chunk_mask: Vec<bool>,
809 block_ordinal: NumBlocks,
810 epoch_id: EpochId,
811 next_epoch_id: EpochId,
812 next_gas_price: Balance,
813 total_supply: Balance,
814 signer: &ValidatorSigner,
815 last_final_block: CryptoHash,
816 last_ds_final_block: CryptoHash,
817 epoch_sync_data_hash: Option<CryptoHash>,
818 approvals: Vec<Option<Box<Signature>>>,
819 next_bp_hash: CryptoHash,
820 block_merkle_root: CryptoHash,
821 prev_height: BlockHeight,
822 chunk_endorsements: Option<ChunkEndorsementsBitmap>,
823 shard_split: Option<(ShardId, AccountId)>,
824 prev_last_certified_block_epoch_id: Option<EpochId>,
825 spice_chunk_endorsement_stats: Option<Vec<SpiceChunkEndorsementStats>>,
826 ) -> Self {
827 Self::new_impl(
828 current_protocol_version,
829 latest_protocol_version,
830 height,
831 prev_hash,
832 block_body_hash,
833 prev_state_root,
834 prev_chunk_outgoing_receipts_root,
835 chunk_headers_root,
836 chunk_tx_root,
837 outcome_root,
838 timestamp,
839 random_value,
840 prev_validator_proposals,
841 chunk_mask,
842 block_ordinal,
843 epoch_id,
844 next_epoch_id,
845 next_gas_price,
846 total_supply,
847 SignatureSource::Signer(signer),
848 last_final_block,
849 last_ds_final_block,
850 epoch_sync_data_hash,
851 approvals,
852 next_bp_hash,
853 block_merkle_root,
854 prev_height,
855 chunk_endorsements,
856 shard_split,
857 prev_last_certified_block_epoch_id,
858 spice_chunk_endorsement_stats,
859 )
860 }
861
862 pub fn from_view(
864 expected_hash: &CryptoHash,
865 epoch_protocol_version: ProtocolVersion,
866 height: BlockHeight,
867 prev_hash: CryptoHash,
868 block_body_hash: CryptoHash,
869 prev_state_root: MerkleHash,
870 prev_chunk_outgoing_receipts_root: MerkleHash,
871 chunk_headers_root: MerkleHash,
872 chunk_tx_root: MerkleHash,
873 outcome_root: MerkleHash,
874 timestamp: u64,
875 random_value: CryptoHash,
876 prev_validator_proposals: Vec<ValidatorStake>,
877 chunk_mask: Vec<bool>,
878 block_ordinal: NumBlocks,
879 epoch_id: EpochId,
880 next_epoch_id: EpochId,
881 next_gas_price: Balance,
882 total_supply: Balance,
883 signature: Signature,
884 last_final_block: CryptoHash,
885 last_ds_final_block: CryptoHash,
886 epoch_sync_data_hash: Option<CryptoHash>,
887 approvals: Vec<Option<Box<Signature>>>,
888 next_bp_hash: CryptoHash,
889 block_merkle_root: CryptoHash,
890 prev_height: BlockHeight,
891 chunk_endorsements: Option<ChunkEndorsementsBitmap>,
892 shard_split: Option<(ShardId, AccountId)>,
893 prev_last_certified_block_epoch_id: Option<EpochId>,
894 spice_chunk_endorsement_stats: Option<Vec<SpiceChunkEndorsementStats>>,
895 ) -> Self {
896 let header = Self::new_impl(
897 epoch_protocol_version,
898 epoch_protocol_version,
899 height,
900 prev_hash,
901 block_body_hash,
902 prev_state_root,
903 prev_chunk_outgoing_receipts_root,
904 chunk_headers_root,
905 chunk_tx_root,
906 outcome_root,
907 timestamp,
908 random_value,
909 prev_validator_proposals,
910 chunk_mask,
911 block_ordinal,
912 epoch_id,
913 next_epoch_id,
914 next_gas_price,
915 total_supply,
916 SignatureSource::Signature(signature),
917 last_final_block,
918 last_ds_final_block,
919 epoch_sync_data_hash,
920 approvals,
921 next_bp_hash,
922 block_merkle_root,
923 prev_height,
924 chunk_endorsements,
925 shard_split,
926 prev_last_certified_block_epoch_id,
927 spice_chunk_endorsement_stats,
928 );
929 if header.hash() != expected_hash {
933 tracing::debug!(height, header_hash=?header.hash(), ?expected_hash, "hash of the created header does not match expected hash");
934 }
935 header
936 }
937
938 fn new_impl(
940 current_protocol_version: ProtocolVersion,
941 latest_protocol_version: ProtocolVersion,
942 height: BlockHeight,
943 prev_hash: CryptoHash,
944 block_body_hash: CryptoHash,
945 prev_state_root: MerkleHash,
946 prev_chunk_outgoing_receipts_root: MerkleHash,
947 chunk_headers_root: MerkleHash,
948 chunk_tx_root: MerkleHash,
949 outcome_root: MerkleHash,
950 timestamp: u64,
951 random_value: CryptoHash,
952 prev_validator_proposals: Vec<ValidatorStake>,
953 chunk_mask: Vec<bool>,
954 block_ordinal: NumBlocks,
955 epoch_id: EpochId,
956 next_epoch_id: EpochId,
957 next_gas_price: Balance,
958 total_supply: Balance,
959 signature_source: SignatureSource,
960 last_final_block: CryptoHash,
961 last_ds_final_block: CryptoHash,
962 epoch_sync_data_hash: Option<CryptoHash>,
963 approvals: Vec<Option<Box<Signature>>>,
964 next_bp_hash: CryptoHash,
965 block_merkle_root: CryptoHash,
966 prev_height: BlockHeight,
967 chunk_endorsements: Option<ChunkEndorsementsBitmap>,
968 shard_split: Option<(ShardId, AccountId)>,
969 prev_last_certified_block_epoch_id: Option<EpochId>,
970 spice_chunk_endorsement_stats: Option<Vec<SpiceChunkEndorsementStats>>,
971 ) -> Self {
972 let inner_lite = BlockHeaderInnerLite {
973 height,
974 epoch_id,
975 next_epoch_id,
976 prev_state_root,
977 prev_outcome_root: outcome_root,
978 timestamp,
979 next_bp_hash,
980 block_merkle_root,
981 };
982
983 let chunk_endorsements = chunk_endorsements.unwrap_or_else(|| {
984 panic!(
985 "BlockHeaderV5 (or newer) is enabled but chunk endorsement bitmap is not provided"
986 )
987 });
988
989 if ProtocolFeature::Spice.enabled(current_protocol_version) {
990 let prev_last_certified_block_epoch_id = prev_last_certified_block_epoch_id.expect(
991 "BlockHeaderV7 requires prev_last_certified_block_epoch_id when Spice is enabled",
992 );
993 let spice_chunk_endorsement_stats = spice_chunk_endorsement_stats.expect(
994 "BlockHeaderV7 requires spice_chunk_endorsement_stats when Spice is enabled",
995 );
996 let inner_rest = BlockHeaderInnerRestV7 {
997 block_body_hash,
998 prev_chunk_outgoing_receipts_root,
999 chunk_headers_root,
1000 chunk_tx_root,
1001 random_value,
1002 prev_validator_proposals,
1003 chunk_mask,
1004 next_gas_price,
1005 total_supply,
1006 last_final_block,
1007 last_ds_final_block,
1008 block_ordinal,
1009 prev_height,
1010 epoch_sync_data_hash,
1011 approvals,
1012 latest_protocol_version,
1013 chunk_endorsements,
1014 shard_split,
1015 prev_last_certified_block_epoch_id,
1016 spice_chunk_endorsement_stats,
1017 };
1018 let (hash, signature) =
1019 Self::compute_hash_and_sign(signature_source, prev_hash, &inner_lite, &inner_rest);
1020 Self::BlockHeaderV7(BlockHeaderV7 {
1021 prev_hash,
1022 inner_lite,
1023 inner_rest,
1024 signature,
1025 hash,
1026 })
1027 } else if ProtocolFeature::DynamicResharding.enabled(current_protocol_version) {
1028 let inner_rest = BlockHeaderInnerRestV6 {
1029 block_body_hash,
1030 prev_chunk_outgoing_receipts_root,
1031 chunk_headers_root,
1032 chunk_tx_root,
1033 random_value,
1034 prev_validator_proposals,
1035 chunk_mask,
1036 next_gas_price,
1037 block_ordinal,
1038 total_supply,
1039 last_final_block,
1040 last_ds_final_block,
1041 prev_height,
1042 epoch_sync_data_hash,
1043 approvals,
1044 latest_protocol_version,
1045 chunk_endorsements,
1046 shard_split,
1047 };
1048 let (hash, signature) =
1049 Self::compute_hash_and_sign(signature_source, prev_hash, &inner_lite, &inner_rest);
1050 Self::BlockHeaderV6(BlockHeaderV6 {
1051 prev_hash,
1052 inner_lite,
1053 inner_rest,
1054 signature,
1055 hash,
1056 })
1057 } else {
1058 #[allow(deprecated)]
1059 let inner_rest = BlockHeaderInnerRestV5 {
1060 block_body_hash,
1061 prev_chunk_outgoing_receipts_root,
1062 chunk_headers_root,
1063 chunk_tx_root,
1064 challenges_root: Default::default(),
1065 random_value,
1066 prev_validator_proposals,
1067 chunk_mask,
1068 next_gas_price,
1069 total_supply,
1070 challenges_result: vec![],
1071 last_final_block,
1072 last_ds_final_block,
1073 block_ordinal,
1074 prev_height,
1075 epoch_sync_data_hash,
1076 approvals,
1077 latest_protocol_version,
1078 chunk_endorsements,
1079 };
1080 let (hash, signature) =
1081 Self::compute_hash_and_sign(signature_source, prev_hash, &inner_lite, &inner_rest);
1082 Self::BlockHeaderV5(BlockHeaderV5 {
1083 prev_hash,
1084 inner_lite,
1085 inner_rest,
1086 signature,
1087 hash,
1088 })
1089 }
1090 }
1091
1092 fn compute_hash_and_sign<T>(
1097 signature_source: SignatureSource,
1098 prev_hash: CryptoHash,
1099 inner_lite: &BlockHeaderInnerLite,
1100 inner_rest: &T,
1101 ) -> (CryptoHash, Signature)
1102 where
1103 T: BorshSerialize + ?Sized,
1104 {
1105 let hash = BlockHeader::compute_hash(
1106 prev_hash,
1107 &borsh::to_vec(&inner_lite).expect("Failed to serialize"),
1108 &borsh::to_vec(&inner_rest).expect("Failed to serialize"),
1109 );
1110 match signature_source {
1111 SignatureSource::Signer(signer) => (hash, signer.sign_bytes(hash.as_ref())),
1112 SignatureSource::Signature(signature) => (hash, signature),
1113 }
1114 }
1115
1116 pub fn genesis(
1117 genesis_protocol_version: ProtocolVersion,
1118 height: BlockHeight,
1119 state_root: MerkleHash,
1120 block_body_hash: CryptoHash,
1121 prev_chunk_outgoing_receipts_root: MerkleHash,
1122 chunk_headers_root: MerkleHash,
1123 chunk_tx_root: MerkleHash,
1124 num_shards: u64,
1125 timestamp: Utc,
1126 initial_gas_price: Balance,
1127 initial_total_supply: Balance,
1128 next_bp_hash: CryptoHash,
1129 ) -> Self {
1130 let chunks_included = if height == 0 { num_shards } else { 0 };
1131 let genesis_prev_last_certified_block_epoch_id =
1132 if ProtocolFeature::Spice.enabled(genesis_protocol_version) {
1133 Some(EpochId::default())
1134 } else {
1135 None
1136 };
1137 let genesis_spice_chunk_endorsement_stats =
1138 if ProtocolFeature::Spice.enabled(genesis_protocol_version) {
1139 Some(Vec::new())
1140 } else {
1141 None
1142 };
1143 Self::new_impl(
1144 genesis_protocol_version,
1145 genesis_protocol_version,
1146 height,
1147 CryptoHash::default(), block_body_hash,
1149 state_root,
1150 prev_chunk_outgoing_receipts_root,
1151 chunk_headers_root,
1152 chunk_tx_root,
1153 CryptoHash::default(), timestamp.unix_timestamp_nanos() as u64,
1155 CryptoHash::default(), vec![], vec![true; chunks_included as usize], 1, EpochId::default(), EpochId::default(), initial_gas_price,
1162 initial_total_supply,
1163 SignatureSource::Signature(Signature::empty(KeyType::ED25519)),
1164 CryptoHash::default(), CryptoHash::default(), None, vec![], next_bp_hash,
1169 CryptoHash::default(), 0, Some(ChunkEndorsementsBitmap::genesis()),
1172 None, genesis_prev_last_certified_block_epoch_id,
1174 genesis_spice_chunk_endorsement_stats,
1175 )
1176 }
1177
1178 #[inline]
1179 pub fn is_genesis(&self) -> bool {
1180 self.prev_hash() == &CryptoHash::default()
1181 }
1182
1183 #[inline]
1184 pub fn hash(&self) -> &CryptoHash {
1185 match self {
1186 BlockHeader::BlockHeaderV1(header) => &header.hash,
1187 BlockHeader::BlockHeaderV2(header) => &header.hash,
1188 BlockHeader::BlockHeaderV3(header) => &header.hash,
1189 BlockHeader::BlockHeaderV4(header) => &header.hash,
1190 BlockHeader::BlockHeaderV5(header) => &header.hash,
1191 BlockHeader::BlockHeaderV6(header) => &header.hash,
1192 BlockHeader::BlockHeaderV7(header) => &header.hash,
1193 }
1194 }
1195
1196 #[inline]
1197 pub fn prev_hash(&self) -> &CryptoHash {
1198 match self {
1199 BlockHeader::BlockHeaderV1(header) => &header.prev_hash,
1200 BlockHeader::BlockHeaderV2(header) => &header.prev_hash,
1201 BlockHeader::BlockHeaderV3(header) => &header.prev_hash,
1202 BlockHeader::BlockHeaderV4(header) => &header.prev_hash,
1203 BlockHeader::BlockHeaderV5(header) => &header.prev_hash,
1204 BlockHeader::BlockHeaderV6(header) => &header.prev_hash,
1205 BlockHeader::BlockHeaderV7(header) => &header.prev_hash,
1206 }
1207 }
1208
1209 #[inline]
1210 pub fn signature(&self) -> &Signature {
1211 match self {
1212 BlockHeader::BlockHeaderV1(header) => &header.signature,
1213 BlockHeader::BlockHeaderV2(header) => &header.signature,
1214 BlockHeader::BlockHeaderV3(header) => &header.signature,
1215 BlockHeader::BlockHeaderV4(header) => &header.signature,
1216 BlockHeader::BlockHeaderV5(header) => &header.signature,
1217 BlockHeader::BlockHeaderV6(header) => &header.signature,
1218 BlockHeader::BlockHeaderV7(header) => &header.signature,
1219 }
1220 }
1221
1222 #[inline]
1223 pub fn height(&self) -> BlockHeight {
1224 match self {
1225 BlockHeader::BlockHeaderV1(header) => header.inner_lite.height,
1226 BlockHeader::BlockHeaderV2(header) => header.inner_lite.height,
1227 BlockHeader::BlockHeaderV3(header) => header.inner_lite.height,
1228 BlockHeader::BlockHeaderV4(header) => header.inner_lite.height,
1229 BlockHeader::BlockHeaderV5(header) => header.inner_lite.height,
1230 BlockHeader::BlockHeaderV6(header) => header.inner_lite.height,
1231 BlockHeader::BlockHeaderV7(header) => header.inner_lite.height,
1232 }
1233 }
1234
1235 #[inline]
1236 pub fn prev_height(&self) -> Option<BlockHeight> {
1237 match self {
1238 BlockHeader::BlockHeaderV1(_) => None,
1239 BlockHeader::BlockHeaderV2(_) => None,
1240 BlockHeader::BlockHeaderV3(header) => Some(header.inner_rest.prev_height),
1241 BlockHeader::BlockHeaderV4(header) => Some(header.inner_rest.prev_height),
1242 BlockHeader::BlockHeaderV5(header) => Some(header.inner_rest.prev_height),
1243 BlockHeader::BlockHeaderV6(header) => Some(header.inner_rest.prev_height),
1244 BlockHeader::BlockHeaderV7(header) => Some(header.inner_rest.prev_height),
1245 }
1246 }
1247
1248 #[inline]
1249 pub fn epoch_id(&self) -> &EpochId {
1250 match self {
1251 BlockHeader::BlockHeaderV1(header) => &header.inner_lite.epoch_id,
1252 BlockHeader::BlockHeaderV2(header) => &header.inner_lite.epoch_id,
1253 BlockHeader::BlockHeaderV3(header) => &header.inner_lite.epoch_id,
1254 BlockHeader::BlockHeaderV4(header) => &header.inner_lite.epoch_id,
1255 BlockHeader::BlockHeaderV5(header) => &header.inner_lite.epoch_id,
1256 BlockHeader::BlockHeaderV6(header) => &header.inner_lite.epoch_id,
1257 BlockHeader::BlockHeaderV7(header) => &header.inner_lite.epoch_id,
1258 }
1259 }
1260
1261 #[inline]
1262 pub fn next_epoch_id(&self) -> &EpochId {
1263 match self {
1264 BlockHeader::BlockHeaderV1(header) => &header.inner_lite.next_epoch_id,
1265 BlockHeader::BlockHeaderV2(header) => &header.inner_lite.next_epoch_id,
1266 BlockHeader::BlockHeaderV3(header) => &header.inner_lite.next_epoch_id,
1267 BlockHeader::BlockHeaderV4(header) => &header.inner_lite.next_epoch_id,
1268 BlockHeader::BlockHeaderV5(header) => &header.inner_lite.next_epoch_id,
1269 BlockHeader::BlockHeaderV6(header) => &header.inner_lite.next_epoch_id,
1270 BlockHeader::BlockHeaderV7(header) => &header.inner_lite.next_epoch_id,
1271 }
1272 }
1273
1274 #[inline]
1275 pub fn prev_state_root(&self) -> &MerkleHash {
1276 match self {
1277 BlockHeader::BlockHeaderV1(header) => &header.inner_lite.prev_state_root,
1278 BlockHeader::BlockHeaderV2(header) => &header.inner_lite.prev_state_root,
1279 BlockHeader::BlockHeaderV3(header) => &header.inner_lite.prev_state_root,
1280 BlockHeader::BlockHeaderV4(header) => &header.inner_lite.prev_state_root,
1281 BlockHeader::BlockHeaderV5(header) => &header.inner_lite.prev_state_root,
1282 BlockHeader::BlockHeaderV6(header) => &header.inner_lite.prev_state_root,
1283 BlockHeader::BlockHeaderV7(header) => &header.inner_lite.prev_state_root,
1284 }
1285 }
1286
1287 #[inline]
1288 pub fn prev_chunk_outgoing_receipts_root(&self) -> &MerkleHash {
1289 match self {
1290 BlockHeader::BlockHeaderV1(header) => {
1291 &header.inner_rest.prev_chunk_outgoing_receipts_root
1292 }
1293 BlockHeader::BlockHeaderV2(header) => {
1294 &header.inner_rest.prev_chunk_outgoing_receipts_root
1295 }
1296 BlockHeader::BlockHeaderV3(header) => {
1297 &header.inner_rest.prev_chunk_outgoing_receipts_root
1298 }
1299 BlockHeader::BlockHeaderV4(header) => {
1300 &header.inner_rest.prev_chunk_outgoing_receipts_root
1301 }
1302 BlockHeader::BlockHeaderV5(header) => {
1303 &header.inner_rest.prev_chunk_outgoing_receipts_root
1304 }
1305 BlockHeader::BlockHeaderV6(header) => {
1306 &header.inner_rest.prev_chunk_outgoing_receipts_root
1307 }
1308 BlockHeader::BlockHeaderV7(header) => {
1309 &header.inner_rest.prev_chunk_outgoing_receipts_root
1310 }
1311 }
1312 }
1313
1314 #[inline]
1315 pub fn chunk_headers_root(&self) -> &MerkleHash {
1316 match self {
1317 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.chunk_headers_root,
1318 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.chunk_headers_root,
1319 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.chunk_headers_root,
1320 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.chunk_headers_root,
1321 BlockHeader::BlockHeaderV5(header) => &header.inner_rest.chunk_headers_root,
1322 BlockHeader::BlockHeaderV6(header) => &header.inner_rest.chunk_headers_root,
1323 BlockHeader::BlockHeaderV7(header) => &header.inner_rest.chunk_headers_root,
1324 }
1325 }
1326
1327 #[inline]
1328 pub fn chunk_tx_root(&self) -> &MerkleHash {
1329 match self {
1330 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.chunk_tx_root,
1331 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.chunk_tx_root,
1332 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.chunk_tx_root,
1333 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.chunk_tx_root,
1334 BlockHeader::BlockHeaderV5(header) => &header.inner_rest.chunk_tx_root,
1335 BlockHeader::BlockHeaderV6(header) => &header.inner_rest.chunk_tx_root,
1336 BlockHeader::BlockHeaderV7(header) => &header.inner_rest.chunk_tx_root,
1337 }
1338 }
1339
1340 pub fn chunks_included(&self) -> u64 {
1341 let mask = match self {
1342 BlockHeader::BlockHeaderV1(header) => return header.inner_rest.chunks_included,
1343 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.chunk_mask,
1344 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.chunk_mask,
1345 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.chunk_mask,
1346 BlockHeader::BlockHeaderV5(header) => &header.inner_rest.chunk_mask,
1347 BlockHeader::BlockHeaderV6(header) => &header.inner_rest.chunk_mask,
1348 BlockHeader::BlockHeaderV7(header) => &header.inner_rest.chunk_mask,
1349 };
1350 mask.iter().map(|&x| u64::from(x)).sum::<u64>()
1351 }
1352
1353 #[inline]
1354 pub fn outcome_root(&self) -> &MerkleHash {
1355 match self {
1356 BlockHeader::BlockHeaderV1(header) => &header.inner_lite.prev_outcome_root,
1357 BlockHeader::BlockHeaderV2(header) => &header.inner_lite.prev_outcome_root,
1358 BlockHeader::BlockHeaderV3(header) => &header.inner_lite.prev_outcome_root,
1359 BlockHeader::BlockHeaderV4(header) => &header.inner_lite.prev_outcome_root,
1360 BlockHeader::BlockHeaderV5(header) => &header.inner_lite.prev_outcome_root,
1361 BlockHeader::BlockHeaderV6(header) => &header.inner_lite.prev_outcome_root,
1362 BlockHeader::BlockHeaderV7(header) => &header.inner_lite.prev_outcome_root,
1363 }
1364 }
1365
1366 #[inline]
1367 pub fn block_body_hash(&self) -> Option<CryptoHash> {
1368 match self {
1369 BlockHeader::BlockHeaderV1(_) => None,
1370 BlockHeader::BlockHeaderV2(_) => None,
1371 BlockHeader::BlockHeaderV3(_) => None,
1372 BlockHeader::BlockHeaderV4(header) => Some(header.inner_rest.block_body_hash),
1373 BlockHeader::BlockHeaderV5(header) => Some(header.inner_rest.block_body_hash),
1374 BlockHeader::BlockHeaderV6(header) => Some(header.inner_rest.block_body_hash),
1375 BlockHeader::BlockHeaderV7(header) => Some(header.inner_rest.block_body_hash),
1376 }
1377 }
1378
1379 #[inline]
1380 pub fn raw_timestamp(&self) -> u64 {
1381 match self {
1382 BlockHeader::BlockHeaderV1(header) => header.inner_lite.timestamp,
1383 BlockHeader::BlockHeaderV2(header) => header.inner_lite.timestamp,
1384 BlockHeader::BlockHeaderV3(header) => header.inner_lite.timestamp,
1385 BlockHeader::BlockHeaderV4(header) => header.inner_lite.timestamp,
1386 BlockHeader::BlockHeaderV5(header) => header.inner_lite.timestamp,
1387 BlockHeader::BlockHeaderV6(header) => header.inner_lite.timestamp,
1388 BlockHeader::BlockHeaderV7(header) => header.inner_lite.timestamp,
1389 }
1390 }
1391
1392 #[inline]
1393 pub fn prev_validator_proposals(&self) -> ValidatorStakeIter<'_> {
1394 match self {
1395 BlockHeader::BlockHeaderV1(header) => {
1396 ValidatorStakeIter::v1(&header.inner_rest.prev_validator_proposals)
1397 }
1398 BlockHeader::BlockHeaderV2(header) => {
1399 ValidatorStakeIter::v1(&header.inner_rest.prev_validator_proposals)
1400 }
1401 BlockHeader::BlockHeaderV3(header) => {
1402 ValidatorStakeIter::new(&header.inner_rest.prev_validator_proposals)
1403 }
1404 BlockHeader::BlockHeaderV4(header) => {
1405 ValidatorStakeIter::new(&header.inner_rest.prev_validator_proposals)
1406 }
1407 BlockHeader::BlockHeaderV5(header) => {
1408 ValidatorStakeIter::new(&header.inner_rest.prev_validator_proposals)
1409 }
1410 BlockHeader::BlockHeaderV6(header) => {
1411 ValidatorStakeIter::new(&header.inner_rest.prev_validator_proposals)
1412 }
1413 BlockHeader::BlockHeaderV7(header) => {
1414 ValidatorStakeIter::new(&header.inner_rest.prev_validator_proposals)
1415 }
1416 }
1417 }
1418
1419 #[inline]
1420 pub fn chunk_mask(&self) -> &[bool] {
1421 match self {
1422 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.chunk_mask,
1423 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.chunk_mask,
1424 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.chunk_mask,
1425 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.chunk_mask,
1426 BlockHeader::BlockHeaderV5(header) => &header.inner_rest.chunk_mask,
1427 BlockHeader::BlockHeaderV6(header) => &header.inner_rest.chunk_mask,
1428 BlockHeader::BlockHeaderV7(header) => &header.inner_rest.chunk_mask,
1429 }
1430 }
1431
1432 #[inline]
1433 pub fn block_ordinal(&self) -> NumBlocks {
1434 match self {
1435 BlockHeader::BlockHeaderV1(_) => 0, BlockHeader::BlockHeaderV2(_) => 0, BlockHeader::BlockHeaderV3(header) => header.inner_rest.block_ordinal,
1438 BlockHeader::BlockHeaderV4(header) => header.inner_rest.block_ordinal,
1439 BlockHeader::BlockHeaderV5(header) => header.inner_rest.block_ordinal,
1440 BlockHeader::BlockHeaderV6(header) => header.inner_rest.block_ordinal,
1441 BlockHeader::BlockHeaderV7(header) => header.inner_rest.block_ordinal,
1442 }
1443 }
1444
1445 #[inline]
1446 pub fn next_gas_price(&self) -> Balance {
1447 match self {
1448 BlockHeader::BlockHeaderV1(header) => header.inner_rest.next_gas_price,
1449 BlockHeader::BlockHeaderV2(header) => header.inner_rest.next_gas_price,
1450 BlockHeader::BlockHeaderV3(header) => header.inner_rest.next_gas_price,
1451 BlockHeader::BlockHeaderV4(header) => header.inner_rest.next_gas_price,
1452 BlockHeader::BlockHeaderV5(header) => header.inner_rest.next_gas_price,
1453 BlockHeader::BlockHeaderV6(header) => header.inner_rest.next_gas_price,
1454 BlockHeader::BlockHeaderV7(header) => header.inner_rest.next_gas_price,
1455 }
1456 }
1457
1458 #[inline]
1459 pub fn total_supply(&self) -> Balance {
1460 match self {
1461 BlockHeader::BlockHeaderV1(header) => header.inner_rest.total_supply,
1462 BlockHeader::BlockHeaderV2(header) => header.inner_rest.total_supply,
1463 BlockHeader::BlockHeaderV3(header) => header.inner_rest.total_supply,
1464 BlockHeader::BlockHeaderV4(header) => header.inner_rest.total_supply,
1465 BlockHeader::BlockHeaderV5(header) => header.inner_rest.total_supply,
1466 BlockHeader::BlockHeaderV6(header) => header.inner_rest.total_supply,
1467 BlockHeader::BlockHeaderV7(header) => header.inner_rest.total_supply,
1468 }
1469 }
1470
1471 #[inline]
1472 pub fn random_value(&self) -> &CryptoHash {
1473 match self {
1474 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.random_value,
1475 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.random_value,
1476 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.random_value,
1477 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.random_value,
1478 BlockHeader::BlockHeaderV5(header) => &header.inner_rest.random_value,
1479 BlockHeader::BlockHeaderV6(header) => &header.inner_rest.random_value,
1480 BlockHeader::BlockHeaderV7(header) => &header.inner_rest.random_value,
1481 }
1482 }
1483
1484 #[inline]
1485 pub fn last_final_block(&self) -> &CryptoHash {
1486 match self {
1487 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.last_final_block,
1488 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.last_final_block,
1489 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.last_final_block,
1490 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.last_final_block,
1491 BlockHeader::BlockHeaderV5(header) => &header.inner_rest.last_final_block,
1492 BlockHeader::BlockHeaderV6(header) => &header.inner_rest.last_final_block,
1493 BlockHeader::BlockHeaderV7(header) => &header.inner_rest.last_final_block,
1494 }
1495 }
1496
1497 #[inline]
1498 pub fn last_final_block_for_height(&self, target_height: BlockHeight) -> &CryptoHash {
1501 if target_height == self.height() + 1 && self.last_ds_final_block() == self.prev_hash() {
1502 self.prev_hash()
1503 } else {
1504 self.last_final_block()
1505 }
1506 }
1507
1508 #[inline]
1509 pub fn last_ds_final_block(&self) -> &CryptoHash {
1510 match self {
1511 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.last_ds_final_block,
1512 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.last_ds_final_block,
1513 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.last_ds_final_block,
1514 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.last_ds_final_block,
1515 BlockHeader::BlockHeaderV5(header) => &header.inner_rest.last_ds_final_block,
1516 BlockHeader::BlockHeaderV6(header) => &header.inner_rest.last_ds_final_block,
1517 BlockHeader::BlockHeaderV7(header) => &header.inner_rest.last_ds_final_block,
1518 }
1519 }
1520
1521 #[inline]
1522 pub fn next_bp_hash(&self) -> &CryptoHash {
1523 match self {
1524 BlockHeader::BlockHeaderV1(header) => &header.inner_lite.next_bp_hash,
1525 BlockHeader::BlockHeaderV2(header) => &header.inner_lite.next_bp_hash,
1526 BlockHeader::BlockHeaderV3(header) => &header.inner_lite.next_bp_hash,
1527 BlockHeader::BlockHeaderV4(header) => &header.inner_lite.next_bp_hash,
1528 BlockHeader::BlockHeaderV5(header) => &header.inner_lite.next_bp_hash,
1529 BlockHeader::BlockHeaderV6(header) => &header.inner_lite.next_bp_hash,
1530 BlockHeader::BlockHeaderV7(header) => &header.inner_lite.next_bp_hash,
1531 }
1532 }
1533
1534 #[inline]
1535 pub fn block_merkle_root(&self) -> &CryptoHash {
1536 match self {
1537 BlockHeader::BlockHeaderV1(header) => &header.inner_lite.block_merkle_root,
1538 BlockHeader::BlockHeaderV2(header) => &header.inner_lite.block_merkle_root,
1539 BlockHeader::BlockHeaderV3(header) => &header.inner_lite.block_merkle_root,
1540 BlockHeader::BlockHeaderV4(header) => &header.inner_lite.block_merkle_root,
1541 BlockHeader::BlockHeaderV5(header) => &header.inner_lite.block_merkle_root,
1542 BlockHeader::BlockHeaderV6(header) => &header.inner_lite.block_merkle_root,
1543 BlockHeader::BlockHeaderV7(header) => &header.inner_lite.block_merkle_root,
1544 }
1545 }
1546
1547 #[inline]
1548 pub fn epoch_sync_data_hash(&self) -> Option<CryptoHash> {
1549 match self {
1550 BlockHeader::BlockHeaderV1(_) => None,
1551 BlockHeader::BlockHeaderV2(_) => None,
1552 BlockHeader::BlockHeaderV3(header) => header.inner_rest.epoch_sync_data_hash,
1553 BlockHeader::BlockHeaderV4(header) => header.inner_rest.epoch_sync_data_hash,
1554 BlockHeader::BlockHeaderV5(header) => header.inner_rest.epoch_sync_data_hash,
1555 BlockHeader::BlockHeaderV6(header) => header.inner_rest.epoch_sync_data_hash,
1556 BlockHeader::BlockHeaderV7(header) => header.inner_rest.epoch_sync_data_hash,
1557 }
1558 }
1559
1560 #[inline]
1561 pub fn approvals(&self) -> &[Option<Box<Signature>>] {
1562 match self {
1563 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.approvals,
1564 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.approvals,
1565 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.approvals,
1566 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.approvals,
1567 BlockHeader::BlockHeaderV5(header) => &header.inner_rest.approvals,
1568 BlockHeader::BlockHeaderV6(header) => &header.inner_rest.approvals,
1569 BlockHeader::BlockHeaderV7(header) => &header.inner_rest.approvals,
1570 }
1571 }
1572
1573 pub fn verify_block_producer(&self, public_key: &PublicKey) -> bool {
1575 self.signature().verify(self.hash().as_ref(), public_key)
1576 }
1577
1578 pub fn timestamp(&self) -> Utc {
1579 Utc::from_unix_timestamp_nanos(self.raw_timestamp() as i128).unwrap()
1580 }
1581
1582 pub fn num_approvals(&self) -> u64 {
1583 self.approvals().iter().filter(|x| x.is_some()).count() as u64
1584 }
1585
1586 pub fn verify_chunks_included(&self) -> bool {
1587 match self {
1588 BlockHeader::BlockHeaderV1(header) => {
1589 header.inner_rest.chunk_mask.iter().map(|&x| u64::from(x)).sum::<u64>()
1590 == header.inner_rest.chunks_included
1591 }
1592 BlockHeader::BlockHeaderV2(_header) => true,
1593 BlockHeader::BlockHeaderV3(_header) => true,
1594 BlockHeader::BlockHeaderV4(_header) => true,
1595 BlockHeader::BlockHeaderV5(_header) => true,
1596 BlockHeader::BlockHeaderV6(_header) => true,
1597 BlockHeader::BlockHeaderV7(_header) => true,
1598 }
1599 }
1600
1601 #[inline]
1602 pub fn latest_protocol_version(&self) -> u32 {
1603 match self {
1604 BlockHeader::BlockHeaderV1(header) => header.inner_rest.latest_protocol_version,
1605 BlockHeader::BlockHeaderV2(header) => header.inner_rest.latest_protocol_version,
1606 BlockHeader::BlockHeaderV3(header) => header.inner_rest.latest_protocol_version,
1607 BlockHeader::BlockHeaderV4(header) => header.inner_rest.latest_protocol_version,
1608 BlockHeader::BlockHeaderV5(header) => header.inner_rest.latest_protocol_version,
1609 BlockHeader::BlockHeaderV6(header) => header.inner_rest.latest_protocol_version,
1610 BlockHeader::BlockHeaderV7(header) => header.inner_rest.latest_protocol_version,
1611 }
1612 }
1613
1614 pub fn inner_lite_bytes(&self) -> Vec<u8> {
1615 match self {
1616 BlockHeader::BlockHeaderV1(header) => {
1617 borsh::to_vec(&header.inner_lite).expect("Failed to serialize")
1618 }
1619 BlockHeader::BlockHeaderV2(header) => {
1620 borsh::to_vec(&header.inner_lite).expect("Failed to serialize")
1621 }
1622 BlockHeader::BlockHeaderV3(header) => {
1623 borsh::to_vec(&header.inner_lite).expect("Failed to serialize")
1624 }
1625 BlockHeader::BlockHeaderV4(header) => {
1626 borsh::to_vec(&header.inner_lite).expect("Failed to serialize")
1627 }
1628 BlockHeader::BlockHeaderV5(header) => {
1629 borsh::to_vec(&header.inner_lite).expect("Failed to serialize")
1630 }
1631 BlockHeader::BlockHeaderV6(header) => {
1632 borsh::to_vec(&header.inner_lite).expect("Failed to serialize")
1633 }
1634 BlockHeader::BlockHeaderV7(header) => {
1635 borsh::to_vec(&header.inner_lite).expect("Failed to serialize")
1636 }
1637 }
1638 }
1639
1640 pub fn inner_rest_bytes(&self) -> Vec<u8> {
1641 match self {
1642 BlockHeader::BlockHeaderV1(header) => {
1643 borsh::to_vec(&header.inner_rest).expect("Failed to serialize")
1644 }
1645 BlockHeader::BlockHeaderV2(header) => {
1646 borsh::to_vec(&header.inner_rest).expect("Failed to serialize")
1647 }
1648 BlockHeader::BlockHeaderV3(header) => {
1649 borsh::to_vec(&header.inner_rest).expect("Failed to serialize")
1650 }
1651 BlockHeader::BlockHeaderV4(header) => {
1652 borsh::to_vec(&header.inner_rest).expect("Failed to serialize")
1653 }
1654 BlockHeader::BlockHeaderV5(header) => {
1655 borsh::to_vec(&header.inner_rest).expect("Failed to serialize")
1656 }
1657 BlockHeader::BlockHeaderV6(header) => {
1658 borsh::to_vec(&header.inner_rest).expect("Failed to serialize")
1659 }
1660 BlockHeader::BlockHeaderV7(header) => {
1661 borsh::to_vec(&header.inner_rest).expect("Failed to serialize")
1662 }
1663 }
1664 }
1665
1666 #[inline]
1667 pub fn chunk_endorsements(&self) -> Option<&ChunkEndorsementsBitmap> {
1668 match self {
1669 BlockHeader::BlockHeaderV1(_) => None,
1670 BlockHeader::BlockHeaderV2(_) => None,
1671 BlockHeader::BlockHeaderV3(_) => None,
1672 BlockHeader::BlockHeaderV4(_) => None,
1673 BlockHeader::BlockHeaderV5(header) => Some(&header.inner_rest.chunk_endorsements),
1674 BlockHeader::BlockHeaderV6(header) => Some(&header.inner_rest.chunk_endorsements),
1675 BlockHeader::BlockHeaderV7(header) => Some(&header.inner_rest.chunk_endorsements),
1676 }
1677 }
1678
1679 #[inline]
1680 pub fn inner_lite(&self) -> &BlockHeaderInnerLite {
1681 match self {
1682 BlockHeader::BlockHeaderV1(header) => &header.inner_lite,
1683 BlockHeader::BlockHeaderV2(header) => &header.inner_lite,
1684 BlockHeader::BlockHeaderV3(header) => &header.inner_lite,
1685 BlockHeader::BlockHeaderV4(header) => &header.inner_lite,
1686 BlockHeader::BlockHeaderV5(header) => &header.inner_lite,
1687 BlockHeader::BlockHeaderV6(header) => &header.inner_lite,
1688 BlockHeader::BlockHeaderV7(header) => &header.inner_lite,
1689 }
1690 }
1691
1692 pub fn challenges_present(&self) -> bool {
1695 #[allow(deprecated)]
1696 let (challenges_root, challenges_result) = match self {
1697 Self::BlockHeaderV1(header) => {
1698 (&header.inner_rest.challenges_root, &header.inner_rest.challenges_result)
1699 }
1700 Self::BlockHeaderV2(header) => {
1701 (&header.inner_rest.challenges_root, &header.inner_rest.challenges_result)
1702 }
1703 Self::BlockHeaderV3(header) => {
1704 (&header.inner_rest.challenges_root, &header.inner_rest.challenges_result)
1705 }
1706 Self::BlockHeaderV4(header) => {
1707 (&header.inner_rest.challenges_root, &header.inner_rest.challenges_result)
1708 }
1709 Self::BlockHeaderV5(header) => {
1710 (&header.inner_rest.challenges_root, &header.inner_rest.challenges_result)
1711 }
1712 Self::BlockHeaderV6(_) => return false,
1713 Self::BlockHeaderV7(_) => return false,
1714 };
1715
1716 !challenges_result.is_empty() || challenges_root != &MerkleHash::default()
1717 }
1718
1719 #[inline]
1723 pub fn shard_split(&self) -> Option<&(ShardId, AccountId)> {
1724 match self {
1725 BlockHeader::BlockHeaderV1(_) => None,
1726 BlockHeader::BlockHeaderV2(_) => None,
1727 BlockHeader::BlockHeaderV3(_) => None,
1728 BlockHeader::BlockHeaderV4(_) => None,
1729 BlockHeader::BlockHeaderV5(_) => None,
1730 BlockHeader::BlockHeaderV6(header) => header.inner_rest.shard_split.as_ref(),
1731 BlockHeader::BlockHeaderV7(header) => header.inner_rest.shard_split.as_ref(),
1732 }
1733 }
1734
1735 #[inline]
1738 pub fn prev_last_certified_block_epoch_id(&self) -> Option<&EpochId> {
1739 match self {
1740 BlockHeader::BlockHeaderV1(_)
1741 | BlockHeader::BlockHeaderV2(_)
1742 | BlockHeader::BlockHeaderV3(_)
1743 | BlockHeader::BlockHeaderV4(_)
1744 | BlockHeader::BlockHeaderV5(_)
1745 | BlockHeader::BlockHeaderV6(_) => None,
1746 BlockHeader::BlockHeaderV7(header) => {
1747 Some(&header.inner_rest.prev_last_certified_block_epoch_id)
1748 }
1749 }
1750 }
1751
1752 #[inline]
1755 pub fn spice_chunk_endorsement_stats(&self) -> Option<&[SpiceChunkEndorsementStats]> {
1756 match self {
1757 BlockHeader::BlockHeaderV1(_)
1758 | BlockHeader::BlockHeaderV2(_)
1759 | BlockHeader::BlockHeaderV3(_)
1760 | BlockHeader::BlockHeaderV4(_)
1761 | BlockHeader::BlockHeaderV5(_)
1762 | BlockHeader::BlockHeaderV6(_) => None,
1763 BlockHeader::BlockHeaderV7(header) => {
1764 Some(&header.inner_rest.spice_chunk_endorsement_stats)
1765 }
1766 }
1767 }
1768
1769 #[inline]
1771 pub fn is_spice(&self) -> bool {
1772 match self {
1773 BlockHeader::BlockHeaderV1(_)
1774 | BlockHeader::BlockHeaderV2(_)
1775 | BlockHeader::BlockHeaderV3(_)
1776 | BlockHeader::BlockHeaderV4(_)
1777 | BlockHeader::BlockHeaderV5(_)
1778 | BlockHeader::BlockHeaderV6(_) => false,
1779 BlockHeader::BlockHeaderV7(_) => true,
1780 }
1781 }
1782}
1783
1784pub fn compute_bp_hash_from_validator_stakes(
1785 validator_stakes: &Vec<ValidatorStake>,
1786 use_versioned_bp_hash_format: bool,
1787) -> CryptoHash {
1788 if use_versioned_bp_hash_format {
1789 CryptoHash::hash_borsh_iter(validator_stakes)
1790 } else {
1791 let stakes = validator_stakes.into_iter().map(|stake| stake.clone().into_v1());
1792 CryptoHash::hash_borsh_iter(stakes)
1793 }
1794}