1use crate::account::{AccessKey, Account};
2use crate::action::RegisterRsa2048KeysAction;
3use crate::challenge::ChallengesResult;
4use crate::errors::EpochError;
5pub use crate::hash::CryptoHash;
6use crate::receipt::Receipt;
7use crate::serialize::dec_format;
8use crate::trie_key::TrieKey;
9use borsh::{BorshDeserialize, BorshSerialize};
10use once_cell::sync::Lazy;
11use serde_with::base64::Base64;
12use serde_with::serde_as;
13use std::sync::Arc;
14use unc_crypto::PublicKey;
15pub use unc_primitives_core::types::*;
17pub use unc_vm_runner::logic::TrieNodesCount;
18
19pub type StateRoot = CryptoHash;
21
22#[derive(
24 serde::Serialize, serde::Deserialize, Default, Clone, Debug, PartialEq, Eq, arbitrary::Arbitrary,
25)]
26pub enum Finality {
27 #[serde(rename = "optimistic")]
28 None,
29 #[serde(rename = "unc-final")]
30 DoomSlug,
31 #[serde(rename = "final")]
32 #[default]
33 Final,
34}
35
36#[derive(Debug, serde::Serialize, serde::Deserialize)]
37pub struct AccountWithPublicKey {
38 pub account_id: AccountId,
39 pub public_key: PublicKey,
40}
41
42#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, Eq, PartialEq)]
44pub struct AccountInfo {
45 pub account_id: AccountId,
46 pub public_key: PublicKey,
47 #[serde(with = "dec_format")]
48 pub pledging: Balance,
49 #[serde(with = "dec_format")]
50 pub power: Power,
51}
52
53#[serde_as]
58#[derive(
59 serde::Serialize,
60 serde::Deserialize,
61 Clone,
62 Debug,
63 PartialEq,
64 Eq,
65 derive_more::Deref,
66 derive_more::From,
67 derive_more::Into,
68 BorshSerialize,
69 BorshDeserialize,
70)]
71#[serde(transparent)]
72pub struct StoreKey(#[serde_as(as = "Base64")] Vec<u8>);
73
74#[serde_as]
79#[derive(
80 serde::Serialize,
81 serde::Deserialize,
82 Clone,
83 Debug,
84 PartialEq,
85 Eq,
86 derive_more::Deref,
87 derive_more::From,
88 derive_more::Into,
89 BorshSerialize,
90 BorshDeserialize,
91)]
92#[serde(transparent)]
93pub struct StoreValue(#[serde_as(as = "Base64")] Vec<u8>);
94
95#[serde_as]
101#[derive(
102 serde::Serialize,
103 serde::Deserialize,
104 Clone,
105 Debug,
106 PartialEq,
107 Eq,
108 derive_more::Deref,
109 derive_more::From,
110 derive_more::Into,
111 BorshSerialize,
112 BorshDeserialize,
113)]
114#[serde(transparent)]
115pub struct FunctionArgs(#[serde_as(as = "Base64")] Vec<u8>);
116
117#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
119pub enum StateChangeKind {
120 AccountTouched { account_id: AccountId },
121 AccessKeyTouched { account_id: AccountId },
122 DataTouched { account_id: AccountId },
123 ContractCodeTouched { account_id: AccountId },
124 RsaKeyTouched { account_id: AccountId },
125}
126
127pub type StateChangesKinds = Vec<StateChangeKind>;
128
129#[easy_ext::ext(StateChangesKindsExt)]
130impl StateChangesKinds {
131 pub fn from_changes(
132 raw_changes: &mut dyn Iterator<Item = Result<RawStateChangesWithTrieKey, std::io::Error>>,
133 ) -> Result<StateChangesKinds, std::io::Error> {
134 raw_changes
135 .filter_map(|raw_change| {
136 let RawStateChangesWithTrieKey { trie_key, .. } = match raw_change {
137 Ok(p) => p,
138 Err(e) => return Some(Err(e)),
139 };
140 match trie_key {
141 TrieKey::Account { account_id } => {
142 Some(Ok(StateChangeKind::AccountTouched { account_id }))
143 }
144 TrieKey::ContractCode { account_id } => {
145 Some(Ok(StateChangeKind::ContractCodeTouched { account_id }))
146 }
147 TrieKey::AccessKey { account_id, .. } => {
148 Some(Ok(StateChangeKind::AccessKeyTouched { account_id }))
149 }
150 TrieKey::ContractData { account_id, .. } => {
151 Some(Ok(StateChangeKind::DataTouched { account_id }))
152 }
153 TrieKey::Rsa2048Keys { account_id, .. } => {
154 Some(Ok(StateChangeKind::RsaKeyTouched { account_id }))
155 }
156 _ => None,
157 }
158 })
159 .collect()
160 }
161}
162
163#[derive(Debug, Clone, BorshSerialize, BorshDeserialize, PartialEq)]
165pub enum StateChangeCause {
166 NotWritableToDisk,
170 InitialState,
173 TransactionProcessing { tx_hash: CryptoHash },
175 ActionReceiptProcessingStarted { receipt_hash: CryptoHash },
178 ActionReceiptGasReward { receipt_hash: CryptoHash },
180 ReceiptProcessing { receipt_hash: CryptoHash },
182 PostponedReceipt { receipt_hash: CryptoHash },
187 UpdatedDelayedReceipts,
190 ValidatorAccountsUpdate,
193 Migration,
196 Resharding,
198}
199
200#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
202pub struct RawStateChange {
203 pub cause: StateChangeCause,
204 pub data: Option<Vec<u8>>,
205}
206
207#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
209pub struct RawStateChangesWithTrieKey {
210 pub trie_key: TrieKey,
211 pub changes: Vec<RawStateChange>,
212}
213
214#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
216pub struct ConsolidatedStateChange {
217 pub trie_key: TrieKey,
218 pub value: Option<Vec<u8>>,
219}
220
221#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
222pub struct StateChangesForResharding {
223 pub changes: Vec<ConsolidatedStateChange>,
224 pub processed_delayed_receipts: Vec<Receipt>,
228}
229
230impl StateChangesForResharding {
231 pub fn from_raw_state_changes(
232 changes: &[RawStateChangesWithTrieKey],
233 processed_delayed_receipts: Vec<Receipt>,
234 ) -> Self {
235 let changes = changes
236 .iter()
237 .map(|RawStateChangesWithTrieKey { trie_key, changes }| {
238 let value = changes.last().expect("state_changes must not be empty").data.clone();
239 ConsolidatedStateChange { trie_key: trie_key.clone(), value }
240 })
241 .collect();
242 Self { changes, processed_delayed_receipts }
243 }
244}
245
246pub type RawStateChanges = std::collections::BTreeMap<Vec<u8>, RawStateChangesWithTrieKey>;
248
249#[derive(Debug)]
250pub enum StateChangesRequest {
251 AccountChanges { account_ids: Vec<AccountId> },
252 SingleAccessKeyChanges { keys: Vec<AccountWithPublicKey> },
253 AllAccessKeyChanges { account_ids: Vec<AccountId> },
254 ContractCodeChanges { account_ids: Vec<AccountId> },
255 DataChanges { account_ids: Vec<AccountId>, key_prefix: StoreKey },
256}
257
258#[derive(Debug)]
259pub enum StateChangeValue {
260 AccountUpdate {
261 account_id: AccountId,
262 account: Account,
263 },
264 AccountDeletion {
265 account_id: AccountId,
266 },
267 AccessKeyUpdate {
268 account_id: AccountId,
269 public_key: PublicKey,
270 access_key: AccessKey,
271 },
272 AccessKeyDeletion {
273 account_id: AccountId,
274 public_key: PublicKey,
275 },
276 DataUpdate {
277 account_id: AccountId,
278 key: StoreKey,
279 value: StoreValue,
280 },
281 DataDeletion {
282 account_id: AccountId,
283 key: StoreKey,
284 },
285 ContractCodeUpdate {
286 account_id: AccountId,
287 code: Vec<u8>,
288 },
289 ContractCodeDeletion {
290 account_id: AccountId,
291 },
292 RsaKeyUpdate {
293 account_id: AccountId,
294 public_key: PublicKey,
295 rsa_key: RegisterRsa2048KeysAction,
296 },
297 RsaKeyDeletion {
298 account_id: AccountId,
299 public_key: PublicKey,
300 },
301}
302
303impl StateChangeValue {
304 pub fn affected_account_id(&self) -> &AccountId {
305 match &self {
306 StateChangeValue::AccountUpdate { account_id, .. }
307 | StateChangeValue::AccountDeletion { account_id }
308 | StateChangeValue::AccessKeyUpdate { account_id, .. }
309 | StateChangeValue::AccessKeyDeletion { account_id, .. }
310 | StateChangeValue::DataUpdate { account_id, .. }
311 | StateChangeValue::DataDeletion { account_id, .. }
312 | StateChangeValue::ContractCodeUpdate { account_id, .. }
313 | StateChangeValue::RsaKeyUpdate { account_id, .. }
314 | StateChangeValue::RsaKeyDeletion { account_id, .. }
315 | StateChangeValue::ContractCodeDeletion { account_id } => account_id,
316 }
317 }
318}
319
320#[derive(Debug)]
321pub struct StateChangeWithCause {
322 pub cause: StateChangeCause,
323 pub value: StateChangeValue,
324}
325
326pub type StateChanges = Vec<StateChangeWithCause>;
327
328#[easy_ext::ext(StateChangesExt)]
329impl StateChanges {
330 pub fn from_changes(
331 raw_changes: impl Iterator<Item = Result<RawStateChangesWithTrieKey, std::io::Error>>,
332 ) -> Result<StateChanges, std::io::Error> {
333 let mut state_changes = Self::new();
334
335 for raw_change in raw_changes {
336 let RawStateChangesWithTrieKey { trie_key, changes } = raw_change?;
337
338 match trie_key {
339 TrieKey::Account { account_id } => state_changes.extend(changes.into_iter().map(
340 |RawStateChange { cause, data }| StateChangeWithCause {
341 cause,
342 value: if let Some(change_data) = data {
343 StateChangeValue::AccountUpdate {
344 account_id: account_id.clone(),
345 account: <_>::try_from_slice(&change_data).expect(
346 "Failed to parse internally stored account information",
347 ),
348 }
349 } else {
350 StateChangeValue::AccountDeletion { account_id: account_id.clone() }
351 },
352 },
353 )),
354 TrieKey::AccessKey { account_id, public_key } => {
355 state_changes.extend(changes.into_iter().map(
356 |RawStateChange { cause, data }| StateChangeWithCause {
357 cause,
358 value: if let Some(change_data) = data {
359 StateChangeValue::AccessKeyUpdate {
360 account_id: account_id.clone(),
361 public_key: public_key.clone(),
362 access_key: <_>::try_from_slice(&change_data)
363 .expect("Failed to parse internally stored access key"),
364 }
365 } else {
366 StateChangeValue::AccessKeyDeletion {
367 account_id: account_id.clone(),
368 public_key: public_key.clone(),
369 }
370 },
371 },
372 ))
373 }
374 TrieKey::ContractCode { account_id } => {
375 state_changes.extend(changes.into_iter().map(
376 |RawStateChange { cause, data }| StateChangeWithCause {
377 cause,
378 value: match data {
379 Some(change_data) => StateChangeValue::ContractCodeUpdate {
380 account_id: account_id.clone(),
381 code: change_data,
382 },
383 None => StateChangeValue::ContractCodeDeletion {
384 account_id: account_id.clone(),
385 },
386 },
387 },
388 ));
389 }
390 TrieKey::ContractData { account_id, key } => {
391 state_changes.extend(changes.into_iter().map(
392 |RawStateChange { cause, data }| StateChangeWithCause {
393 cause,
394 value: if let Some(change_data) = data {
395 StateChangeValue::DataUpdate {
396 account_id: account_id.clone(),
397 key: key.to_vec().into(),
398 value: change_data.into(),
399 }
400 } else {
401 StateChangeValue::DataDeletion {
402 account_id: account_id.clone(),
403 key: key.to_vec().into(),
404 }
405 },
406 },
407 ));
408 }
409 TrieKey::ReceivedData { .. } => {}
411 TrieKey::PostponedReceiptId { .. } => {}
412 TrieKey::PendingDataCount { .. } => {}
413 TrieKey::PostponedReceipt { .. } => {}
414 TrieKey::DelayedReceiptIndices => {}
415 TrieKey::DelayedReceipt { .. } => {}
416 TrieKey::Rsa2048Keys { account_id, public_key } => {
417 state_changes.extend(changes.into_iter().map(
418 |RawStateChange { cause, data }| StateChangeWithCause {
419 cause,
420 value: if let Some(change_data) = data {
421 StateChangeValue::AccessKeyUpdate {
422 account_id: account_id.clone(),
423 public_key: public_key.clone(),
424 access_key: <_>::try_from_slice(&change_data)
425 .expect("Failed to parse internally stored access key"),
426 }
427 } else {
428 StateChangeValue::AccessKeyDeletion {
429 account_id: account_id.clone(),
430 public_key: public_key.clone(),
431 }
432 },
433 },
434 ))
435 }
436 }
437 }
438
439 Ok(state_changes)
440 }
441 pub fn from_account_changes(
442 raw_changes: impl Iterator<Item = Result<RawStateChangesWithTrieKey, std::io::Error>>,
443 ) -> Result<StateChanges, std::io::Error> {
444 let state_changes = Self::from_changes(raw_changes)?;
445
446 Ok(state_changes
447 .into_iter()
448 .filter(|state_change| {
449 matches!(
450 state_change.value,
451 StateChangeValue::AccountUpdate { .. }
452 | StateChangeValue::AccountDeletion { .. }
453 )
454 })
455 .collect())
456 }
457
458 pub fn from_access_key_changes(
459 raw_changes: impl Iterator<Item = Result<RawStateChangesWithTrieKey, std::io::Error>>,
460 ) -> Result<StateChanges, std::io::Error> {
461 let state_changes = Self::from_changes(raw_changes)?;
462
463 Ok(state_changes
464 .into_iter()
465 .filter(|state_change| {
466 matches!(
467 state_change.value,
468 StateChangeValue::AccessKeyUpdate { .. }
469 | StateChangeValue::AccessKeyDeletion { .. }
470 )
471 })
472 .collect())
473 }
474
475 pub fn from_contract_code_changes(
476 raw_changes: impl Iterator<Item = Result<RawStateChangesWithTrieKey, std::io::Error>>,
477 ) -> Result<StateChanges, std::io::Error> {
478 let state_changes = Self::from_changes(raw_changes)?;
479
480 Ok(state_changes
481 .into_iter()
482 .filter(|state_change| {
483 matches!(
484 state_change.value,
485 StateChangeValue::ContractCodeUpdate { .. }
486 | StateChangeValue::ContractCodeDeletion { .. }
487 )
488 })
489 .collect())
490 }
491
492 pub fn from_data_changes(
493 raw_changes: impl Iterator<Item = Result<RawStateChangesWithTrieKey, std::io::Error>>,
494 ) -> Result<StateChanges, std::io::Error> {
495 let state_changes = Self::from_changes(raw_changes)?;
496
497 Ok(state_changes
498 .into_iter()
499 .filter(|state_change| {
500 matches!(
501 state_change.value,
502 StateChangeValue::DataUpdate { .. } | StateChangeValue::DataDeletion { .. }
503 )
504 })
505 .collect())
506 }
507}
508
509#[derive(PartialEq, Eq, Clone, Debug, BorshSerialize, BorshDeserialize, serde::Serialize)]
510pub struct StateRootNode {
511 pub data: Arc<[u8]>,
517
518 pub memory_usage: u64,
520}
521
522impl StateRootNode {
523 pub fn empty() -> Self {
524 static EMPTY: Lazy<Arc<[u8]>> = Lazy::new(|| Arc::new([]));
525 StateRootNode { data: EMPTY.clone(), memory_usage: 0 }
526 }
527}
528
529#[derive(
533 Debug,
534 Clone,
535 Default,
536 Hash,
537 Eq,
538 PartialEq,
539 PartialOrd,
540 Ord,
541 derive_more::AsRef,
542 BorshSerialize,
543 BorshDeserialize,
544 serde::Serialize,
545 serde::Deserialize,
546 arbitrary::Arbitrary,
547)]
548#[as_ref(forward)]
549pub struct EpochId(pub CryptoHash);
550
551impl std::str::FromStr for EpochId {
552 type Err = Box<dyn std::error::Error + Send + Sync>;
553
554 fn from_str(epoch_id_str: &str) -> Result<Self, Self::Err> {
556 Ok(EpochId(CryptoHash::from_str(epoch_id_str)?))
557 }
558}
559#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, PartialEq, Eq)]
566pub struct ApprovalPledge {
567 pub account_id: AccountId,
569 pub public_key: PublicKey,
571 pub pledge_this_epoch: Balance,
573 pub pledge_next_epoch: Balance,
575}
576
577pub mod validator_power_and_pledge {
578 use borsh::{BorshDeserialize, BorshSerialize};
579 use serde::Serialize;
580 use unc_crypto::PublicKey;
581 use unc_primitives_core::types::{AccountId, Balance, Power};
582
583 use super::ApprovalPledge;
584 pub use super::ValidatorPowerAndPledgeV1;
585
586 #[derive(
588 BorshSerialize, BorshDeserialize, Serialize, Debug, Clone, PartialEq, Eq, PartialOrd,
589 )]
590 #[serde(tag = "validator_power_and_pledge_struct_version")]
591 pub enum ValidatorPowerAndPledge {
592 V1(ValidatorPowerAndPledgeV1),
593 }
594 #[derive(Clone)]
595 pub struct ValidatorPowerAndPledgeIter<'a> {
596 collection: ValidatorPowerAndPledgeIterSource<'a>,
597 curr_index: usize,
598 len: usize,
599 }
600
601 impl<'a> ValidatorPowerAndPledgeIter<'a> {
602 pub fn empty() -> Self {
603 Self { collection: ValidatorPowerAndPledgeIterSource::V2(&[]), curr_index: 0, len: 0 }
604 }
605
606 pub fn v1(collection: &'a [ValidatorPowerAndPledgeV1]) -> Self {
607 Self {
608 collection: ValidatorPowerAndPledgeIterSource::V1(collection),
609 curr_index: 0,
610 len: collection.len(),
611 }
612 }
613
614 pub fn new(collection: &'a [ValidatorPowerAndPledge]) -> Self {
615 Self {
616 collection: ValidatorPowerAndPledgeIterSource::V2(collection),
617 curr_index: 0,
618 len: collection.len(),
619 }
620 }
621
622 pub fn len(&self) -> usize {
623 self.len
624 }
625 }
626
627 impl<'a> Iterator for ValidatorPowerAndPledgeIter<'a> {
628 type Item = ValidatorPowerAndPledge;
629
630 fn next(&mut self) -> Option<Self::Item> {
631 if self.curr_index < self.len {
632 let item = match self.collection {
633 ValidatorPowerAndPledgeIterSource::V1(collection) => {
634 ValidatorPowerAndPledge::V1(collection[self.curr_index].clone())
635 }
636 ValidatorPowerAndPledgeIterSource::V2(collection) => {
637 collection[self.curr_index].clone()
638 }
639 };
640 self.curr_index += 1;
641 Some(item)
642 } else {
643 None
644 }
645 }
646 }
647 #[derive(Clone)]
648 enum ValidatorPowerAndPledgeIterSource<'a> {
649 V1(&'a [ValidatorPowerAndPledgeV1]),
650 V2(&'a [ValidatorPowerAndPledge]),
651 }
652
653 impl ValidatorPowerAndPledge {
654 pub fn new_v1(
655 account_id: AccountId,
656 public_key: PublicKey,
657 power: Power,
658 pledge: Balance,
659 ) -> Self {
660 Self::V1(ValidatorPowerAndPledgeV1 { account_id, public_key, power, pledge })
661 }
662
663 pub fn new(
664 account_id: AccountId,
665 public_key: PublicKey,
666 power: Power,
667 pledge: Balance,
668 ) -> Self {
669 Self::new_v1(account_id, public_key, power, pledge)
670 }
671
672 pub fn into_v1(self) -> ValidatorPowerAndPledgeV1 {
673 match self {
674 Self::V1(v1) => v1,
675 }
676 }
677
678 #[inline]
679 pub fn account_and_pledge(self) -> (AccountId, Balance) {
680 match self {
681 Self::V1(v1) => (v1.account_id, v1.pledge),
682 }
683 }
684
685 #[inline]
686 pub fn account_and_power(self) -> (AccountId, Power) {
687 match self {
688 Self::V1(v1) => (v1.account_id, v1.power),
689 }
690 }
691
692 #[inline]
693 pub fn destructure(self) -> (AccountId, PublicKey, Power, Balance) {
694 match self {
695 Self::V1(v1) => (v1.account_id, v1.public_key, v1.power, v1.pledge),
696 }
697 }
698
699 #[inline]
700 pub fn take_account_id(self) -> AccountId {
701 match self {
702 Self::V1(v1) => v1.account_id,
703 }
704 }
705
706 #[inline]
707 pub fn account_id(&self) -> &AccountId {
708 match self {
709 Self::V1(v1) => &v1.account_id,
710 }
711 }
712
713 #[inline]
714 pub fn take_public_key(self) -> PublicKey {
715 match self {
716 Self::V1(v1) => v1.public_key,
717 }
718 }
719
720 #[inline]
721 pub fn public_key(&self) -> &PublicKey {
722 match self {
723 Self::V1(v1) => &v1.public_key,
724 }
725 }
726
727 #[inline]
728 pub fn power(&self) -> Power {
729 match self {
730 Self::V1(v1) => v1.power,
731 }
732 }
733
734 #[inline]
735 pub fn power_mut(&mut self) -> &mut Power {
736 match self {
737 Self::V1(v1) => &mut v1.power,
738 }
739 }
740
741 #[inline]
742 pub fn pledge(&self) -> Balance {
743 match self {
744 Self::V1(v1) => v1.pledge,
745 }
746 }
747
748 pub fn get_approval_pledge(&self, is_next_epoch: bool) -> ApprovalPledge {
749 ApprovalPledge {
750 account_id: self.account_id().clone(),
751 public_key: self.public_key().clone(),
752 pledge_this_epoch: if is_next_epoch { 0 } else { self.pledge() },
753 pledge_next_epoch: if is_next_epoch { self.pledge() } else { 0 },
754 }
755 }
756
757 pub fn num_mandates(&self, pledge_per_mandate: Balance) -> u16 {
778 u16::try_from(self.pledge() / pledge_per_mandate)
781 .expect("number of mandats should fit u16")
782 }
783
784 pub fn partial_mandate_weight(&self, pledge_per_mandate: Balance) -> Balance {
798 self.pledge() % pledge_per_mandate
799 }
800 }
801}
802
803pub mod validator_stake {
804 use borsh::{BorshDeserialize, BorshSerialize};
805 use serde::Serialize;
806 use unc_crypto::PublicKey;
807 use unc_primitives_core::types::{AccountId, Balance};
808
809 pub use super::ValidatorPledgeV1;
810
811 #[derive(BorshSerialize, BorshDeserialize, Serialize, Debug, Clone, PartialEq, Eq)]
813 #[serde(tag = "validator_validator_struct_version")]
814 pub enum ValidatorPledge {
815 V1(ValidatorPledgeV1),
816 }
817
818 pub struct ValidatorPledgeIter<'a> {
819 collection: ValidatorPledgeIterSource<'a>,
820 curr_index: usize,
821 len: usize,
822 }
823
824 impl<'a> ValidatorPledgeIter<'a> {
825 pub fn empty() -> Self {
826 Self { collection: ValidatorPledgeIterSource::V2(&[]), curr_index: 0, len: 0 }
827 }
828
829 pub fn v1(collection: &'a [ValidatorPledgeV1]) -> Self {
830 Self {
831 collection: ValidatorPledgeIterSource::V1(collection),
832 curr_index: 0,
833 len: collection.len(),
834 }
835 }
836
837 pub fn new(collection: &'a [ValidatorPledge]) -> Self {
838 Self {
839 collection: ValidatorPledgeIterSource::V2(collection),
840 curr_index: 0,
841 len: collection.len(),
842 }
843 }
844
845 pub fn len(&self) -> usize {
846 self.len
847 }
848 }
849
850 impl<'a> Iterator for ValidatorPledgeIter<'a> {
851 type Item = ValidatorPledge;
852
853 fn next(&mut self) -> Option<Self::Item> {
854 if self.curr_index < self.len {
855 let item = match self.collection {
856 ValidatorPledgeIterSource::V1(collection) => {
857 ValidatorPledge::V1(collection[self.curr_index].clone())
858 }
859 ValidatorPledgeIterSource::V2(collection) => {
860 collection[self.curr_index].clone()
861 }
862 };
863 self.curr_index += 1;
864 Some(item)
865 } else {
866 None
867 }
868 }
869 }
870
871 enum ValidatorPledgeIterSource<'a> {
872 V1(&'a [ValidatorPledgeV1]),
873 V2(&'a [ValidatorPledge]),
874 }
875
876 impl ValidatorPledge {
877 pub fn new_v1(account_id: AccountId, public_key: PublicKey, pledge: Balance) -> Self {
878 Self::V1(ValidatorPledgeV1 { account_id, public_key, pledge })
879 }
880
881 pub fn new(account_id: AccountId, public_key: PublicKey, pledge: Balance) -> Self {
882 Self::new_v1(account_id, public_key, pledge)
883 }
884
885 pub fn into_v1(self) -> ValidatorPledgeV1 {
886 match self {
887 Self::V1(v1) => v1,
888 }
889 }
890
891 #[inline]
892 pub fn account_and_pledge(self) -> (AccountId, Balance) {
893 match self {
894 Self::V1(v1) => (v1.account_id, v1.pledge),
895 }
896 }
897
898 #[inline]
899 pub fn destructure(self) -> (AccountId, PublicKey, Balance) {
900 match self {
901 Self::V1(v1) => (v1.account_id, v1.public_key, v1.pledge),
902 }
903 }
904
905 #[inline]
906 pub fn take_account_id(self) -> AccountId {
907 match self {
908 Self::V1(v1) => v1.account_id,
909 }
910 }
911
912 #[inline]
913 pub fn account_id(&self) -> &AccountId {
914 match self {
915 Self::V1(v1) => &v1.account_id,
916 }
917 }
918
919 #[inline]
920 pub fn take_public_key(self) -> PublicKey {
921 match self {
922 Self::V1(v1) => v1.public_key,
923 }
924 }
925
926 #[inline]
927 pub fn public_key(&self) -> &PublicKey {
928 match self {
929 Self::V1(v1) => &v1.public_key,
930 }
931 }
932
933 #[inline]
934 pub fn pledge(&self) -> Balance {
935 match self {
936 Self::V1(v1) => v1.pledge,
937 }
938 }
939
940 #[inline]
941 pub fn pledge_mut(&mut self) -> &mut Balance {
942 match self {
943 Self::V1(v1) => &mut v1.pledge,
944 }
945 }
946 }
947}
948#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, PartialEq, Eq)]
949pub struct ApprovalPower {
950 pub account_id: AccountId,
952 pub public_key: PublicKey,
954 pub power_this_epoch: Power,
956 pub power_next_epoch: Power,
957}
958
959pub mod validator_power {
960 use crate::types::ApprovalPower;
961 use borsh::{BorshDeserialize, BorshSerialize};
962 use serde::Serialize;
963 use unc_crypto::PublicKey;
964 use unc_primitives_core::types::{AccountId, Power};
965
966 pub use super::ValidatorPowerV1;
967
968 #[derive(BorshSerialize, BorshDeserialize, Serialize, Debug, Clone, PartialEq, Eq)]
970 #[serde(tag = "validator_power_struct_version")]
971 pub enum ValidatorPower {
972 V1(ValidatorPowerV1),
973 }
974
975 pub struct ValidatorPowerIter<'a> {
976 collection: ValidatorPowerIterSource<'a>,
977 curr_index: usize,
978 len: usize,
979 }
980
981 impl<'a> ValidatorPowerIter<'a> {
982 pub fn empty() -> Self {
983 Self { collection: ValidatorPowerIterSource::V2(&[]), curr_index: 0, len: 0 }
984 }
985
986 pub fn v1(collection: &'a [ValidatorPowerV1]) -> Self {
987 Self {
988 collection: ValidatorPowerIterSource::V1(collection),
989 curr_index: 0,
990 len: collection.len(),
991 }
992 }
993
994 pub fn new(collection: &'a [ValidatorPower]) -> Self {
995 Self {
996 collection: ValidatorPowerIterSource::V2(collection),
997 curr_index: 0,
998 len: collection.len(),
999 }
1000 }
1001
1002 pub fn len(&self) -> usize {
1003 self.len
1004 }
1005 }
1006
1007 impl<'a> Iterator for ValidatorPowerIter<'a> {
1008 type Item = ValidatorPower;
1009
1010 fn next(&mut self) -> Option<Self::Item> {
1011 if self.curr_index < self.len {
1012 let item = match self.collection {
1013 ValidatorPowerIterSource::V1(collection) => {
1014 ValidatorPower::V1(collection[self.curr_index].clone())
1015 }
1016 ValidatorPowerIterSource::V2(collection) => collection[self.curr_index].clone(),
1017 };
1018 self.curr_index += 1;
1019 Some(item)
1020 } else {
1021 None
1022 }
1023 }
1024 }
1025
1026 enum ValidatorPowerIterSource<'a> {
1027 V1(&'a [ValidatorPowerV1]),
1028 V2(&'a [ValidatorPower]),
1029 }
1030
1031 impl ValidatorPower {
1032 pub fn new_v1(account_id: AccountId, public_key: PublicKey, power: Power) -> Self {
1033 Self::V1(ValidatorPowerV1 { account_id, public_key, power })
1034 }
1035
1036 pub fn new(account_id: AccountId, public_key: PublicKey, power: Power) -> Self {
1037 Self::new_v1(account_id, public_key, power)
1038 }
1039
1040 pub fn into_v1(self) -> ValidatorPowerV1 {
1041 match self {
1042 Self::V1(v1) => v1,
1043 }
1044 }
1045
1046 #[inline]
1047 pub fn account_and_power(self) -> (AccountId, Power) {
1048 match self {
1049 Self::V1(v1) => (v1.account_id, v1.power),
1050 }
1051 }
1052
1053 #[inline]
1054 pub fn destructure(self) -> (AccountId, PublicKey, Power) {
1055 match self {
1056 Self::V1(v1) => (v1.account_id, v1.public_key, v1.power),
1057 }
1058 }
1059
1060 #[inline]
1061 pub fn take_account_id(self) -> AccountId {
1062 match self {
1063 Self::V1(v1) => v1.account_id,
1064 }
1065 }
1066
1067 #[inline]
1068 pub fn account_id(&self) -> &AccountId {
1069 match self {
1070 Self::V1(v1) => &v1.account_id,
1071 }
1072 }
1073
1074 #[inline]
1075 pub fn take_public_key(self) -> PublicKey {
1076 match self {
1077 Self::V1(v1) => v1.public_key,
1078 }
1079 }
1080
1081 #[inline]
1082 pub fn public_key(&self) -> &PublicKey {
1083 match self {
1084 Self::V1(v1) => &v1.public_key,
1085 }
1086 }
1087
1088 #[inline]
1089 pub fn power(&self) -> Power {
1090 match self {
1091 Self::V1(v1) => v1.power,
1092 }
1093 }
1094
1095 #[inline]
1096 pub fn power_mut(&mut self) -> &mut Power {
1097 match self {
1098 Self::V1(v1) => &mut v1.power,
1099 }
1100 }
1101
1102 pub fn get_approval_power(&self, is_next_epoch: bool) -> ApprovalPower {
1103 ApprovalPower {
1104 account_id: self.account_id().clone(),
1105 public_key: self.public_key().clone(),
1106 power_this_epoch: if is_next_epoch { 0 } else { self.power() },
1107 power_next_epoch: if is_next_epoch { self.power() } else { 0 },
1108 }
1109 }
1110 }
1111}
1112#[derive(
1114 BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, PartialEq, Eq, PartialOrd,
1115)]
1116pub struct ValidatorPowerAndPledgeV1 {
1117 pub account_id: AccountId,
1119 pub public_key: PublicKey,
1121 pub power: Power,
1123 pub pledge: Balance,
1125}
1126
1127#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, PartialEq, Eq)]
1129pub struct ValidatorPledgeV1 {
1130 pub account_id: AccountId,
1132 pub public_key: PublicKey,
1134 pub pledge: Balance,
1136}
1137
1138#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, PartialEq, Eq)]
1140pub struct ValidatorPowerV1 {
1141 pub account_id: AccountId,
1143 pub public_key: PublicKey,
1145 pub power: Power,
1147}
1148
1149#[derive(Debug, PartialEq, BorshSerialize, BorshDeserialize, Clone, Eq)]
1151pub struct BlockExtra {
1152 pub challenges_result: ChallengesResult,
1153}
1154
1155pub mod chunk_extra {
1156 use crate::types::validator_power::{ValidatorPower, ValidatorPowerIter};
1157 use crate::types::validator_stake::{ValidatorPledge, ValidatorPledgeIter};
1158 use crate::types::StateRoot;
1159 use borsh::{BorshDeserialize, BorshSerialize};
1160 use unc_primitives_core::hash::CryptoHash;
1161 use unc_primitives_core::types::{Balance, Gas};
1162
1163 pub use super::ChunkExtraV1;
1164
1165 #[derive(Debug, PartialEq, BorshSerialize, BorshDeserialize, Clone, Eq)]
1167 pub enum ChunkExtra {
1168 V1(ChunkExtraV1),
1169 V2(ChunkExtraV2),
1170 }
1171
1172 #[derive(Debug, PartialEq, BorshSerialize, BorshDeserialize, Clone, Eq)]
1173 pub struct ChunkExtraV2 {
1174 pub state_root: StateRoot,
1176 pub outcome_root: CryptoHash,
1178 pub validator_power_proposals: Vec<ValidatorPower>,
1180 pub validator_pledge_proposals: Vec<ValidatorPledge>,
1182 pub gas_used: Gas,
1184 pub gas_limit: Gas,
1186 pub balance_burnt: Balance,
1188 }
1189
1190 impl ChunkExtra {
1191 pub fn new_with_only_state_root(state_root: &StateRoot) -> Self {
1192 Self::new(state_root, CryptoHash::default(), vec![], vec![], 0, 0, 0)
1193 }
1194
1195 pub fn new(
1196 state_root: &StateRoot,
1197 outcome_root: CryptoHash,
1198 validator_power_proposals: Vec<ValidatorPower>,
1199 validator_pledge_proposals: Vec<ValidatorPledge>,
1200 gas_used: Gas,
1201 gas_limit: Gas,
1202 balance_burnt: Balance,
1203 ) -> Self {
1204 Self::V2(ChunkExtraV2 {
1205 state_root: *state_root,
1206 outcome_root,
1207 validator_power_proposals,
1208 validator_pledge_proposals,
1209 gas_used,
1210 gas_limit,
1211 balance_burnt,
1212 })
1213 }
1214
1215 #[inline]
1216 pub fn outcome_root(&self) -> &StateRoot {
1217 match self {
1218 Self::V1(v1) => &v1.outcome_root,
1219 Self::V2(v2) => &v2.outcome_root,
1220 }
1221 }
1222
1223 #[inline]
1224 pub fn state_root(&self) -> &StateRoot {
1225 match self {
1226 Self::V1(v1) => &v1.state_root,
1227 Self::V2(v2) => &v2.state_root,
1228 }
1229 }
1230
1231 #[inline]
1232 pub fn state_root_mut(&mut self) -> &mut StateRoot {
1233 match self {
1234 Self::V1(v1) => &mut v1.state_root,
1235 Self::V2(v2) => &mut v2.state_root,
1236 }
1237 }
1238
1239 #[inline]
1240 pub fn validator_power_proposals(&self) -> ValidatorPowerIter {
1241 match self {
1242 Self::V1(v1) => ValidatorPowerIter::v1(&v1.validator_power_proposals),
1243 Self::V2(v2) => ValidatorPowerIter::new(&v2.validator_power_proposals),
1244 }
1245 }
1246
1247 #[inline]
1248 pub fn validator_pledge_proposals(&self) -> ValidatorPledgeIter {
1249 match self {
1250 Self::V1(v1) => ValidatorPledgeIter::v1(&v1.validator_pledge_proposals),
1251 Self::V2(v2) => ValidatorPledgeIter::new(&v2.validator_pledge_proposals),
1252 }
1253 }
1254
1255 #[inline]
1256 pub fn gas_limit(&self) -> Gas {
1257 match self {
1258 Self::V1(v1) => v1.gas_limit,
1259 Self::V2(v2) => v2.gas_limit,
1260 }
1261 }
1262
1263 #[inline]
1264 pub fn gas_used(&self) -> Gas {
1265 match self {
1266 Self::V1(v1) => v1.gas_used,
1267 Self::V2(v2) => v2.gas_used,
1268 }
1269 }
1270
1271 #[inline]
1272 pub fn balance_burnt(&self) -> Balance {
1273 match self {
1274 Self::V1(v1) => v1.balance_burnt,
1275 Self::V2(v2) => v2.balance_burnt,
1276 }
1277 }
1278 }
1279}
1280
1281#[derive(Debug, PartialEq, BorshSerialize, BorshDeserialize, Clone, Eq)]
1283pub struct ChunkExtraV1 {
1284 pub state_root: StateRoot,
1286 pub outcome_root: CryptoHash,
1288 pub validator_power_proposals: Vec<ValidatorPowerV1>,
1290 pub validator_pledge_proposals: Vec<ValidatorPledgeV1>,
1292 pub gas_used: Gas,
1294 pub gas_limit: Gas,
1296 pub balance_burnt: Balance,
1298}
1299
1300#[derive(
1301 Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, arbitrary::Arbitrary,
1302)]
1303#[serde(untagged)]
1304pub enum BlockId {
1305 Height(BlockHeight),
1306 Hash(CryptoHash),
1307}
1308
1309pub type MaybeBlockId = Option<BlockId>;
1310
1311#[derive(
1312 Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, arbitrary::Arbitrary,
1313)]
1314#[serde(rename_all = "snake_case")]
1315pub enum SyncCheckpoint {
1316 Genesis,
1317 EarliestAvailable,
1318}
1319
1320#[derive(
1321 Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, arbitrary::Arbitrary,
1322)]
1323#[serde(rename_all = "snake_case")]
1324pub enum BlockReference {
1325 BlockId(BlockId),
1326 Finality(Finality),
1327 SyncCheckpoint(SyncCheckpoint),
1328}
1329
1330impl BlockReference {
1331 pub fn latest() -> Self {
1332 Self::Finality(Finality::None)
1333 }
1334}
1335
1336impl From<BlockId> for BlockReference {
1337 fn from(block_id: BlockId) -> Self {
1338 Self::BlockId(block_id)
1339 }
1340}
1341
1342impl From<Finality> for BlockReference {
1343 fn from(finality: Finality) -> Self {
1344 Self::Finality(finality)
1345 }
1346}
1347
1348#[derive(Default, BorshSerialize, BorshDeserialize, Clone, Debug, PartialEq, Eq)]
1349pub struct ValidatorStats {
1350 pub produced: NumBlocks,
1351 pub expected: NumBlocks,
1352}
1353
1354#[derive(Debug, BorshSerialize, BorshDeserialize, PartialEq, Eq)]
1355pub struct BlockChunkValidatorStats {
1356 pub block_stats: ValidatorStats,
1357 pub chunk_stats: ValidatorStats,
1358}
1359
1360#[derive(serde::Deserialize, Debug, arbitrary::Arbitrary, PartialEq, Eq)]
1361#[serde(rename_all = "snake_case")]
1362pub enum EpochReference {
1363 EpochId(EpochId),
1364 BlockId(BlockId),
1365 Latest,
1366}
1367
1368impl serde::Serialize for EpochReference {
1369 fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
1370 where
1371 S: serde::Serializer,
1372 {
1373 match self {
1374 EpochReference::EpochId(epoch_id) => {
1375 s.serialize_newtype_variant("EpochReference", 0, "epoch_id", epoch_id)
1376 }
1377 EpochReference::BlockId(block_id) => {
1378 s.serialize_newtype_variant("EpochReference", 1, "block_id", block_id)
1379 }
1380 EpochReference::Latest => {
1381 s.serialize_newtype_variant("EpochReference", 2, "latest", &())
1382 }
1383 }
1384 }
1385}
1386
1387#[derive(Debug)]
1393pub enum ValidatorInfoIdentifier {
1394 EpochId(EpochId),
1395 BlockHash(CryptoHash),
1396}
1397
1398#[derive(
1400 BorshSerialize,
1401 BorshDeserialize,
1402 serde::Serialize,
1403 serde::Deserialize,
1404 Clone,
1405 Debug,
1406 PartialEq,
1407 Eq,
1408)]
1409pub enum ValidatorKickoutReason {
1410 Slashed,
1412 NotEnoughBlocks { produced: NumBlocks, expected: NumBlocks },
1414 NotEnoughChunks { produced: NumBlocks, expected: NumBlocks },
1416 Unpowered,
1418 NotEnoughPower {
1420 #[serde(with = "dec_format", rename = "power_u128")]
1421 power: Power,
1422 #[serde(with = "dec_format", rename = "power_threshold_u128")]
1423 threshold: Power,
1424 },
1425 Unpledge,
1427 NotEnoughPledge {
1429 #[serde(with = "dec_format", rename = "pledge_u128")]
1430 pledge: Balance,
1431 #[serde(with = "dec_format", rename = "pledge_threshold_u128")]
1432 threshold: Balance,
1433 },
1434 DidNotGetASeat,
1436}
1437
1438#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
1439#[serde(tag = "type", rename_all = "snake_case")]
1440pub enum TransactionOrReceiptId {
1441 Transaction { transaction_hash: CryptoHash, sender_id: AccountId },
1442 Receipt { receipt_id: CryptoHash, receiver_id: AccountId },
1443}
1444
1445pub trait EpochInfoProvider {
1448 fn validator_power(
1451 &self,
1452 epoch_id: &EpochId,
1453 last_block_hash: &CryptoHash,
1454 account_id: &AccountId,
1455 ) -> Result<Option<Power>, EpochError>;
1456
1457 fn validator_total_power(
1459 &self,
1460 epoch_id: &EpochId,
1461 last_block_hash: &CryptoHash,
1462 ) -> Result<Power, EpochError>;
1463
1464 fn minimum_power(&self, prev_block_hash: &CryptoHash) -> Result<Power, EpochError>;
1465
1466 fn validator_stake(
1469 &self,
1470 epoch_id: &EpochId,
1471 last_block_hash: &CryptoHash,
1472 account_id: &AccountId,
1473 ) -> Result<Option<Balance>, EpochError>;
1474
1475 fn validator_total_stake(
1477 &self,
1478 epoch_id: &EpochId,
1479 last_block_hash: &CryptoHash,
1480 ) -> Result<Balance, EpochError>;
1481
1482 fn minimum_pledge(&self, prev_block_hash: &CryptoHash) -> Result<Balance, EpochError>;
1483}
1484
1485#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1487pub enum TrieCacheMode {
1488 CachingShard,
1491 CachingChunk,
1496}
1497
1498#[derive(borsh::BorshDeserialize, borsh::BorshSerialize)]
1501pub struct StateChangesForBlockRange {
1502 pub blocks: Vec<StateChangesForBlock>,
1503}
1504
1505#[derive(borsh::BorshDeserialize, borsh::BorshSerialize)]
1508pub struct StateChangesForBlock {
1509 pub block_hash: CryptoHash,
1510 pub state_changes: Vec<StateChangesForShard>,
1511}
1512
1513#[derive(borsh::BorshDeserialize, borsh::BorshSerialize)]
1515pub struct StateChangesForShard {
1516 pub shard_id: ShardId,
1517 pub state_changes: Vec<RawStateChangesWithTrieKey>,
1518}
1519
1520#[cfg(test)]
1521mod tests {
1522 use unc_crypto::{KeyType, PublicKey};
1523 use unc_primitives_core::types::{Balance, Power};
1524
1525 use super::validator_power_and_pledge::ValidatorPowerAndPledge;
1526
1527 fn new_validator_power_and_pledge(power: Power, pledge: Balance) -> ValidatorPowerAndPledge {
1528 ValidatorPowerAndPledge::new(
1529 "test_account".parse().unwrap(),
1530 PublicKey::empty(KeyType::ED25519),
1531 power,
1532 pledge,
1533 )
1534 }
1535
1536 #[test]
1537 fn test_validator_power_num_mandates() {
1538 assert_eq!(new_validator_power_and_pledge(0, 0).num_mandates(5), 0);
1539 assert_eq!(new_validator_power_and_pledge(10, 10).num_mandates(5), 2);
1540 assert_eq!(new_validator_power_and_pledge(12, 12).num_mandates(5), 2);
1541 }
1542
1543 #[test]
1544 fn test_validator_partial_mandate_weight() {
1545 assert_eq!(new_validator_power_and_pledge(0, 0).partial_mandate_weight(5), 0);
1546 assert_eq!(new_validator_power_and_pledge(10, 10).partial_mandate_weight(5), 0);
1547 assert_eq!(new_validator_power_and_pledge(12, 12).partial_mandate_weight(5), 2);
1548 }
1549}