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