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::{AccountId, Balance, BlockHeight, EpochId, MerkleHash, NumBlocks};
8use crate::validator_signer::ValidatorSigner;
9use crate::version::ProtocolVersion;
10use borsh::{BorshDeserialize, BorshSerialize};
11use near_crypto::{KeyType, PublicKey, Signature};
12use near_schema_checker_lib::ProtocolSchema;
13use near_time::Utc;
14
15#[derive(
16 BorshSerialize,
17 BorshDeserialize,
18 serde::Serialize,
19 Debug,
20 Clone,
21 Eq,
22 PartialEq,
23 Default,
24 ProtocolSchema,
25)]
26pub struct BlockHeaderInnerLite {
27 pub height: BlockHeight,
29 pub epoch_id: EpochId,
32 pub next_epoch_id: EpochId,
33 pub prev_state_root: MerkleHash,
35 pub prev_outcome_root: MerkleHash,
37 pub timestamp: u64,
39 pub next_bp_hash: CryptoHash,
41 pub block_merkle_root: CryptoHash,
43}
44
45#[derive(
46 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq, ProtocolSchema,
47)]
48pub struct BlockHeaderInnerRest {
49 pub prev_chunk_outgoing_receipts_root: MerkleHash,
51 pub chunk_headers_root: MerkleHash,
53 pub chunk_tx_root: MerkleHash,
55 pub chunks_included: u64,
57 #[deprecated]
59 pub challenges_root: MerkleHash,
60 pub random_value: CryptoHash,
62 pub prev_validator_proposals: Vec<ValidatorStakeV1>,
64 pub chunk_mask: Vec<bool>,
66 pub next_gas_price: Balance,
68 pub total_supply: Balance,
70 #[deprecated]
72 pub challenges_result: Vec<SlashedValidator>,
73
74 pub last_final_block: CryptoHash,
76 pub last_ds_final_block: CryptoHash,
78
79 pub approvals: Vec<Option<Box<Signature>>>,
81
82 pub latest_protocol_version: ProtocolVersion,
84}
85
86#[derive(
88 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq, ProtocolSchema,
89)]
90pub struct BlockHeaderInnerRestV2 {
91 pub prev_chunk_outgoing_receipts_root: MerkleHash,
93 pub chunk_headers_root: MerkleHash,
95 pub chunk_tx_root: MerkleHash,
97 #[deprecated]
99 pub challenges_root: MerkleHash,
100 pub random_value: CryptoHash,
102 pub prev_validator_proposals: Vec<ValidatorStakeV1>,
104 pub chunk_mask: Vec<bool>,
106 pub next_gas_price: Balance,
108 pub total_supply: Balance,
110 #[deprecated]
112 pub challenges_result: Vec<SlashedValidator>,
113
114 pub last_final_block: CryptoHash,
116 pub last_ds_final_block: CryptoHash,
118
119 pub approvals: Vec<Option<Box<Signature>>>,
121
122 pub latest_protocol_version: ProtocolVersion,
124}
125
126#[derive(
131 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq, ProtocolSchema,
132)]
133pub struct BlockHeaderInnerRestV3 {
134 pub prev_chunk_outgoing_receipts_root: MerkleHash,
136 pub chunk_headers_root: MerkleHash,
138 pub chunk_tx_root: MerkleHash,
140 #[deprecated]
142 pub challenges_root: MerkleHash,
143 pub random_value: CryptoHash,
145 pub prev_validator_proposals: Vec<ValidatorStake>,
147 pub chunk_mask: Vec<bool>,
149 pub next_gas_price: Balance,
151 pub total_supply: Balance,
153 #[deprecated]
155 pub challenges_result: Vec<SlashedValidator>,
156
157 pub last_final_block: CryptoHash,
159 pub last_ds_final_block: CryptoHash,
161
162 pub block_ordinal: NumBlocks,
164
165 pub prev_height: BlockHeight,
166
167 pub epoch_sync_data_hash: Option<CryptoHash>,
168
169 pub approvals: Vec<Option<Box<Signature>>>,
171
172 pub latest_protocol_version: ProtocolVersion,
174}
175
176#[derive(
178 BorshSerialize,
179 BorshDeserialize,
180 serde::Serialize,
181 Debug,
182 Clone,
183 Eq,
184 PartialEq,
185 Default,
186 ProtocolSchema,
187)]
188pub struct BlockHeaderInnerRestV4 {
189 pub block_body_hash: CryptoHash,
191 pub prev_chunk_outgoing_receipts_root: MerkleHash,
193 pub chunk_headers_root: MerkleHash,
195 pub chunk_tx_root: MerkleHash,
197 #[deprecated]
199 pub challenges_root: MerkleHash,
200 pub random_value: CryptoHash,
202 pub prev_validator_proposals: Vec<ValidatorStake>,
204 pub chunk_mask: Vec<bool>,
206 pub next_gas_price: Balance,
208 pub total_supply: Balance,
210 #[deprecated]
212 pub challenges_result: Vec<SlashedValidator>,
213
214 pub last_final_block: CryptoHash,
216 pub last_ds_final_block: CryptoHash,
218
219 pub block_ordinal: NumBlocks,
221
222 pub prev_height: BlockHeight,
223
224 pub epoch_sync_data_hash: Option<CryptoHash>,
225
226 pub approvals: Vec<Option<Box<Signature>>>,
228
229 pub latest_protocol_version: ProtocolVersion,
231}
232
233#[derive(
235 BorshSerialize,
236 BorshDeserialize,
237 serde::Serialize,
238 Debug,
239 Clone,
240 Eq,
241 PartialEq,
242 Default,
243 ProtocolSchema,
244)]
245pub struct BlockHeaderInnerRestV5 {
246 pub block_body_hash: CryptoHash,
248 pub prev_chunk_outgoing_receipts_root: MerkleHash,
250 pub chunk_headers_root: MerkleHash,
252 pub chunk_tx_root: MerkleHash,
254 #[deprecated]
256 pub challenges_root: MerkleHash,
257 pub random_value: CryptoHash,
259 pub prev_validator_proposals: Vec<ValidatorStake>,
261 pub chunk_mask: Vec<bool>,
263 pub next_gas_price: Balance,
265 pub total_supply: Balance,
267 #[deprecated]
269 pub challenges_result: Vec<SlashedValidator>,
270
271 pub last_final_block: CryptoHash,
273 pub last_ds_final_block: CryptoHash,
275
276 pub block_ordinal: NumBlocks,
278
279 pub prev_height: BlockHeight,
280
281 pub epoch_sync_data_hash: Option<CryptoHash>,
282
283 pub approvals: Vec<Option<Box<Signature>>>,
285
286 pub latest_protocol_version: ProtocolVersion,
288
289 pub chunk_endorsements: ChunkEndorsementsBitmap,
290}
291
292#[derive(
294 BorshSerialize,
295 BorshDeserialize,
296 serde::Serialize,
297 Debug,
298 Clone,
299 PartialEq,
300 Eq,
301 Hash,
302 ProtocolSchema,
303)]
304#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
305pub enum ApprovalInner {
306 Endorsement(CryptoHash),
307 Skip(BlockHeight),
308}
309
310#[derive(
312 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, PartialEq, Eq, ProtocolSchema,
313)]
314pub struct Approval {
315 pub inner: ApprovalInner,
316 pub target_height: BlockHeight,
317 pub signature: Signature,
318 pub account_id: AccountId,
319}
320
321#[derive(PartialEq, Eq, Debug)]
323pub enum ApprovalType {
324 SelfApproval,
325 PeerApproval(PeerId),
326}
327
328#[derive(
330 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, PartialEq, Eq, ProtocolSchema,
331)]
332pub struct ApprovalMessage {
333 pub approval: Approval,
334 pub target: AccountId,
335}
336
337impl ApprovalInner {
338 pub fn new(
339 parent_hash: &CryptoHash,
340 parent_height: BlockHeight,
341 target_height: BlockHeight,
342 ) -> Self {
343 if target_height == parent_height + 1 {
344 ApprovalInner::Endorsement(*parent_hash)
345 } else {
346 ApprovalInner::Skip(parent_height)
347 }
348 }
349}
350
351impl Approval {
352 pub fn new(
353 parent_hash: CryptoHash,
354 parent_height: BlockHeight,
355 target_height: BlockHeight,
356 signer: &ValidatorSigner,
357 ) -> Self {
358 let inner = ApprovalInner::new(&parent_hash, parent_height, target_height);
359
360 let signature = signer.sign_bytes(&Approval::get_data_for_sig(&inner, target_height));
361 Approval { inner, target_height, signature, account_id: signer.validator_id().clone() }
362 }
363
364 pub fn get_data_for_sig(inner: &ApprovalInner, target_height: BlockHeight) -> Vec<u8> {
365 [borsh::to_vec(&inner).unwrap().as_ref(), target_height.to_le_bytes().as_ref()].concat()
366 }
367}
368
369impl ApprovalMessage {
370 pub fn new(approval: Approval, target: AccountId) -> Self {
371 ApprovalMessage { approval, target }
372 }
373}
374
375#[derive(
376 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq, ProtocolSchema,
377)]
378#[borsh(init=init)]
379pub struct BlockHeaderV1 {
380 pub prev_hash: CryptoHash,
381
382 pub inner_lite: BlockHeaderInnerLite,
385 pub inner_rest: BlockHeaderInnerRest,
386
387 pub signature: Signature,
389
390 #[borsh(skip)]
392 pub hash: CryptoHash,
393}
394
395impl BlockHeaderV1 {
396 pub fn init(&mut self) {
397 self.hash = BlockHeader::compute_hash(
398 self.prev_hash,
399 &borsh::to_vec(&self.inner_lite).expect("Failed to serialize"),
400 &borsh::to_vec(&self.inner_rest).expect("Failed to serialize"),
401 );
402 }
403}
404
405#[derive(
407 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq, ProtocolSchema,
408)]
409#[borsh(init=init)]
410pub struct BlockHeaderV2 {
411 pub prev_hash: CryptoHash,
412
413 pub inner_lite: BlockHeaderInnerLite,
416 pub inner_rest: BlockHeaderInnerRestV2,
417
418 pub signature: Signature,
420
421 #[borsh(skip)]
423 pub hash: CryptoHash,
424}
425
426#[derive(
429 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq, ProtocolSchema,
430)]
431#[borsh(init=init)]
432pub struct BlockHeaderV3 {
433 pub prev_hash: CryptoHash,
434
435 pub inner_lite: BlockHeaderInnerLite,
438 pub inner_rest: BlockHeaderInnerRestV3,
439
440 pub signature: Signature,
442
443 #[borsh(skip)]
445 pub hash: CryptoHash,
446}
447
448#[derive(
450 BorshSerialize,
451 BorshDeserialize,
452 serde::Serialize,
453 Debug,
454 Clone,
455 Eq,
456 PartialEq,
457 Default,
458 ProtocolSchema,
459)]
460#[borsh(init=init)]
461pub struct BlockHeaderV4 {
462 pub prev_hash: CryptoHash,
463
464 pub inner_lite: BlockHeaderInnerLite,
467 pub inner_rest: BlockHeaderInnerRestV4,
468
469 pub signature: Signature,
471
472 #[borsh(skip)]
474 pub hash: CryptoHash,
475}
476
477#[derive(
479 BorshSerialize,
480 BorshDeserialize,
481 serde::Serialize,
482 Debug,
483 Clone,
484 Eq,
485 PartialEq,
486 Default,
487 ProtocolSchema,
488)]
489#[borsh(init=init)]
490pub struct BlockHeaderV5 {
491 pub prev_hash: CryptoHash,
492
493 pub inner_lite: BlockHeaderInnerLite,
496 pub inner_rest: BlockHeaderInnerRestV5,
497
498 pub signature: Signature,
500
501 #[borsh(skip)]
503 pub hash: CryptoHash,
504}
505
506impl BlockHeaderV2 {
507 pub fn init(&mut self) {
508 self.hash = BlockHeader::compute_hash(
509 self.prev_hash,
510 &borsh::to_vec(&self.inner_lite).expect("Failed to serialize"),
511 &borsh::to_vec(&self.inner_rest).expect("Failed to serialize"),
512 );
513 }
514}
515
516impl BlockHeaderV3 {
517 pub fn init(&mut self) {
518 self.hash = BlockHeader::compute_hash(
519 self.prev_hash,
520 &borsh::to_vec(&self.inner_lite).expect("Failed to serialize"),
521 &borsh::to_vec(&self.inner_rest).expect("Failed to serialize"),
522 );
523 }
524}
525
526impl BlockHeaderV4 {
527 pub fn init(&mut self) {
528 self.hash = BlockHeader::compute_hash(
529 self.prev_hash,
530 &borsh::to_vec(&self.inner_lite).expect("Failed to serialize"),
531 &borsh::to_vec(&self.inner_rest).expect("Failed to serialize"),
532 );
533 }
534}
535
536impl BlockHeaderV5 {
537 pub fn init(&mut self) {
538 self.hash = BlockHeader::compute_hash(
539 self.prev_hash,
540 &borsh::to_vec(&self.inner_lite).expect("Failed to serialize"),
541 &borsh::to_vec(&self.inner_rest).expect("Failed to serialize"),
542 );
543 }
544}
545
546enum SignatureSource<'a> {
548 #[allow(dead_code)]
552 Signer(&'a ValidatorSigner),
553 Signature(Signature),
555}
556
557#[derive(
560 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq, ProtocolSchema,
561)]
562pub enum BlockHeader {
563 BlockHeaderV1(BlockHeaderV1),
564 BlockHeaderV2(BlockHeaderV2),
565 BlockHeaderV3(BlockHeaderV3),
566 BlockHeaderV4(BlockHeaderV4),
567 BlockHeaderV5(BlockHeaderV5),
568}
569
570impl BlockHeader {
571 pub fn compute_inner_hash(inner_lite: &[u8], inner_rest: &[u8]) -> CryptoHash {
572 let hash_lite = hash(inner_lite);
573 let hash_rest = hash(inner_rest);
574 combine_hash(&hash_lite, &hash_rest)
575 }
576
577 pub fn compute_hash(prev_hash: CryptoHash, inner_lite: &[u8], inner_rest: &[u8]) -> CryptoHash {
578 let hash_inner = BlockHeader::compute_inner_hash(inner_lite, inner_rest);
579
580 combine_hash(&hash_inner, &prev_hash)
581 }
582
583 pub fn new(
585 latest_protocol_version: ProtocolVersion,
586 height: BlockHeight,
587 prev_hash: CryptoHash,
588 block_body_hash: CryptoHash,
589 prev_state_root: MerkleHash,
590 prev_chunk_outgoing_receipts_root: MerkleHash,
591 chunk_headers_root: MerkleHash,
592 chunk_tx_root: MerkleHash,
593 outcome_root: MerkleHash,
594 timestamp: u64,
595 random_value: CryptoHash,
596 prev_validator_proposals: Vec<ValidatorStake>,
597 chunk_mask: Vec<bool>,
598 block_ordinal: NumBlocks,
599 epoch_id: EpochId,
600 next_epoch_id: EpochId,
601 next_gas_price: Balance,
602 total_supply: Balance,
603 signer: &ValidatorSigner,
604 last_final_block: CryptoHash,
605 last_ds_final_block: CryptoHash,
606 epoch_sync_data_hash: Option<CryptoHash>,
607 approvals: Vec<Option<Box<Signature>>>,
608 next_bp_hash: CryptoHash,
609 block_merkle_root: CryptoHash,
610 prev_height: BlockHeight,
611 chunk_endorsements: Option<ChunkEndorsementsBitmap>,
612 ) -> Self {
613 Self::new_impl(
614 latest_protocol_version,
615 height,
616 prev_hash,
617 block_body_hash,
618 prev_state_root,
619 prev_chunk_outgoing_receipts_root,
620 chunk_headers_root,
621 chunk_tx_root,
622 outcome_root,
623 timestamp,
624 random_value,
625 prev_validator_proposals,
626 chunk_mask,
627 block_ordinal,
628 epoch_id,
629 next_epoch_id,
630 next_gas_price,
631 total_supply,
632 SignatureSource::Signer(signer),
633 last_final_block,
634 last_ds_final_block,
635 epoch_sync_data_hash,
636 approvals,
637 next_bp_hash,
638 block_merkle_root,
639 prev_height,
640 chunk_endorsements,
641 )
642 }
643
644 pub fn from_view(
646 expected_hash: &CryptoHash,
647 epoch_protocol_version: ProtocolVersion,
648 height: BlockHeight,
649 prev_hash: CryptoHash,
650 block_body_hash: CryptoHash,
651 prev_state_root: MerkleHash,
652 prev_chunk_outgoing_receipts_root: MerkleHash,
653 chunk_headers_root: MerkleHash,
654 chunk_tx_root: MerkleHash,
655 outcome_root: MerkleHash,
656 timestamp: u64,
657 random_value: CryptoHash,
658 prev_validator_proposals: Vec<ValidatorStake>,
659 chunk_mask: Vec<bool>,
660 block_ordinal: NumBlocks,
661 epoch_id: EpochId,
662 next_epoch_id: EpochId,
663 next_gas_price: Balance,
664 total_supply: Balance,
665 signature: Signature,
666 last_final_block: CryptoHash,
667 last_ds_final_block: CryptoHash,
668 epoch_sync_data_hash: Option<CryptoHash>,
669 approvals: Vec<Option<Box<Signature>>>,
670 next_bp_hash: CryptoHash,
671 block_merkle_root: CryptoHash,
672 prev_height: BlockHeight,
673 chunk_endorsements: Option<ChunkEndorsementsBitmap>,
674 ) -> Self {
675 let header = Self::new_impl(
676 epoch_protocol_version,
677 height,
678 prev_hash,
679 block_body_hash,
680 prev_state_root,
681 prev_chunk_outgoing_receipts_root,
682 chunk_headers_root,
683 chunk_tx_root,
684 outcome_root,
685 timestamp,
686 random_value,
687 prev_validator_proposals,
688 chunk_mask,
689 block_ordinal,
690 epoch_id,
691 next_epoch_id,
692 next_gas_price,
693 total_supply,
694 SignatureSource::Signature(signature),
695 last_final_block,
696 last_ds_final_block,
697 epoch_sync_data_hash,
698 approvals,
699 next_bp_hash,
700 block_merkle_root,
701 prev_height,
702 chunk_endorsements,
703 );
704 if header.hash() != expected_hash {
708 tracing::debug!(height, header_hash=?header.hash(), ?expected_hash, "Hash of the created header does not match expected hash");
709 }
710 header
711 }
712
713 fn new_impl(
715 latest_protocol_version: ProtocolVersion,
716 height: BlockHeight,
717 prev_hash: CryptoHash,
718 block_body_hash: CryptoHash,
719 prev_state_root: MerkleHash,
720 prev_chunk_outgoing_receipts_root: MerkleHash,
721 chunk_headers_root: MerkleHash,
722 chunk_tx_root: MerkleHash,
723 outcome_root: MerkleHash,
724 timestamp: u64,
725 random_value: CryptoHash,
726 prev_validator_proposals: Vec<ValidatorStake>,
727 chunk_mask: Vec<bool>,
728 block_ordinal: NumBlocks,
729 epoch_id: EpochId,
730 next_epoch_id: EpochId,
731 next_gas_price: Balance,
732 total_supply: Balance,
733 signature_source: SignatureSource,
734 last_final_block: CryptoHash,
735 last_ds_final_block: CryptoHash,
736 epoch_sync_data_hash: Option<CryptoHash>,
737 approvals: Vec<Option<Box<Signature>>>,
738 next_bp_hash: CryptoHash,
739 block_merkle_root: CryptoHash,
740 prev_height: BlockHeight,
741 chunk_endorsements: Option<ChunkEndorsementsBitmap>,
742 ) -> Self {
743 let inner_lite = BlockHeaderInnerLite {
744 height,
745 epoch_id,
746 next_epoch_id,
747 prev_state_root,
748 prev_outcome_root: outcome_root,
749 timestamp,
750 next_bp_hash,
751 block_merkle_root,
752 };
753
754 let chunk_endorsements = chunk_endorsements.unwrap_or_else(|| {
755 panic!("BlockHeaderV5 is enabled but chunk endorsement bitmap is not provided")
756 });
757 #[allow(deprecated)]
758 let inner_rest = BlockHeaderInnerRestV5 {
759 block_body_hash,
760 prev_chunk_outgoing_receipts_root,
761 chunk_headers_root,
762 chunk_tx_root,
763 challenges_root: CryptoHash::default(),
764 random_value,
765 prev_validator_proposals,
766 chunk_mask,
767 next_gas_price,
768 block_ordinal,
769 total_supply,
770 challenges_result: vec![],
771 last_final_block,
772 last_ds_final_block,
773 prev_height,
774 epoch_sync_data_hash,
775 approvals,
776 latest_protocol_version,
777 chunk_endorsements,
778 };
779 let (hash, signature) =
780 Self::compute_hash_and_sign(signature_source, prev_hash, &inner_lite, &inner_rest);
781 Self::BlockHeaderV5(BlockHeaderV5 { prev_hash, inner_lite, inner_rest, signature, hash })
782 }
783
784 fn compute_hash_and_sign<T>(
789 signature_source: SignatureSource,
790 prev_hash: CryptoHash,
791 inner_lite: &BlockHeaderInnerLite,
792 inner_rest: &T,
793 ) -> (CryptoHash, Signature)
794 where
795 T: BorshSerialize + ?Sized,
796 {
797 let hash = BlockHeader::compute_hash(
798 prev_hash,
799 &borsh::to_vec(&inner_lite).expect("Failed to serialize"),
800 &borsh::to_vec(&inner_rest).expect("Failed to serialize"),
801 );
802 match signature_source {
803 SignatureSource::Signer(signer) => (hash, signer.sign_bytes(hash.as_ref())),
804 SignatureSource::Signature(signature) => (hash, signature),
805 }
806 }
807
808 pub fn genesis(
809 genesis_protocol_version: ProtocolVersion,
810 height: BlockHeight,
811 state_root: MerkleHash,
812 block_body_hash: CryptoHash,
813 prev_chunk_outgoing_receipts_root: MerkleHash,
814 chunk_headers_root: MerkleHash,
815 chunk_tx_root: MerkleHash,
816 num_shards: u64,
817 timestamp: Utc,
818 initial_gas_price: Balance,
819 initial_total_supply: Balance,
820 next_bp_hash: CryptoHash,
821 ) -> Self {
822 let chunks_included = if height == 0 { num_shards } else { 0 };
823 Self::new_impl(
824 genesis_protocol_version,
825 height,
826 CryptoHash::default(), block_body_hash,
828 state_root,
829 prev_chunk_outgoing_receipts_root,
830 chunk_headers_root,
831 chunk_tx_root,
832 CryptoHash::default(), timestamp.unix_timestamp_nanos() as u64,
834 CryptoHash::default(), vec![], vec![true; chunks_included as usize], 1, EpochId::default(), EpochId::default(), initial_gas_price,
841 initial_total_supply,
842 SignatureSource::Signature(Signature::empty(KeyType::ED25519)),
843 CryptoHash::default(), CryptoHash::default(), None, vec![], next_bp_hash,
848 CryptoHash::default(), 0, Some(ChunkEndorsementsBitmap::genesis()),
851 )
852 }
853
854 #[inline]
855 pub fn is_genesis(&self) -> bool {
856 self.prev_hash() == &CryptoHash::default()
857 }
858
859 #[inline]
860 pub fn hash(&self) -> &CryptoHash {
861 match self {
862 BlockHeader::BlockHeaderV1(header) => &header.hash,
863 BlockHeader::BlockHeaderV2(header) => &header.hash,
864 BlockHeader::BlockHeaderV3(header) => &header.hash,
865 BlockHeader::BlockHeaderV4(header) => &header.hash,
866 BlockHeader::BlockHeaderV5(header) => &header.hash,
867 }
868 }
869
870 #[inline]
871 pub fn prev_hash(&self) -> &CryptoHash {
872 match self {
873 BlockHeader::BlockHeaderV1(header) => &header.prev_hash,
874 BlockHeader::BlockHeaderV2(header) => &header.prev_hash,
875 BlockHeader::BlockHeaderV3(header) => &header.prev_hash,
876 BlockHeader::BlockHeaderV4(header) => &header.prev_hash,
877 BlockHeader::BlockHeaderV5(header) => &header.prev_hash,
878 }
879 }
880
881 #[inline]
882 pub fn signature(&self) -> &Signature {
883 match self {
884 BlockHeader::BlockHeaderV1(header) => &header.signature,
885 BlockHeader::BlockHeaderV2(header) => &header.signature,
886 BlockHeader::BlockHeaderV3(header) => &header.signature,
887 BlockHeader::BlockHeaderV4(header) => &header.signature,
888 BlockHeader::BlockHeaderV5(header) => &header.signature,
889 }
890 }
891
892 #[inline]
893 pub fn height(&self) -> BlockHeight {
894 match self {
895 BlockHeader::BlockHeaderV1(header) => header.inner_lite.height,
896 BlockHeader::BlockHeaderV2(header) => header.inner_lite.height,
897 BlockHeader::BlockHeaderV3(header) => header.inner_lite.height,
898 BlockHeader::BlockHeaderV4(header) => header.inner_lite.height,
899 BlockHeader::BlockHeaderV5(header) => header.inner_lite.height,
900 }
901 }
902
903 #[inline]
904 pub fn prev_height(&self) -> Option<BlockHeight> {
905 match self {
906 BlockHeader::BlockHeaderV1(_) => None,
907 BlockHeader::BlockHeaderV2(_) => None,
908 BlockHeader::BlockHeaderV3(header) => Some(header.inner_rest.prev_height),
909 BlockHeader::BlockHeaderV4(header) => Some(header.inner_rest.prev_height),
910 BlockHeader::BlockHeaderV5(header) => Some(header.inner_rest.prev_height),
911 }
912 }
913
914 #[inline]
915 pub fn epoch_id(&self) -> &EpochId {
916 match self {
917 BlockHeader::BlockHeaderV1(header) => &header.inner_lite.epoch_id,
918 BlockHeader::BlockHeaderV2(header) => &header.inner_lite.epoch_id,
919 BlockHeader::BlockHeaderV3(header) => &header.inner_lite.epoch_id,
920 BlockHeader::BlockHeaderV4(header) => &header.inner_lite.epoch_id,
921 BlockHeader::BlockHeaderV5(header) => &header.inner_lite.epoch_id,
922 }
923 }
924
925 #[inline]
926 pub fn next_epoch_id(&self) -> &EpochId {
927 match self {
928 BlockHeader::BlockHeaderV1(header) => &header.inner_lite.next_epoch_id,
929 BlockHeader::BlockHeaderV2(header) => &header.inner_lite.next_epoch_id,
930 BlockHeader::BlockHeaderV3(header) => &header.inner_lite.next_epoch_id,
931 BlockHeader::BlockHeaderV4(header) => &header.inner_lite.next_epoch_id,
932 BlockHeader::BlockHeaderV5(header) => &header.inner_lite.next_epoch_id,
933 }
934 }
935
936 #[inline]
937 pub fn prev_state_root(&self) -> &MerkleHash {
938 match self {
939 BlockHeader::BlockHeaderV1(header) => &header.inner_lite.prev_state_root,
940 BlockHeader::BlockHeaderV2(header) => &header.inner_lite.prev_state_root,
941 BlockHeader::BlockHeaderV3(header) => &header.inner_lite.prev_state_root,
942 BlockHeader::BlockHeaderV4(header) => &header.inner_lite.prev_state_root,
943 BlockHeader::BlockHeaderV5(header) => &header.inner_lite.prev_state_root,
944 }
945 }
946
947 #[inline]
948 pub fn prev_chunk_outgoing_receipts_root(&self) -> &MerkleHash {
949 match self {
950 BlockHeader::BlockHeaderV1(header) => {
951 &header.inner_rest.prev_chunk_outgoing_receipts_root
952 }
953 BlockHeader::BlockHeaderV2(header) => {
954 &header.inner_rest.prev_chunk_outgoing_receipts_root
955 }
956 BlockHeader::BlockHeaderV3(header) => {
957 &header.inner_rest.prev_chunk_outgoing_receipts_root
958 }
959 BlockHeader::BlockHeaderV4(header) => {
960 &header.inner_rest.prev_chunk_outgoing_receipts_root
961 }
962 BlockHeader::BlockHeaderV5(header) => {
963 &header.inner_rest.prev_chunk_outgoing_receipts_root
964 }
965 }
966 }
967
968 #[inline]
969 pub fn chunk_headers_root(&self) -> &MerkleHash {
970 match self {
971 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.chunk_headers_root,
972 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.chunk_headers_root,
973 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.chunk_headers_root,
974 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.chunk_headers_root,
975 BlockHeader::BlockHeaderV5(header) => &header.inner_rest.chunk_headers_root,
976 }
977 }
978
979 #[inline]
980 pub fn chunk_tx_root(&self) -> &MerkleHash {
981 match self {
982 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.chunk_tx_root,
983 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.chunk_tx_root,
984 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.chunk_tx_root,
985 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.chunk_tx_root,
986 BlockHeader::BlockHeaderV5(header) => &header.inner_rest.chunk_tx_root,
987 }
988 }
989
990 pub fn chunks_included(&self) -> u64 {
991 let mask = match self {
992 BlockHeader::BlockHeaderV1(header) => return header.inner_rest.chunks_included,
993 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.chunk_mask,
994 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.chunk_mask,
995 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.chunk_mask,
996 BlockHeader::BlockHeaderV5(header) => &header.inner_rest.chunk_mask,
997 };
998 mask.iter().map(|&x| u64::from(x)).sum::<u64>()
999 }
1000
1001 #[inline]
1002 pub fn outcome_root(&self) -> &MerkleHash {
1003 match self {
1004 BlockHeader::BlockHeaderV1(header) => &header.inner_lite.prev_outcome_root,
1005 BlockHeader::BlockHeaderV2(header) => &header.inner_lite.prev_outcome_root,
1006 BlockHeader::BlockHeaderV3(header) => &header.inner_lite.prev_outcome_root,
1007 BlockHeader::BlockHeaderV4(header) => &header.inner_lite.prev_outcome_root,
1008 BlockHeader::BlockHeaderV5(header) => &header.inner_lite.prev_outcome_root,
1009 }
1010 }
1011
1012 #[inline]
1013 pub fn block_body_hash(&self) -> Option<CryptoHash> {
1014 match self {
1015 BlockHeader::BlockHeaderV1(_) => None,
1016 BlockHeader::BlockHeaderV2(_) => None,
1017 BlockHeader::BlockHeaderV3(_) => None,
1018 BlockHeader::BlockHeaderV4(header) => Some(header.inner_rest.block_body_hash),
1019 BlockHeader::BlockHeaderV5(header) => Some(header.inner_rest.block_body_hash),
1020 }
1021 }
1022
1023 #[inline]
1024 pub fn raw_timestamp(&self) -> u64 {
1025 match self {
1026 BlockHeader::BlockHeaderV1(header) => header.inner_lite.timestamp,
1027 BlockHeader::BlockHeaderV2(header) => header.inner_lite.timestamp,
1028 BlockHeader::BlockHeaderV3(header) => header.inner_lite.timestamp,
1029 BlockHeader::BlockHeaderV4(header) => header.inner_lite.timestamp,
1030 BlockHeader::BlockHeaderV5(header) => header.inner_lite.timestamp,
1031 }
1032 }
1033
1034 #[inline]
1035 pub fn prev_validator_proposals(&self) -> ValidatorStakeIter {
1036 match self {
1037 BlockHeader::BlockHeaderV1(header) => {
1038 ValidatorStakeIter::v1(&header.inner_rest.prev_validator_proposals)
1039 }
1040 BlockHeader::BlockHeaderV2(header) => {
1041 ValidatorStakeIter::v1(&header.inner_rest.prev_validator_proposals)
1042 }
1043 BlockHeader::BlockHeaderV3(header) => {
1044 ValidatorStakeIter::new(&header.inner_rest.prev_validator_proposals)
1045 }
1046 BlockHeader::BlockHeaderV4(header) => {
1047 ValidatorStakeIter::new(&header.inner_rest.prev_validator_proposals)
1048 }
1049 BlockHeader::BlockHeaderV5(header) => {
1050 ValidatorStakeIter::new(&header.inner_rest.prev_validator_proposals)
1051 }
1052 }
1053 }
1054
1055 #[inline]
1056 pub fn chunk_mask(&self) -> &[bool] {
1057 match self {
1058 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.chunk_mask,
1059 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.chunk_mask,
1060 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.chunk_mask,
1061 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.chunk_mask,
1062 BlockHeader::BlockHeaderV5(header) => &header.inner_rest.chunk_mask,
1063 }
1064 }
1065
1066 #[inline]
1067 pub fn block_ordinal(&self) -> NumBlocks {
1068 match self {
1069 BlockHeader::BlockHeaderV1(_) => 0, BlockHeader::BlockHeaderV2(_) => 0, BlockHeader::BlockHeaderV3(header) => header.inner_rest.block_ordinal,
1072 BlockHeader::BlockHeaderV4(header) => header.inner_rest.block_ordinal,
1073 BlockHeader::BlockHeaderV5(header) => header.inner_rest.block_ordinal,
1074 }
1075 }
1076
1077 #[inline]
1078 pub fn next_gas_price(&self) -> Balance {
1079 match self {
1080 BlockHeader::BlockHeaderV1(header) => header.inner_rest.next_gas_price,
1081 BlockHeader::BlockHeaderV2(header) => header.inner_rest.next_gas_price,
1082 BlockHeader::BlockHeaderV3(header) => header.inner_rest.next_gas_price,
1083 BlockHeader::BlockHeaderV4(header) => header.inner_rest.next_gas_price,
1084 BlockHeader::BlockHeaderV5(header) => header.inner_rest.next_gas_price,
1085 }
1086 }
1087
1088 #[inline]
1089 pub fn total_supply(&self) -> Balance {
1090 match self {
1091 BlockHeader::BlockHeaderV1(header) => header.inner_rest.total_supply,
1092 BlockHeader::BlockHeaderV2(header) => header.inner_rest.total_supply,
1093 BlockHeader::BlockHeaderV3(header) => header.inner_rest.total_supply,
1094 BlockHeader::BlockHeaderV4(header) => header.inner_rest.total_supply,
1095 BlockHeader::BlockHeaderV5(header) => header.inner_rest.total_supply,
1096 }
1097 }
1098
1099 #[inline]
1100 pub fn random_value(&self) -> &CryptoHash {
1101 match self {
1102 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.random_value,
1103 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.random_value,
1104 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.random_value,
1105 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.random_value,
1106 BlockHeader::BlockHeaderV5(header) => &header.inner_rest.random_value,
1107 }
1108 }
1109
1110 #[inline]
1111 pub fn last_final_block(&self) -> &CryptoHash {
1112 match self {
1113 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.last_final_block,
1114 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.last_final_block,
1115 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.last_final_block,
1116 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.last_final_block,
1117 BlockHeader::BlockHeaderV5(header) => &header.inner_rest.last_final_block,
1118 }
1119 }
1120
1121 #[inline]
1122 pub fn last_ds_final_block(&self) -> &CryptoHash {
1123 match self {
1124 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.last_ds_final_block,
1125 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.last_ds_final_block,
1126 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.last_ds_final_block,
1127 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.last_ds_final_block,
1128 BlockHeader::BlockHeaderV5(header) => &header.inner_rest.last_ds_final_block,
1129 }
1130 }
1131
1132 #[inline]
1133 pub fn next_bp_hash(&self) -> &CryptoHash {
1134 match self {
1135 BlockHeader::BlockHeaderV1(header) => &header.inner_lite.next_bp_hash,
1136 BlockHeader::BlockHeaderV2(header) => &header.inner_lite.next_bp_hash,
1137 BlockHeader::BlockHeaderV3(header) => &header.inner_lite.next_bp_hash,
1138 BlockHeader::BlockHeaderV4(header) => &header.inner_lite.next_bp_hash,
1139 BlockHeader::BlockHeaderV5(header) => &header.inner_lite.next_bp_hash,
1140 }
1141 }
1142
1143 #[inline]
1144 pub fn block_merkle_root(&self) -> &CryptoHash {
1145 match self {
1146 BlockHeader::BlockHeaderV1(header) => &header.inner_lite.block_merkle_root,
1147 BlockHeader::BlockHeaderV2(header) => &header.inner_lite.block_merkle_root,
1148 BlockHeader::BlockHeaderV3(header) => &header.inner_lite.block_merkle_root,
1149 BlockHeader::BlockHeaderV4(header) => &header.inner_lite.block_merkle_root,
1150 BlockHeader::BlockHeaderV5(header) => &header.inner_lite.block_merkle_root,
1151 }
1152 }
1153
1154 #[inline]
1155 pub fn epoch_sync_data_hash(&self) -> Option<CryptoHash> {
1156 match self {
1157 BlockHeader::BlockHeaderV1(_) => None,
1158 BlockHeader::BlockHeaderV2(_) => None,
1159 BlockHeader::BlockHeaderV3(header) => header.inner_rest.epoch_sync_data_hash,
1160 BlockHeader::BlockHeaderV4(header) => header.inner_rest.epoch_sync_data_hash,
1161 BlockHeader::BlockHeaderV5(header) => header.inner_rest.epoch_sync_data_hash,
1162 }
1163 }
1164
1165 #[inline]
1166 pub fn approvals(&self) -> &[Option<Box<Signature>>] {
1167 match self {
1168 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.approvals,
1169 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.approvals,
1170 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.approvals,
1171 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.approvals,
1172 BlockHeader::BlockHeaderV5(header) => &header.inner_rest.approvals,
1173 }
1174 }
1175
1176 pub fn verify_block_producer(&self, public_key: &PublicKey) -> bool {
1178 self.signature().verify(self.hash().as_ref(), public_key)
1179 }
1180
1181 pub fn timestamp(&self) -> Utc {
1182 Utc::from_unix_timestamp_nanos(self.raw_timestamp() as i128).unwrap()
1183 }
1184
1185 pub fn num_approvals(&self) -> u64 {
1186 self.approvals().iter().filter(|x| x.is_some()).count() as u64
1187 }
1188
1189 pub fn verify_chunks_included(&self) -> bool {
1190 match self {
1191 BlockHeader::BlockHeaderV1(header) => {
1192 header.inner_rest.chunk_mask.iter().map(|&x| u64::from(x)).sum::<u64>()
1193 == header.inner_rest.chunks_included
1194 }
1195 BlockHeader::BlockHeaderV2(_header) => true,
1196 BlockHeader::BlockHeaderV3(_header) => true,
1197 BlockHeader::BlockHeaderV4(_header) => true,
1198 BlockHeader::BlockHeaderV5(_header) => true,
1199 }
1200 }
1201
1202 #[inline]
1203 pub fn latest_protocol_version(&self) -> u32 {
1204 match self {
1205 BlockHeader::BlockHeaderV1(header) => header.inner_rest.latest_protocol_version,
1206 BlockHeader::BlockHeaderV2(header) => header.inner_rest.latest_protocol_version,
1207 BlockHeader::BlockHeaderV3(header) => header.inner_rest.latest_protocol_version,
1208 BlockHeader::BlockHeaderV4(header) => header.inner_rest.latest_protocol_version,
1209 BlockHeader::BlockHeaderV5(header) => header.inner_rest.latest_protocol_version,
1210 }
1211 }
1212
1213 pub fn inner_lite_bytes(&self) -> Vec<u8> {
1214 match self {
1215 BlockHeader::BlockHeaderV1(header) => {
1216 borsh::to_vec(&header.inner_lite).expect("Failed to serialize")
1217 }
1218 BlockHeader::BlockHeaderV2(header) => {
1219 borsh::to_vec(&header.inner_lite).expect("Failed to serialize")
1220 }
1221 BlockHeader::BlockHeaderV3(header) => {
1222 borsh::to_vec(&header.inner_lite).expect("Failed to serialize")
1223 }
1224 BlockHeader::BlockHeaderV4(header) => {
1225 borsh::to_vec(&header.inner_lite).expect("Failed to serialize")
1226 }
1227 BlockHeader::BlockHeaderV5(header) => {
1228 borsh::to_vec(&header.inner_lite).expect("Failed to serialize")
1229 }
1230 }
1231 }
1232
1233 pub fn inner_rest_bytes(&self) -> Vec<u8> {
1234 match self {
1235 BlockHeader::BlockHeaderV1(header) => {
1236 borsh::to_vec(&header.inner_rest).expect("Failed to serialize")
1237 }
1238 BlockHeader::BlockHeaderV2(header) => {
1239 borsh::to_vec(&header.inner_rest).expect("Failed to serialize")
1240 }
1241 BlockHeader::BlockHeaderV3(header) => {
1242 borsh::to_vec(&header.inner_rest).expect("Failed to serialize")
1243 }
1244 BlockHeader::BlockHeaderV4(header) => {
1245 borsh::to_vec(&header.inner_rest).expect("Failed to serialize")
1246 }
1247 BlockHeader::BlockHeaderV5(header) => {
1248 borsh::to_vec(&header.inner_rest).expect("Failed to serialize")
1249 }
1250 }
1251 }
1252
1253 #[inline]
1254 pub fn chunk_endorsements(&self) -> Option<&ChunkEndorsementsBitmap> {
1255 match self {
1256 BlockHeader::BlockHeaderV1(_) => None,
1257 BlockHeader::BlockHeaderV2(_) => None,
1258 BlockHeader::BlockHeaderV3(_) => None,
1259 BlockHeader::BlockHeaderV4(_) => None,
1260 BlockHeader::BlockHeaderV5(header) => Some(&header.inner_rest.chunk_endorsements),
1261 }
1262 }
1263
1264 #[inline]
1265 pub fn inner_lite(&self) -> &BlockHeaderInnerLite {
1266 match self {
1267 BlockHeader::BlockHeaderV1(header) => &header.inner_lite,
1268 BlockHeader::BlockHeaderV2(header) => &header.inner_lite,
1269 BlockHeader::BlockHeaderV3(header) => &header.inner_lite,
1270 BlockHeader::BlockHeaderV4(header) => &header.inner_lite,
1271 BlockHeader::BlockHeaderV5(header) => &header.inner_lite,
1272 }
1273 }
1274
1275 pub fn challenges_present(&self) -> bool {
1278 #[allow(deprecated)]
1279 let (challenges_root, challenges_result) = match self {
1280 Self::BlockHeaderV1(header) => {
1281 (&header.inner_rest.challenges_root, &header.inner_rest.challenges_result)
1282 }
1283 Self::BlockHeaderV2(header) => {
1284 (&header.inner_rest.challenges_root, &header.inner_rest.challenges_result)
1285 }
1286 Self::BlockHeaderV3(header) => {
1287 (&header.inner_rest.challenges_root, &header.inner_rest.challenges_result)
1288 }
1289 Self::BlockHeaderV4(header) => {
1290 (&header.inner_rest.challenges_root, &header.inner_rest.challenges_result)
1291 }
1292 Self::BlockHeaderV5(header) => {
1293 (&header.inner_rest.challenges_root, &header.inner_rest.challenges_result)
1294 }
1295 };
1296
1297 !challenges_result.is_empty() || challenges_root != &MerkleHash::default()
1298 }
1299}
1300
1301pub fn compute_bp_hash_from_validator_stakes(
1302 validator_stakes: &Vec<ValidatorStake>,
1303 use_versioned_bp_hash_format: bool,
1304) -> CryptoHash {
1305 if use_versioned_bp_hash_format {
1306 CryptoHash::hash_borsh_iter(validator_stakes)
1307 } else {
1308 let stakes = validator_stakes.into_iter().map(|stake| stake.clone().into_v1());
1309 CryptoHash::hash_borsh_iter(stakes)
1310 }
1311}