1use crate::challenge::ChallengesResult;
2use crate::hash::{hash, CryptoHash};
3use crate::merkle::combine_hash;
4use crate::network::PeerId;
5use crate::types::validator_power::{ValidatorPower, ValidatorPowerIter, ValidatorPowerV1};
6use crate::types::validator_stake::{ValidatorPledge, ValidatorPledgeIter};
7use crate::types::{
8 AccountId, Balance, BlockHeight, EpochId, MerkleHash, NumBlocks, ValidatorPledgeV1,
9};
10use crate::utils::{from_timestamp, to_timestamp};
11use crate::validator_signer::ValidatorSigner;
12use crate::version::{get_protocol_version, ProtocolVersion, PROTOCOL_VERSION};
13use borsh::{BorshDeserialize, BorshSerialize};
14use chrono::{DateTime, Utc};
15use std::sync::Arc;
16use unc_crypto::{KeyType, PublicKey, Signature};
17
18#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq)]
19pub struct BlockHeaderInnerLite {
20 pub height: BlockHeight,
22 pub epoch_id: EpochId,
25 pub next_epoch_id: EpochId,
26 pub prev_state_root: MerkleHash,
28 pub prev_outcome_root: MerkleHash,
30 pub timestamp: u64,
32 pub next_bp_hash: CryptoHash,
34 pub block_merkle_root: CryptoHash,
36}
37
38#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq)]
39pub struct BlockHeaderInnerRest {
40 pub prev_chunk_outgoing_receipts_root: MerkleHash,
42 pub chunk_headers_root: MerkleHash,
44 pub chunk_tx_root: MerkleHash,
46 pub chunks_included: u64,
48 pub challenges_root: MerkleHash,
50 pub random_value: CryptoHash,
52 pub prev_validator_power_proposals: Vec<ValidatorPowerV1>,
54 pub prev_validator_pledge_proposals: Vec<ValidatorPledgeV1>,
56 pub chunk_mask: Vec<bool>,
58 pub next_gas_price: Balance,
60 pub total_supply: Balance,
62 pub challenges_result: ChallengesResult,
64
65 pub last_final_block: CryptoHash,
67 pub last_ds_final_block: CryptoHash,
69
70 pub approvals: Vec<Option<Box<Signature>>>,
72
73 pub latest_protocol_version: ProtocolVersion,
75}
76
77#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq)]
79pub struct BlockHeaderInnerRestV2 {
80 pub prev_chunk_outgoing_receipts_root: MerkleHash,
82 pub chunk_headers_root: MerkleHash,
84 pub chunk_tx_root: MerkleHash,
86 pub challenges_root: MerkleHash,
88 pub random_value: CryptoHash,
90 pub prev_validator_power_proposals: Vec<ValidatorPowerV1>,
92 pub prev_validator_pledge_proposals: Vec<ValidatorPledgeV1>,
94 pub chunk_mask: Vec<bool>,
96 pub next_gas_price: Balance,
98 pub total_supply: Balance,
100 pub challenges_result: ChallengesResult,
102
103 pub last_final_block: CryptoHash,
105 pub last_ds_final_block: CryptoHash,
107
108 pub approvals: Vec<Option<Box<Signature>>>,
110
111 pub latest_protocol_version: ProtocolVersion,
113}
114
115#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq)]
120pub struct BlockHeaderInnerRestV3 {
121 pub prev_chunk_outgoing_receipts_root: MerkleHash,
123 pub chunk_headers_root: MerkleHash,
125 pub chunk_tx_root: MerkleHash,
127 pub challenges_root: MerkleHash,
129 pub random_value: CryptoHash,
131 pub prev_validator_power_proposals: Vec<ValidatorPower>,
133 pub prev_validator_pledge_proposals: Vec<ValidatorPledge>,
135 pub chunk_mask: Vec<bool>,
137 pub next_gas_price: Balance,
139 pub total_supply: Balance,
141 pub challenges_result: ChallengesResult,
143
144 pub last_final_block: CryptoHash,
146 pub last_ds_final_block: CryptoHash,
148
149 pub block_ordinal: NumBlocks,
151
152 pub prev_height: BlockHeight,
153
154 pub epoch_sync_data_hash: Option<CryptoHash>,
155
156 pub approvals: Vec<Option<Box<Signature>>>,
158
159 pub latest_protocol_version: ProtocolVersion,
161}
162
163#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq)]
165pub struct BlockHeaderInnerRestV4 {
166 pub block_body_hash: CryptoHash,
168 pub prev_chunk_outgoing_receipts_root: MerkleHash,
170 pub chunk_headers_root: MerkleHash,
172 pub chunk_tx_root: MerkleHash,
174 pub challenges_root: MerkleHash,
176 pub random_value: CryptoHash,
178 pub prev_validator_power_proposals: Vec<ValidatorPower>,
180 pub prev_validator_pledge_proposals: Vec<ValidatorPledge>,
182 pub chunk_mask: Vec<bool>,
184 pub next_gas_price: Balance,
186 pub total_supply: Balance,
188 pub challenges_result: ChallengesResult,
190
191 pub last_final_block: CryptoHash,
193 pub last_ds_final_block: CryptoHash,
195
196 pub block_ordinal: NumBlocks,
198
199 pub prev_height: BlockHeight,
200
201 pub epoch_sync_data_hash: Option<CryptoHash>,
202
203 pub approvals: Vec<Option<Box<Signature>>>,
205
206 pub latest_protocol_version: ProtocolVersion,
208}
209
210#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, PartialEq, Eq, Hash)]
212pub enum ApprovalInner {
213 Endorsement(CryptoHash),
214 Skip(BlockHeight),
215}
216
217#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, PartialEq, Eq)]
219pub struct Approval {
220 pub inner: ApprovalInner,
221 pub target_height: BlockHeight,
222 pub signature: Signature,
223 pub account_id: AccountId,
224}
225
226#[derive(PartialEq, Eq, Debug)]
228pub enum ApprovalType {
229 SelfApproval,
230 PeerApproval(PeerId),
231}
232
233#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, PartialEq, Eq)]
235pub struct ApprovalMessage {
236 pub approval: Approval,
237 pub target: AccountId,
238}
239
240impl ApprovalInner {
241 pub fn new(
242 parent_hash: &CryptoHash,
243 parent_height: BlockHeight,
244 target_height: BlockHeight,
245 ) -> Self {
246 if target_height == parent_height + 1 {
247 ApprovalInner::Endorsement(*parent_hash)
248 } else {
249 ApprovalInner::Skip(parent_height)
250 }
251 }
252}
253
254impl Approval {
255 pub fn new(
256 parent_hash: CryptoHash,
257 parent_height: BlockHeight,
258 target_height: BlockHeight,
259 signer: &dyn ValidatorSigner,
260 ) -> Self {
261 let inner = ApprovalInner::new(&parent_hash, parent_height, target_height);
262 let signature = signer.sign_approval(&inner, target_height);
263 Approval { inner, target_height, signature, account_id: signer.validator_id().clone() }
264 }
265
266 pub fn get_data_for_sig(inner: &ApprovalInner, target_height: BlockHeight) -> Vec<u8> {
267 [borsh::to_vec(&inner).unwrap().as_ref(), target_height.to_le_bytes().as_ref()].concat()
268 }
269}
270
271impl ApprovalMessage {
272 pub fn new(approval: Approval, target: AccountId) -> Self {
273 ApprovalMessage { approval, target }
274 }
275}
276
277#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq)]
278#[borsh(init=init)]
279pub struct BlockHeaderV1 {
280 pub prev_hash: CryptoHash,
281
282 pub inner_lite: BlockHeaderInnerLite,
285 pub inner_rest: BlockHeaderInnerRest,
286
287 pub signature: Signature,
289
290 #[borsh(skip)]
292 pub hash: CryptoHash,
293}
294
295impl BlockHeaderV1 {
296 pub fn init(&mut self) {
297 self.hash = BlockHeader::compute_hash(
298 self.prev_hash,
299 &borsh::to_vec(&self.inner_lite).expect("Failed to serialize"),
300 &borsh::to_vec(&self.inner_rest).expect("Failed to serialize"),
301 );
302 }
303}
304
305#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq)]
307#[borsh(init=init)]
308pub struct BlockHeaderV2 {
309 pub prev_hash: CryptoHash,
310
311 pub inner_lite: BlockHeaderInnerLite,
314 pub inner_rest: BlockHeaderInnerRestV2,
315
316 pub signature: Signature,
318
319 #[borsh(skip)]
321 pub hash: CryptoHash,
322}
323
324#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq)]
327#[borsh(init=init)]
328pub struct BlockHeaderV3 {
329 pub prev_hash: CryptoHash,
330
331 pub inner_lite: BlockHeaderInnerLite,
334 pub inner_rest: BlockHeaderInnerRestV3,
335
336 pub signature: Signature,
338
339 #[borsh(skip)]
341 pub hash: CryptoHash,
342}
343
344#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq)]
346#[borsh(init=init)]
347pub struct BlockHeaderV4 {
348 pub prev_hash: CryptoHash,
349
350 pub inner_lite: BlockHeaderInnerLite,
353 pub inner_rest: BlockHeaderInnerRestV4,
354
355 pub signature: Signature,
357
358 #[borsh(skip)]
360 pub hash: CryptoHash,
361}
362
363impl BlockHeaderV2 {
364 pub fn init(&mut self) {
365 self.hash = BlockHeader::compute_hash(
366 self.prev_hash,
367 &borsh::to_vec(&self.inner_lite).expect("Failed to serialize"),
368 &borsh::to_vec(&self.inner_rest).expect("Failed to serialize"),
369 );
370 }
371}
372
373impl BlockHeaderV3 {
374 pub fn init(&mut self) {
375 self.hash = BlockHeader::compute_hash(
376 self.prev_hash,
377 &borsh::to_vec(&self.inner_lite).expect("Failed to serialize"),
378 &borsh::to_vec(&self.inner_rest).expect("Failed to serialize"),
379 );
380 }
381}
382
383impl BlockHeaderV4 {
384 pub fn init(&mut self) {
385 self.hash = BlockHeader::compute_hash(
386 self.prev_hash,
387 &borsh::to_vec(&self.inner_lite).expect("Failed to serialize"),
388 &borsh::to_vec(&self.inner_rest).expect("Failed to serialize"),
389 );
390 }
391}
392
393#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq)]
396pub enum BlockHeader {
397 BlockHeaderV1(Arc<BlockHeaderV1>),
398 BlockHeaderV2(Arc<BlockHeaderV2>),
399 BlockHeaderV3(Arc<BlockHeaderV3>),
400 BlockHeaderV4(Arc<BlockHeaderV4>),
401}
402
403impl BlockHeader {
404 pub fn compute_inner_hash(inner_lite: &[u8], inner_rest: &[u8]) -> CryptoHash {
405 let hash_lite = hash(inner_lite);
406 let hash_rest = hash(inner_rest);
407 combine_hash(&hash_lite, &hash_rest)
408 }
409
410 pub fn compute_hash(prev_hash: CryptoHash, inner_lite: &[u8], inner_rest: &[u8]) -> CryptoHash {
411 let hash_inner = BlockHeader::compute_inner_hash(inner_lite, inner_rest);
412
413 combine_hash(&hash_inner, &prev_hash)
414 }
415
416 pub fn new(
417 this_epoch_protocol_version: ProtocolVersion,
418 next_epoch_protocol_version: ProtocolVersion,
419 height: BlockHeight,
420 prev_hash: CryptoHash,
421 block_body_hash: CryptoHash,
422 prev_state_root: MerkleHash,
423 prev_chunk_outgoing_receipts_root: MerkleHash,
424 chunk_headers_root: MerkleHash,
425 chunk_tx_root: MerkleHash,
426 outcome_root: MerkleHash,
427 timestamp: u64,
428 challenges_root: MerkleHash,
429 random_value: CryptoHash,
430 prev_validator_power_proposals: Vec<ValidatorPower>,
431 prev_validator_pledge_proposals: Vec<ValidatorPledge>,
432 chunk_mask: Vec<bool>,
433 block_ordinal: NumBlocks,
434 epoch_id: EpochId,
435 next_epoch_id: EpochId,
436 next_gas_price: Balance,
437 total_supply: Balance,
438 challenges_result: ChallengesResult,
439 signer: &dyn ValidatorSigner,
440 last_final_block: CryptoHash,
441 last_ds_final_block: CryptoHash,
442 epoch_sync_data_hash: Option<CryptoHash>,
443 approvals: Vec<Option<Box<Signature>>>,
444 next_bp_hash: CryptoHash,
445 block_merkle_root: CryptoHash,
446 prev_height: BlockHeight,
447 ) -> Self {
448 let inner_lite = BlockHeaderInnerLite {
449 height,
450 epoch_id,
451 next_epoch_id,
452 prev_state_root,
453 prev_outcome_root: outcome_root,
454 timestamp,
455 next_bp_hash,
456 block_merkle_root,
457 };
458 let last_header_v2_version =
462 crate::version::ProtocolFeature::BlockHeaderV3.protocol_version() - 1;
463 if next_epoch_protocol_version <= 29 {
466 let chunks_included = chunk_mask.iter().map(|val| *val as u64).sum::<u64>();
467 let inner_rest = BlockHeaderInnerRest {
468 prev_chunk_outgoing_receipts_root,
469 chunk_headers_root,
470 chunk_tx_root,
471 chunks_included,
472 challenges_root,
473 random_value,
474 prev_validator_power_proposals: prev_validator_power_proposals
475 .into_iter()
476 .map(|v| v.into_v1())
477 .collect(),
478 prev_validator_pledge_proposals: prev_validator_pledge_proposals
479 .into_iter()
480 .map(|v| v.into_v1())
481 .collect(),
482 chunk_mask,
483 next_gas_price,
484 total_supply,
485 challenges_result,
486 last_final_block,
487 last_ds_final_block,
488 approvals,
489 latest_protocol_version: PROTOCOL_VERSION,
490 };
491 let (hash, signature) = signer.sign_block_header_parts(
492 prev_hash,
493 &borsh::to_vec(&inner_lite).expect("Failed to serialize"),
494 &borsh::to_vec(&inner_rest).expect("Failed to serialize"),
495 );
496 Self::BlockHeaderV1(Arc::new(BlockHeaderV1 {
497 prev_hash,
498 inner_lite,
499 inner_rest,
500 signature,
501 hash,
502 }))
503 } else if this_epoch_protocol_version <= last_header_v2_version {
504 let inner_rest = BlockHeaderInnerRestV2 {
505 prev_chunk_outgoing_receipts_root,
506 chunk_headers_root,
507 chunk_tx_root,
508 challenges_root,
509 random_value,
510 prev_validator_power_proposals: prev_validator_power_proposals
511 .into_iter()
512 .map(|v| v.into_v1())
513 .collect(),
514 prev_validator_pledge_proposals: prev_validator_pledge_proposals
515 .into_iter()
516 .map(|v| v.into_v1())
517 .collect(),
518 chunk_mask,
519 next_gas_price,
520 total_supply,
521 challenges_result,
522 last_final_block,
523 last_ds_final_block,
524 approvals,
525 latest_protocol_version: PROTOCOL_VERSION,
526 };
527 let (hash, signature) = signer.sign_block_header_parts(
528 prev_hash,
529 &borsh::to_vec(&inner_lite).expect("Failed to serialize"),
530 &borsh::to_vec(&inner_rest).expect("Failed to serialize"),
531 );
532 Self::BlockHeaderV2(Arc::new(BlockHeaderV2 {
533 prev_hash,
534 inner_lite,
535 inner_rest,
536 signature,
537 hash,
538 }))
539 } else if !crate::checked_feature!("stable", BlockHeaderV4, this_epoch_protocol_version) {
540 let inner_rest = BlockHeaderInnerRestV3 {
541 prev_chunk_outgoing_receipts_root,
542 chunk_headers_root,
543 chunk_tx_root,
544 challenges_root,
545 random_value,
546 prev_validator_power_proposals,
547 prev_validator_pledge_proposals,
548 chunk_mask,
549 next_gas_price,
550 block_ordinal,
551 total_supply,
552 challenges_result,
553 last_final_block,
554 last_ds_final_block,
555 prev_height,
556 epoch_sync_data_hash,
557 approvals,
558 latest_protocol_version: get_protocol_version(next_epoch_protocol_version),
559 };
560 let (hash, signature) = signer.sign_block_header_parts(
561 prev_hash,
562 &borsh::to_vec(&inner_lite).expect("Failed to serialize"),
563 &borsh::to_vec(&inner_rest).expect("Failed to serialize"),
564 );
565 Self::BlockHeaderV3(Arc::new(BlockHeaderV3 {
566 prev_hash,
567 inner_lite,
568 inner_rest,
569 signature,
570 hash,
571 }))
572 } else {
573 let inner_rest = BlockHeaderInnerRestV4 {
574 block_body_hash,
575 prev_chunk_outgoing_receipts_root,
576 chunk_headers_root,
577 chunk_tx_root,
578 challenges_root,
579 random_value,
580 prev_validator_power_proposals,
581 prev_validator_pledge_proposals,
582 chunk_mask,
583 next_gas_price,
584 block_ordinal,
585 total_supply,
586 challenges_result,
587 last_final_block,
588 last_ds_final_block,
589 prev_height,
590 epoch_sync_data_hash,
591 approvals,
592 latest_protocol_version: get_protocol_version(next_epoch_protocol_version),
593 };
594 let (hash, signature) = signer.sign_block_header_parts(
595 prev_hash,
596 &borsh::to_vec(&inner_lite).expect("Failed to serialize"),
597 &borsh::to_vec(&inner_rest).expect("Failed to serialize"),
598 );
599 Self::BlockHeaderV4(Arc::new(BlockHeaderV4 {
600 prev_hash,
601 inner_lite,
602 inner_rest,
603 signature,
604 hash,
605 }))
606 }
607 }
608
609 pub fn genesis(
610 genesis_protocol_version: ProtocolVersion,
611 height: BlockHeight,
612 state_root: MerkleHash,
613 block_body_hash: CryptoHash,
614 prev_chunk_outgoing_receipts_root: MerkleHash,
615 chunk_headers_root: MerkleHash,
616 chunk_tx_root: MerkleHash,
617 num_shards: u64,
618 challenges_root: MerkleHash,
619 timestamp: DateTime<Utc>,
620 initial_gas_price: Balance,
621 initial_total_supply: Balance,
622 next_bp_hash: CryptoHash,
623 ) -> Self {
624 let chunks_included = if height == 0 { num_shards } else { 0 };
625 let inner_lite = BlockHeaderInnerLite {
626 height,
627 epoch_id: EpochId::default(),
628 next_epoch_id: EpochId::default(),
629 prev_state_root: state_root,
630 prev_outcome_root: CryptoHash::default(),
631 timestamp: to_timestamp(timestamp),
632 next_bp_hash,
633 block_merkle_root: CryptoHash::default(),
634 };
635 let last_header_v2_version =
636 crate::version::ProtocolFeature::BlockHeaderV3.protocol_version() - 1;
637 if genesis_protocol_version <= 29 {
638 let inner_rest = BlockHeaderInnerRest {
639 prev_chunk_outgoing_receipts_root,
640 chunk_headers_root,
641 chunk_tx_root,
642 chunks_included,
643 challenges_root,
644 random_value: CryptoHash::default(),
645 prev_validator_power_proposals: vec![],
646 prev_validator_pledge_proposals: vec![],
647 chunk_mask: vec![],
648 next_gas_price: initial_gas_price,
649 total_supply: initial_total_supply,
650 challenges_result: vec![],
651 last_final_block: CryptoHash::default(),
652 last_ds_final_block: CryptoHash::default(),
653 approvals: vec![],
654 latest_protocol_version: genesis_protocol_version,
655 };
656 let hash = BlockHeader::compute_hash(
657 CryptoHash::default(),
658 &borsh::to_vec(&inner_lite).expect("Failed to serialize"),
659 &borsh::to_vec(&inner_rest).expect("Failed to serialize"),
660 );
661 Self::BlockHeaderV1(Arc::new(BlockHeaderV1 {
662 prev_hash: CryptoHash::default(),
663 inner_lite,
664 inner_rest,
665 signature: Signature::empty(KeyType::ED25519),
666 hash,
667 }))
668 } else if genesis_protocol_version <= last_header_v2_version {
669 let inner_rest = BlockHeaderInnerRestV2 {
670 prev_chunk_outgoing_receipts_root,
671 chunk_headers_root,
672 chunk_tx_root,
673 challenges_root,
674 random_value: CryptoHash::default(),
675 prev_validator_power_proposals: vec![],
676 prev_validator_pledge_proposals: vec![],
677 chunk_mask: vec![true; chunks_included as usize],
678 next_gas_price: initial_gas_price,
679 total_supply: initial_total_supply,
680 challenges_result: vec![],
681 last_final_block: CryptoHash::default(),
682 last_ds_final_block: CryptoHash::default(),
683 approvals: vec![],
684 latest_protocol_version: genesis_protocol_version,
685 };
686 let hash = BlockHeader::compute_hash(
687 CryptoHash::default(),
688 &borsh::to_vec(&inner_lite).expect("Failed to serialize"),
689 &borsh::to_vec(&inner_rest).expect("Failed to serialize"),
690 );
691 Self::BlockHeaderV2(Arc::new(BlockHeaderV2 {
692 prev_hash: CryptoHash::default(),
693 inner_lite,
694 inner_rest,
695 signature: Signature::empty(KeyType::ED25519),
696 hash,
697 }))
698 } else if !crate::checked_feature!("stable", BlockHeaderV4, genesis_protocol_version) {
699 let inner_rest = BlockHeaderInnerRestV3 {
700 prev_chunk_outgoing_receipts_root,
701 chunk_headers_root,
702 chunk_tx_root,
703 challenges_root,
704 random_value: CryptoHash::default(),
705 prev_validator_power_proposals: vec![],
706 prev_validator_pledge_proposals: vec![],
707 chunk_mask: vec![true; chunks_included as usize],
708 block_ordinal: 1, next_gas_price: initial_gas_price,
710 total_supply: initial_total_supply,
711 challenges_result: vec![],
712 last_final_block: CryptoHash::default(),
713 last_ds_final_block: CryptoHash::default(),
714 prev_height: 0,
715 epoch_sync_data_hash: None, approvals: vec![],
717 latest_protocol_version: genesis_protocol_version,
718 };
719 let hash = BlockHeader::compute_hash(
720 CryptoHash::default(),
721 &borsh::to_vec(&inner_lite).expect("Failed to serialize"),
722 &borsh::to_vec(&inner_rest).expect("Failed to serialize"),
723 );
724 Self::BlockHeaderV3(Arc::new(BlockHeaderV3 {
725 prev_hash: CryptoHash::default(),
726 inner_lite,
727 inner_rest,
728 signature: Signature::empty(KeyType::ED25519),
729 hash,
730 }))
731 } else {
732 let inner_rest = BlockHeaderInnerRestV4 {
733 prev_chunk_outgoing_receipts_root,
734 chunk_headers_root,
735 chunk_tx_root,
736 challenges_root,
737 block_body_hash,
738 random_value: CryptoHash::default(),
739 prev_validator_power_proposals: vec![],
740 prev_validator_pledge_proposals: vec![],
741 chunk_mask: vec![true; chunks_included as usize],
742 block_ordinal: 1, next_gas_price: initial_gas_price,
744 total_supply: initial_total_supply,
745 challenges_result: vec![],
746 last_final_block: CryptoHash::default(),
747 last_ds_final_block: CryptoHash::default(),
748 prev_height: 0,
749 epoch_sync_data_hash: None, approvals: vec![],
751 latest_protocol_version: genesis_protocol_version,
752 };
753 let hash = BlockHeader::compute_hash(
754 CryptoHash::default(),
755 &borsh::to_vec(&inner_lite).expect("Failed to serialize"),
756 &borsh::to_vec(&inner_rest).expect("Failed to serialize"),
757 );
758 Self::BlockHeaderV4(Arc::new(BlockHeaderV4 {
759 prev_hash: CryptoHash::default(),
760 inner_lite,
761 inner_rest,
762 signature: Signature::empty(KeyType::ED25519),
763 hash,
764 }))
765 }
766 }
767
768 #[inline]
769 pub fn hash(&self) -> &CryptoHash {
770 match self {
771 BlockHeader::BlockHeaderV1(header) => &header.hash,
772 BlockHeader::BlockHeaderV2(header) => &header.hash,
773 BlockHeader::BlockHeaderV3(header) => &header.hash,
774 BlockHeader::BlockHeaderV4(header) => &header.hash,
775 }
776 }
777
778 #[inline]
779 pub fn prev_hash(&self) -> &CryptoHash {
780 match self {
781 BlockHeader::BlockHeaderV1(header) => &header.prev_hash,
782 BlockHeader::BlockHeaderV2(header) => &header.prev_hash,
783 BlockHeader::BlockHeaderV3(header) => &header.prev_hash,
784 BlockHeader::BlockHeaderV4(header) => &header.prev_hash,
785 }
786 }
787
788 #[inline]
789 pub fn signature(&self) -> &Signature {
790 match self {
791 BlockHeader::BlockHeaderV1(header) => &header.signature,
792 BlockHeader::BlockHeaderV2(header) => &header.signature,
793 BlockHeader::BlockHeaderV3(header) => &header.signature,
794 BlockHeader::BlockHeaderV4(header) => &header.signature,
795 }
796 }
797
798 #[inline]
799 pub fn height(&self) -> BlockHeight {
800 match self {
801 BlockHeader::BlockHeaderV1(header) => header.inner_lite.height,
802 BlockHeader::BlockHeaderV2(header) => header.inner_lite.height,
803 BlockHeader::BlockHeaderV3(header) => header.inner_lite.height,
804 BlockHeader::BlockHeaderV4(header) => header.inner_lite.height,
805 }
806 }
807
808 #[inline]
809 pub fn prev_height(&self) -> Option<BlockHeight> {
810 match self {
811 BlockHeader::BlockHeaderV1(_) => None,
812 BlockHeader::BlockHeaderV2(_) => None,
813 BlockHeader::BlockHeaderV3(header) => Some(header.inner_rest.prev_height),
814 BlockHeader::BlockHeaderV4(header) => Some(header.inner_rest.prev_height),
815 }
816 }
817
818 #[inline]
819 pub fn epoch_id(&self) -> &EpochId {
820 match self {
821 BlockHeader::BlockHeaderV1(header) => &header.inner_lite.epoch_id,
822 BlockHeader::BlockHeaderV2(header) => &header.inner_lite.epoch_id,
823 BlockHeader::BlockHeaderV3(header) => &header.inner_lite.epoch_id,
824 BlockHeader::BlockHeaderV4(header) => &header.inner_lite.epoch_id,
825 }
826 }
827
828 #[inline]
829 pub fn next_epoch_id(&self) -> &EpochId {
830 match self {
831 BlockHeader::BlockHeaderV1(header) => &header.inner_lite.next_epoch_id,
832 BlockHeader::BlockHeaderV2(header) => &header.inner_lite.next_epoch_id,
833 BlockHeader::BlockHeaderV3(header) => &header.inner_lite.next_epoch_id,
834 BlockHeader::BlockHeaderV4(header) => &header.inner_lite.next_epoch_id,
835 }
836 }
837
838 #[inline]
839 pub fn prev_state_root(&self) -> &MerkleHash {
840 match self {
841 BlockHeader::BlockHeaderV1(header) => &header.inner_lite.prev_state_root,
842 BlockHeader::BlockHeaderV2(header) => &header.inner_lite.prev_state_root,
843 BlockHeader::BlockHeaderV3(header) => &header.inner_lite.prev_state_root,
844 BlockHeader::BlockHeaderV4(header) => &header.inner_lite.prev_state_root,
845 }
846 }
847
848 #[inline]
849 pub fn prev_chunk_outgoing_receipts_root(&self) -> &MerkleHash {
850 match self {
851 BlockHeader::BlockHeaderV1(header) => {
852 &header.inner_rest.prev_chunk_outgoing_receipts_root
853 }
854 BlockHeader::BlockHeaderV2(header) => {
855 &header.inner_rest.prev_chunk_outgoing_receipts_root
856 }
857 BlockHeader::BlockHeaderV3(header) => {
858 &header.inner_rest.prev_chunk_outgoing_receipts_root
859 }
860 BlockHeader::BlockHeaderV4(header) => {
861 &header.inner_rest.prev_chunk_outgoing_receipts_root
862 }
863 }
864 }
865
866 #[inline]
867 pub fn chunk_headers_root(&self) -> &MerkleHash {
868 match self {
869 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.chunk_headers_root,
870 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.chunk_headers_root,
871 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.chunk_headers_root,
872 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.chunk_headers_root,
873 }
874 }
875
876 #[inline]
877 pub fn chunk_tx_root(&self) -> &MerkleHash {
878 match self {
879 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.chunk_tx_root,
880 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.chunk_tx_root,
881 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.chunk_tx_root,
882 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.chunk_tx_root,
883 }
884 }
885
886 pub fn chunks_included(&self) -> u64 {
887 let mask = match self {
888 BlockHeader::BlockHeaderV1(header) => return header.inner_rest.chunks_included,
889 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.chunk_mask,
890 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.chunk_mask,
891 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.chunk_mask,
892 };
893 mask.iter().map(|&x| u64::from(x)).sum::<u64>()
894 }
895
896 #[inline]
897 pub fn challenges_root(&self) -> &MerkleHash {
898 match self {
899 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.challenges_root,
900 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.challenges_root,
901 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.challenges_root,
902 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.challenges_root,
903 }
904 }
905
906 #[inline]
907 pub fn outcome_root(&self) -> &MerkleHash {
908 match self {
909 BlockHeader::BlockHeaderV1(header) => &header.inner_lite.prev_outcome_root,
910 BlockHeader::BlockHeaderV2(header) => &header.inner_lite.prev_outcome_root,
911 BlockHeader::BlockHeaderV3(header) => &header.inner_lite.prev_outcome_root,
912 BlockHeader::BlockHeaderV4(header) => &header.inner_lite.prev_outcome_root,
913 }
914 }
915
916 #[inline]
917 pub fn block_body_hash(&self) -> Option<CryptoHash> {
918 match self {
919 BlockHeader::BlockHeaderV1(_) => None,
920 BlockHeader::BlockHeaderV2(_) => None,
921 BlockHeader::BlockHeaderV3(_) => None,
922 BlockHeader::BlockHeaderV4(header) => Some(header.inner_rest.block_body_hash),
923 }
924 }
925
926 #[inline]
927 pub fn raw_timestamp(&self) -> u64 {
928 match self {
929 BlockHeader::BlockHeaderV1(header) => header.inner_lite.timestamp,
930 BlockHeader::BlockHeaderV2(header) => header.inner_lite.timestamp,
931 BlockHeader::BlockHeaderV3(header) => header.inner_lite.timestamp,
932 BlockHeader::BlockHeaderV4(header) => header.inner_lite.timestamp,
933 }
934 }
935
936 #[inline]
937 pub fn prev_validator_power_proposals(&self) -> ValidatorPowerIter {
938 match self {
939 BlockHeader::BlockHeaderV1(header) => {
940 ValidatorPowerIter::v1(&header.inner_rest.prev_validator_power_proposals)
941 }
942 BlockHeader::BlockHeaderV2(header) => {
943 ValidatorPowerIter::v1(&header.inner_rest.prev_validator_power_proposals)
944 }
945 BlockHeader::BlockHeaderV3(header) => {
946 ValidatorPowerIter::new(&header.inner_rest.prev_validator_power_proposals)
947 }
948 BlockHeader::BlockHeaderV4(header) => {
949 ValidatorPowerIter::new(&header.inner_rest.prev_validator_power_proposals)
950 }
951 }
952 }
953
954 #[inline]
955 pub fn prev_validator_pledge_proposals(&self) -> ValidatorPledgeIter {
956 match self {
957 BlockHeader::BlockHeaderV1(header) => {
958 ValidatorPledgeIter::v1(&header.inner_rest.prev_validator_pledge_proposals)
959 }
960 BlockHeader::BlockHeaderV2(header) => {
961 ValidatorPledgeIter::v1(&header.inner_rest.prev_validator_pledge_proposals)
962 }
963 BlockHeader::BlockHeaderV3(header) => {
964 ValidatorPledgeIter::new(&header.inner_rest.prev_validator_pledge_proposals)
965 }
966 BlockHeader::BlockHeaderV4(header) => {
967 ValidatorPledgeIter::new(&header.inner_rest.prev_validator_pledge_proposals)
968 }
969 }
970 }
971
972 #[inline]
973 pub fn chunk_mask(&self) -> &[bool] {
974 match self {
975 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.chunk_mask,
976 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.chunk_mask,
977 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.chunk_mask,
978 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.chunk_mask,
979 }
980 }
981
982 #[inline]
983 pub fn block_ordinal(&self) -> NumBlocks {
984 match self {
985 BlockHeader::BlockHeaderV1(_) => 0, BlockHeader::BlockHeaderV2(_) => 0, BlockHeader::BlockHeaderV3(header) => header.inner_rest.block_ordinal,
988 BlockHeader::BlockHeaderV4(header) => header.inner_rest.block_ordinal,
989 }
990 }
991
992 #[inline]
993 pub fn next_gas_price(&self) -> Balance {
994 match self {
995 BlockHeader::BlockHeaderV1(header) => header.inner_rest.next_gas_price,
996 BlockHeader::BlockHeaderV2(header) => header.inner_rest.next_gas_price,
997 BlockHeader::BlockHeaderV3(header) => header.inner_rest.next_gas_price,
998 BlockHeader::BlockHeaderV4(header) => header.inner_rest.next_gas_price,
999 }
1000 }
1001
1002 #[inline]
1003 pub fn total_supply(&self) -> Balance {
1004 match self {
1005 BlockHeader::BlockHeaderV1(header) => header.inner_rest.total_supply,
1006 BlockHeader::BlockHeaderV2(header) => header.inner_rest.total_supply,
1007 BlockHeader::BlockHeaderV3(header) => header.inner_rest.total_supply,
1008 BlockHeader::BlockHeaderV4(header) => header.inner_rest.total_supply,
1009 }
1010 }
1011
1012 #[inline]
1013 pub fn random_value(&self) -> &CryptoHash {
1014 match self {
1015 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.random_value,
1016 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.random_value,
1017 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.random_value,
1018 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.random_value,
1019 }
1020 }
1021
1022 #[inline]
1023 pub fn last_final_block(&self) -> &CryptoHash {
1024 match self {
1025 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.last_final_block,
1026 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.last_final_block,
1027 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.last_final_block,
1028 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.last_final_block,
1029 }
1030 }
1031
1032 #[inline]
1033 pub fn last_ds_final_block(&self) -> &CryptoHash {
1034 match self {
1035 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.last_ds_final_block,
1036 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.last_ds_final_block,
1037 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.last_ds_final_block,
1038 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.last_ds_final_block,
1039 }
1040 }
1041
1042 #[inline]
1043 pub fn challenges_result(&self) -> &ChallengesResult {
1044 match self {
1045 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.challenges_result,
1046 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.challenges_result,
1047 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.challenges_result,
1048 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.challenges_result,
1049 }
1050 }
1051
1052 #[inline]
1053 pub fn next_bp_hash(&self) -> &CryptoHash {
1054 match self {
1055 BlockHeader::BlockHeaderV1(header) => &header.inner_lite.next_bp_hash,
1056 BlockHeader::BlockHeaderV2(header) => &header.inner_lite.next_bp_hash,
1057 BlockHeader::BlockHeaderV3(header) => &header.inner_lite.next_bp_hash,
1058 BlockHeader::BlockHeaderV4(header) => &header.inner_lite.next_bp_hash,
1059 }
1060 }
1061
1062 #[inline]
1063 pub fn block_merkle_root(&self) -> &CryptoHash {
1064 match self {
1065 BlockHeader::BlockHeaderV1(header) => &header.inner_lite.block_merkle_root,
1066 BlockHeader::BlockHeaderV2(header) => &header.inner_lite.block_merkle_root,
1067 BlockHeader::BlockHeaderV3(header) => &header.inner_lite.block_merkle_root,
1068 BlockHeader::BlockHeaderV4(header) => &header.inner_lite.block_merkle_root,
1069 }
1070 }
1071
1072 #[inline]
1073 pub fn epoch_sync_data_hash(&self) -> Option<CryptoHash> {
1074 match self {
1075 BlockHeader::BlockHeaderV1(_) => None,
1076 BlockHeader::BlockHeaderV2(_) => None,
1077 BlockHeader::BlockHeaderV3(header) => header.inner_rest.epoch_sync_data_hash,
1078 BlockHeader::BlockHeaderV4(header) => header.inner_rest.epoch_sync_data_hash,
1079 }
1080 }
1081
1082 #[inline]
1083 pub fn approvals(&self) -> &[Option<Box<Signature>>] {
1084 match self {
1085 BlockHeader::BlockHeaderV1(header) => &header.inner_rest.approvals,
1086 BlockHeader::BlockHeaderV2(header) => &header.inner_rest.approvals,
1087 BlockHeader::BlockHeaderV3(header) => &header.inner_rest.approvals,
1088 BlockHeader::BlockHeaderV4(header) => &header.inner_rest.approvals,
1089 }
1090 }
1091
1092 pub fn verify_block_producer(&self, public_key: &PublicKey) -> bool {
1094 self.signature().verify(self.hash().as_ref(), public_key)
1095 }
1096
1097 pub fn timestamp(&self) -> DateTime<Utc> {
1098 from_timestamp(self.raw_timestamp())
1099 }
1100
1101 pub fn num_approvals(&self) -> u64 {
1102 self.approvals().iter().filter(|x| x.is_some()).count() as u64
1103 }
1104
1105 pub fn verify_chunks_included(&self) -> bool {
1106 match self {
1107 BlockHeader::BlockHeaderV1(header) => {
1108 header.inner_rest.chunk_mask.iter().map(|&x| u64::from(x)).sum::<u64>()
1109 == header.inner_rest.chunks_included
1110 }
1111 BlockHeader::BlockHeaderV2(_header) => true,
1112 BlockHeader::BlockHeaderV3(_header) => true,
1113 BlockHeader::BlockHeaderV4(_header) => true,
1114 }
1115 }
1116
1117 #[inline]
1118 pub fn latest_protocol_version(&self) -> u32 {
1119 match self {
1120 BlockHeader::BlockHeaderV1(header) => header.inner_rest.latest_protocol_version,
1121 BlockHeader::BlockHeaderV2(header) => header.inner_rest.latest_protocol_version,
1122 BlockHeader::BlockHeaderV3(header) => header.inner_rest.latest_protocol_version,
1123 BlockHeader::BlockHeaderV4(header) => header.inner_rest.latest_protocol_version,
1124 }
1125 }
1126
1127 pub fn inner_lite_bytes(&self) -> Vec<u8> {
1128 match self {
1129 BlockHeader::BlockHeaderV1(header) => {
1130 borsh::to_vec(&header.inner_lite).expect("Failed to serialize")
1131 }
1132 BlockHeader::BlockHeaderV2(header) => {
1133 borsh::to_vec(&header.inner_lite).expect("Failed to serialize")
1134 }
1135 BlockHeader::BlockHeaderV3(header) => {
1136 borsh::to_vec(&header.inner_lite).expect("Failed to serialize")
1137 }
1138 BlockHeader::BlockHeaderV4(header) => {
1139 borsh::to_vec(&header.inner_lite).expect("Failed to serialize")
1140 }
1141 }
1142 }
1143
1144 pub fn inner_rest_bytes(&self) -> Vec<u8> {
1145 match self {
1146 BlockHeader::BlockHeaderV1(header) => {
1147 borsh::to_vec(&header.inner_rest).expect("Failed to serialize")
1148 }
1149 BlockHeader::BlockHeaderV2(header) => {
1150 borsh::to_vec(&header.inner_rest).expect("Failed to serialize")
1151 }
1152 BlockHeader::BlockHeaderV3(header) => {
1153 borsh::to_vec(&header.inner_rest).expect("Failed to serialize")
1154 }
1155 BlockHeader::BlockHeaderV4(header) => {
1156 borsh::to_vec(&header.inner_rest).expect("Failed to serialize")
1157 }
1158 }
1159 }
1160}