1use crate::account::{AccessKey, AccessKeyPermission, Account, FunctionCallPermission};
7use crate::action::delegate::{DelegateAction, SignedDelegateAction};
8use crate::block::{Block, BlockHeader, Tip};
9use crate::block_header::{
10 BlockHeaderInnerLite, BlockHeaderInnerRest, BlockHeaderInnerRestV2, BlockHeaderInnerRestV3,
11 BlockHeaderV1, BlockHeaderV2, BlockHeaderV3,
12};
13use crate::block_header::{BlockHeaderInnerRestV4, BlockHeaderV4};
14use crate::challenge::{Challenge, ChallengesResult};
15use crate::checked_feature;
16use crate::errors::TxExecutionError;
17use crate::hash::{hash, CryptoHash};
18use crate::merkle::{combine_hash, MerklePath};
19use crate::network::PeerId;
20use crate::receipt::{ActionReceipt, DataReceipt, DataReceiver, Receipt, ReceiptEnum};
21use crate::serialize::dec_format;
22use crate::sharding::{
23 ChunkHash, ShardChunk, ShardChunkHeader, ShardChunkHeaderInner, ShardChunkHeaderInnerV2,
24 ShardChunkHeaderV3,
25};
26use crate::transaction::{
27 Action, AddKeyAction, CreateAccountAction, DeleteAccountAction, DeleteKeyAction,
28 DeployContractAction, ExecutionMetadata, ExecutionOutcome, ExecutionOutcomeWithIdAndProof,
29 ExecutionStatus, FunctionCallAction, PartialExecutionOutcome, PartialExecutionStatus,
30 PledgeAction, SignedTransaction, TransferAction,
31};
32use crate::types::{
33 AccountId, AccountWithPublicKey, Balance, BlockHeight, EpochHeight, EpochId, FunctionArgs, Gas,
34 Nonce, NumBlocks, Power, ShardId, StateChangeCause, StateChangeKind, StateChangeValue,
35 StateChangeWithCause, StateChangesRequest, StateRoot, StorageUsage, StoreKey, StoreValue,
36 ValidatorKickoutReason,
37};
38
39use crate::action::{CreateRsa2048ChallengeAction, RegisterRsa2048KeysAction};
40use crate::types::validator_power_and_pledge::{
41 ValidatorPowerAndPledge, ValidatorPowerAndPledgeIter,
42};
43use crate::version::{ProtocolVersion, Version};
44use crate::views::validator_pledge_view::ValidatorPledgeView;
45use crate::views::validator_power_and_pledge_view::ValidatorPowerAndPledgeView;
46use borsh::{BorshDeserialize, BorshSerialize};
47use chrono::DateTime;
48use serde_with::base64::Base64;
49use serde_with::serde_as;
50use std::collections::HashMap;
51use std::fmt;
52use std::ops::Range;
53use std::sync::Arc;
54use strum::IntoEnumIterator;
55use unc_crypto::{PublicKey, Signature};
56use unc_fmt::{AbbrBytes, Slice};
57use unc_parameters::{ActionCosts, ExtCosts};
58use unc_vm_runner::logic::CompiledContractCache;
59use unc_vm_runner::ContractCode;
60use validator_power_view::ValidatorPowerView;
61
62#[derive(serde::Serialize, serde::Deserialize, Debug, Eq, PartialEq, Clone)]
64pub struct AccountView {
65 #[serde(with = "dec_format")]
66 pub amount: Balance,
67 #[serde(with = "dec_format")]
68 pub pledging: Balance,
69 #[serde(with = "dec_format")]
70 pub power: Power,
71 pub code_hash: CryptoHash,
72 pub storage_usage: StorageUsage,
73 #[serde(default)]
75 pub storage_paid_at: BlockHeight,
76}
77
78#[serde_as]
80#[derive(serde::Serialize, serde::Deserialize, PartialEq, Eq, Debug, Clone)]
81pub struct ContractCodeView {
82 #[serde(rename = "code_base64")]
83 #[serde_as(as = "Base64")]
84 pub code: Vec<u8>,
85 pub hash: CryptoHash,
86}
87
88#[derive(Debug)]
90pub struct ViewApplyState {
91 pub block_height: BlockHeight,
93 pub prev_block_hash: CryptoHash,
95 pub block_hash: CryptoHash,
97 pub epoch_id: EpochId,
99 pub epoch_height: EpochHeight,
101 pub block_timestamp: u64,
103 pub current_protocol_version: ProtocolVersion,
105 pub cache: Option<Box<dyn CompiledContractCache>>,
107}
108
109impl From<&Account> for AccountView {
110 fn from(account: &Account) -> Self {
111 AccountView {
112 amount: account.amount(),
113 pledging: account.pledging(),
114 power: account.power(),
115 code_hash: account.code_hash(),
116 storage_usage: account.storage_usage(),
117 storage_paid_at: 0,
118 }
119 }
120}
121
122impl From<Account> for AccountView {
123 fn from(account: Account) -> Self {
124 (&account).into()
125 }
126}
127
128impl From<&AccountView> for Account {
129 fn from(view: &AccountView) -> Self {
130 Account::new(view.amount, view.pledging, view.power, view.code_hash, view.storage_usage)
131 }
132}
133
134impl From<AccountView> for Account {
135 fn from(view: AccountView) -> Self {
136 (&view).into()
137 }
138}
139
140impl From<ContractCode> for ContractCodeView {
141 fn from(contract_code: ContractCode) -> Self {
142 let hash = *contract_code.hash();
143 let code = contract_code.into_code();
144 ContractCodeView { code, hash }
145 }
146}
147
148impl From<ContractCodeView> for ContractCode {
149 fn from(contract_code: ContractCodeView) -> Self {
150 ContractCode::new(contract_code.code, Some(contract_code.hash))
151 }
152}
153
154#[derive(
155 BorshSerialize,
156 BorshDeserialize,
157 Debug,
158 Eq,
159 PartialEq,
160 Clone,
161 serde::Serialize,
162 serde::Deserialize,
163)]
164pub enum AccessKeyPermissionView {
165 FunctionCall {
166 #[serde(with = "dec_format")]
167 allowance: Option<Balance>,
168 receiver_id: String,
169 method_names: Vec<String>,
170 },
171 FullAccess,
172}
173
174impl From<AccessKeyPermission> for AccessKeyPermissionView {
175 fn from(permission: AccessKeyPermission) -> Self {
176 match permission {
177 AccessKeyPermission::FunctionCall(func_call) => AccessKeyPermissionView::FunctionCall {
178 allowance: func_call.allowance,
179 receiver_id: func_call.receiver_id,
180 method_names: func_call.method_names,
181 },
182 AccessKeyPermission::FullAccess => AccessKeyPermissionView::FullAccess,
183 }
184 }
185}
186
187impl From<AccessKeyPermissionView> for AccessKeyPermission {
188 fn from(view: AccessKeyPermissionView) -> Self {
189 match view {
190 AccessKeyPermissionView::FunctionCall { allowance, receiver_id, method_names } => {
191 AccessKeyPermission::FunctionCall(FunctionCallPermission {
192 allowance,
193 receiver_id,
194 method_names,
195 })
196 }
197 AccessKeyPermissionView::FullAccess => AccessKeyPermission::FullAccess,
198 }
199 }
200}
201
202#[derive(
203 BorshSerialize,
204 BorshDeserialize,
205 Debug,
206 Eq,
207 PartialEq,
208 Clone,
209 serde::Serialize,
210 serde::Deserialize,
211)]
212pub struct AccessKeyView {
213 pub nonce: Nonce,
214 pub permission: AccessKeyPermissionView,
215}
216
217impl From<AccessKey> for AccessKeyView {
218 fn from(access_key: AccessKey) -> Self {
219 Self { nonce: access_key.nonce, permission: access_key.permission.into() }
220 }
221}
222
223impl From<AccessKeyView> for AccessKey {
224 fn from(view: AccessKeyView) -> Self {
225 Self { nonce: view.nonce, permission: view.permission.into() }
226 }
227}
228
229#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone)]
231pub struct StateItem {
232 pub key: StoreKey,
233 pub value: StoreValue,
234}
235
236#[serde_as]
237#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone)]
238pub struct ViewStateResult {
239 pub values: Vec<StateItem>,
240 #[serde_as(as = "Vec<Base64>")]
241 #[serde(default, skip_serializing_if = "Vec::is_empty")]
242 pub proof: Vec<Arc<[u8]>>,
243}
244
245#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone, Default)]
246pub struct CallResult {
247 pub result: Vec<u8>,
248 pub logs: Vec<String>,
249}
250
251#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone)]
252pub struct QueryError {
253 pub error: String,
254 pub logs: Vec<String>,
255}
256
257#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone)]
258pub struct AccessKeyInfoView {
259 pub public_key: PublicKey,
260 pub access_key: AccessKeyView,
261}
262
263#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone)]
264pub struct AccessKeyList {
265 pub keys: Vec<AccessKeyInfoView>,
266}
267
268impl FromIterator<AccessKeyInfoView> for AccessKeyList {
269 fn from_iter<I: IntoIterator<Item = AccessKeyInfoView>>(iter: I) -> Self {
270 Self { keys: iter.into_iter().collect() }
271 }
272}
273
274#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone)]
275pub struct ChipsList {
276 pub total_power: Power,
277 pub chips: Vec<ChipView>,
278}
279
280impl FromIterator<ChipView> for ChipsList {
281 fn from_iter<I: IntoIterator<Item = ChipView>>(iter: I) -> Self {
282 let chips: Vec<ChipView> = iter.into_iter().collect();
283
284 let total_power: u64 = chips.iter().map(|chip| chip.power).sum();
286
287 ChipsList { total_power: total_power.into(), chips }
288 }
289}
290
291#[cfg_attr(feature = "deepsize_feature", derive(deepsize::DeepSizeOf))]
292#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone)]
293pub struct KnownPeerStateView {
294 pub peer_id: PeerId,
295 pub status: String,
296 pub addr: String,
297 pub first_seen: i64,
298 pub last_seen: i64,
299 pub last_attempt: Option<(i64, String)>,
300}
301
302#[cfg_attr(feature = "deepsize_feature", derive(deepsize::DeepSizeOf))]
303#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone)]
304pub struct ConnectionInfoView {
305 pub peer_id: PeerId,
306 pub addr: String,
307 pub time_established: i64,
308 pub time_connected_until: i64,
309}
310
311#[cfg_attr(feature = "deepsize_feature", derive(deepsize::DeepSizeOf))]
312#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone)]
313pub struct SnapshotHostInfoView {
314 pub peer_id: PeerId,
315 pub sync_hash: CryptoHash,
316 pub epoch_height: u64,
317 pub shards: Vec<u64>,
318}
319
320#[cfg_attr(feature = "deepsize_feature", derive(deepsize::DeepSizeOf))]
321#[derive(Debug, PartialEq, Eq, Clone)]
322pub enum QueryResponseKind {
323 ViewAccount(AccountView),
324 ViewCode(ContractCodeView),
325 ViewState(ViewStateResult),
326 CallResult(CallResult),
327 AccessKey(AccessKeyView),
328 AccessKeyList(AccessKeyList),
329 ChipList(ChipsList),
330}
331
332#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone)]
333#[serde(tag = "request_type", rename_all = "snake_case")]
334pub enum QueryRequest {
335 ViewAccount {
336 account_id: AccountId,
337 },
338 ViewCode {
339 account_id: AccountId,
340 },
341 ViewState {
342 account_id: AccountId,
343 #[serde(rename = "prefix_base64")]
344 prefix: StoreKey,
345 #[serde(default, skip_serializing_if = "is_false")]
346 include_proof: bool,
347 },
348 ViewAccessKey {
349 account_id: AccountId,
350 public_key: PublicKey,
351 },
352 ViewAccessKeyList {
353 account_id: AccountId,
354 },
355 ViewChipList {
356 account_id: AccountId,
357 },
358 CallFunction {
359 account_id: AccountId,
360 method_name: String,
361 #[serde(rename = "args_base64")]
362 args: FunctionArgs,
363 },
364}
365
366fn is_false(v: &bool) -> bool {
367 !*v
368}
369
370#[derive(Debug, PartialEq, Eq, Clone)]
371pub struct QueryResponse {
372 pub kind: QueryResponseKind,
373 pub block_height: BlockHeight,
374 pub block_hash: CryptoHash,
375}
376
377#[derive(serde::Serialize, serde::Deserialize, Debug)]
378pub struct StatusSyncInfo {
379 pub latest_block_hash: CryptoHash,
380 pub latest_block_height: BlockHeight,
381 pub latest_state_root: CryptoHash,
382 pub latest_block_time: DateTime<chrono::Utc>,
383 pub syncing: bool,
384 pub earliest_block_hash: Option<CryptoHash>,
385 pub earliest_block_height: Option<BlockHeight>,
386 pub earliest_block_time: Option<DateTime<chrono::Utc>>,
387 pub epoch_id: Option<EpochId>,
388 pub epoch_start_height: Option<BlockHeight>,
389}
390
391#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone)]
393pub struct ValidatorInfo {
394 pub account_id: AccountId,
395 pub is_slashed: bool,
396}
397
398#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
399pub struct PeerInfoView {
400 pub addr: String,
401 pub account_id: Option<AccountId>,
402 pub height: Option<BlockHeight>,
403 pub block_hash: Option<CryptoHash>,
404 pub is_highest_block_invalid: bool,
405 pub tracked_shards: Vec<ShardId>,
406 pub archival: bool,
407 pub peer_id: PublicKey,
408 pub received_bytes_per_sec: u64,
409 pub sent_bytes_per_sec: u64,
410 pub last_time_peer_requested_millis: u64,
411 pub last_time_received_message_millis: u64,
412 pub connection_established_time_millis: u64,
413 pub is_outbound_peer: bool,
414 pub nonce: u64,
416}
417
418#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
421pub struct KnownProducerView {
422 pub account_id: AccountId,
423 pub peer_id: PublicKey,
424 pub next_hops: Option<Vec<PublicKey>>,
425}
426
427#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
428pub struct Tier1ProxyView {
429 pub addr: std::net::SocketAddr,
430 pub peer_id: PublicKey,
431}
432
433#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
434pub struct AccountDataView {
435 pub peer_id: PublicKey,
436 pub proxies: Vec<Tier1ProxyView>,
437 pub account_key: PublicKey,
438 pub timestamp: DateTime<chrono::Utc>,
439}
440
441#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
442pub struct NetworkInfoView {
443 pub peer_max_count: u32,
444 pub num_connected_peers: usize,
445 pub connected_peers: Vec<PeerInfoView>,
446 pub known_producers: Vec<KnownProducerView>,
447 pub tier1_accounts_keys: Vec<PublicKey>,
448 pub tier1_accounts_data: Vec<AccountDataView>,
449 pub tier1_connections: Vec<PeerInfoView>,
450}
451
452#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
453pub enum SyncStatusView {
454 AwaitingPeers,
456 NoSync,
458 EpochSync { epoch_ord: u64 },
462 HeaderSync {
464 start_height: BlockHeight,
465 current_height: BlockHeight,
466 highest_height: BlockHeight,
467 },
468 StateSync(CryptoHash, HashMap<ShardId, ShardSyncDownloadView>),
470 StateSyncDone,
472 BlockSync {
474 start_height: BlockHeight,
475 current_height: BlockHeight,
476 highest_height: BlockHeight,
477 },
478}
479
480#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
481pub struct PeerStoreView {
482 pub peer_states: Vec<KnownPeerStateView>,
483}
484
485#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
486pub struct RecentOutboundConnectionsView {
487 pub recent_outbound_connections: Vec<ConnectionInfoView>,
488}
489
490#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
491pub struct SnapshotHostsView {
492 pub hosts: Vec<SnapshotHostInfoView>,
493}
494
495#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
496pub struct EdgeView {
497 pub peer0: PeerId,
498 pub peer1: PeerId,
499 pub nonce: u64,
500}
501
502#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
503pub struct NetworkGraphView {
504 pub edges: Vec<EdgeView>,
505 pub next_hops: HashMap<PeerId, Vec<PeerId>>,
506}
507
508#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
509pub struct LabeledEdgeView {
510 pub peer0: u32,
511 pub peer1: u32,
512 pub nonce: u64,
513}
514
515#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
516pub struct EdgeCacheView {
517 pub peer_labels: HashMap<PeerId, u32>,
518 pub spanning_trees: HashMap<u32, Vec<LabeledEdgeView>>,
519}
520
521#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
522pub struct PeerDistancesView {
523 pub distance: Vec<Option<u32>>,
524 pub min_nonce: u64,
525}
526
527#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
528pub struct NetworkRoutesView {
529 pub edge_cache: EdgeCacheView,
530 pub local_edges: HashMap<PeerId, EdgeView>,
531 pub peer_distances: HashMap<PeerId, PeerDistancesView>,
532 pub my_distances: HashMap<PeerId, u32>,
533}
534
535#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
536pub struct ShardSyncDownloadView {
537 pub downloads: Vec<DownloadStatusView>,
538 pub status: String,
539}
540
541#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
542pub struct DownloadStatusView {
543 pub error: bool,
544 pub done: bool,
545}
546
547#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
548pub struct CatchupStatusView {
549 pub sync_block_hash: CryptoHash,
551 pub sync_block_height: BlockHeight,
552 pub shard_sync_status: HashMap<ShardId, String>,
554 pub blocks_to_catchup: Vec<BlockStatusView>,
556}
557
558#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
559pub struct RequestedStatePartsView {
560 pub block_hash: CryptoHash,
562 pub shard_requested_parts: HashMap<ShardId, Vec<PartElapsedTimeView>>,
564}
565
566#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
567pub struct BlockStatusView {
568 pub height: BlockHeight,
569 pub hash: CryptoHash,
570}
571
572impl BlockStatusView {
573 pub fn new(height: &BlockHeight, hash: &CryptoHash) -> BlockStatusView {
574 Self { height: *height, hash: *hash }
575 }
576}
577
578impl From<Tip> for BlockStatusView {
579 fn from(tip: Tip) -> Self {
580 Self { height: tip.height, hash: tip.last_block_hash }
581 }
582}
583
584#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone)]
585pub struct PartElapsedTimeView {
586 pub part_id: u64,
587 pub elapsed_ms: u128,
588}
589
590impl PartElapsedTimeView {
591 pub fn new(part_id: &u64, elapsed_ms: u128) -> PartElapsedTimeView {
592 Self { part_id: *part_id, elapsed_ms }
593 }
594}
595
596#[derive(serde::Serialize, serde::Deserialize, Debug)]
597pub struct BlockByChunksView {
598 pub height: BlockHeight,
599 pub hash: CryptoHash,
600 pub block_status: String,
601 pub chunk_status: String,
602}
603
604#[derive(serde::Serialize, serde::Deserialize, Debug)]
605pub struct ChainProcessingInfo {
606 pub num_blocks_in_processing: usize,
607 pub num_orphans: usize,
608 pub num_blocks_missing_chunks: usize,
609 pub blocks_info: Vec<BlockProcessingInfo>,
611 pub floating_chunks_info: Vec<ChunkProcessingInfo>,
613}
614
615#[derive(serde::Serialize, serde::Deserialize, Debug)]
616pub struct BlockProcessingInfo {
617 pub height: BlockHeight,
618 pub hash: CryptoHash,
619 pub received_timestamp: DateTime<chrono::Utc>,
620 pub in_progress_ms: u128,
624 pub orphaned_ms: Option<u128>,
628 pub missing_chunks_ms: Option<u128>,
632 pub block_status: BlockProcessingStatus,
633 pub chunks_info: Vec<Option<ChunkProcessingInfo>>,
636}
637
638#[derive(
639 BorshSerialize,
640 BorshDeserialize,
641 Clone,
642 Debug,
643 PartialEq,
644 Eq,
645 serde::Serialize,
646 serde::Deserialize,
647)]
648pub enum BlockProcessingStatus {
649 Orphan,
650 WaitingForChunks,
651 InProcessing,
652 Accepted,
653 Error(String),
654 Dropped(DroppedReason),
655 Unknown,
656}
657
658#[derive(
659 BorshSerialize,
660 BorshDeserialize,
661 Clone,
662 Debug,
663 PartialEq,
664 Eq,
665 serde::Serialize,
666 serde::Deserialize,
667)]
668pub enum DroppedReason {
669 HeightProcessed,
671 TooManyProcessingBlocks,
673}
674
675#[derive(serde::Serialize, serde::Deserialize, Debug)]
676pub struct ChunkProcessingInfo {
677 pub height_created: BlockHeight,
678 pub shard_id: ShardId,
679 pub chunk_hash: ChunkHash,
680 pub prev_block_hash: CryptoHash,
681 pub created_by: Option<AccountId>,
684 pub status: ChunkProcessingStatus,
685 pub requested_timestamp: Option<DateTime<chrono::Utc>>,
687 pub completed_timestamp: Option<DateTime<chrono::Utc>>,
689 pub request_duration: Option<u64>,
691 pub chunk_parts_collection: Vec<PartCollectionInfo>,
692}
693
694#[derive(serde::Serialize, serde::Deserialize, Debug)]
695pub struct PartCollectionInfo {
696 pub part_owner: AccountId,
697 pub received_time: Option<DateTime<chrono::Utc>>,
699 pub forwarded_received_time: Option<DateTime<chrono::Utc>>,
701 pub chunk_received_time: Option<DateTime<chrono::Utc>>,
703}
704
705#[derive(serde::Serialize, serde::Deserialize, Debug)]
706pub enum ChunkProcessingStatus {
707 NeedToRequest,
708 Requested,
709 Completed,
710}
711
712#[derive(serde::Serialize, serde::Deserialize, Debug)]
713pub struct DetailedDebugStatus {
714 pub network_info: NetworkInfoView,
715 pub sync_status: String,
716 pub catchup_status: Vec<CatchupStatusView>,
717 pub current_head_status: BlockStatusView,
718 pub current_header_head_status: BlockStatusView,
719 pub block_production_delay_millis: u64,
720}
721
722#[derive(serde::Serialize, serde::Deserialize, Debug)]
724pub struct StatusResponse {
725 pub version: Version,
727 pub chain_id: String,
729 pub protocol_version: u32,
731 pub latest_protocol_version: u32,
733 #[serde(skip_serializing_if = "Option::is_none")]
735 pub rpc_addr: Option<String>,
736 pub validators: Vec<ValidatorInfo>,
738 pub sync_info: StatusSyncInfo,
740 pub validator_account_id: Option<AccountId>,
742 pub validator_public_key: Option<PublicKey>,
744 pub node_public_key: PublicKey,
746 pub node_key: Option<PublicKey>,
748 pub uptime_sec: i64,
750 #[serde(skip_serializing_if = "Option::is_none")]
752 pub detailed_debug_status: Option<DetailedDebugStatus>,
753}
754
755#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
756pub struct ChallengeView {
757 }
759
760impl From<Challenge> for ChallengeView {
761 fn from(_challenge: Challenge) -> Self {
762 Self {}
763 }
764}
765
766#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone)]
767pub struct ChipView {
768 pub miner_id: String,
769 pub public_key: String,
770 pub power: u64,
771 pub sn: String,
772 pub bus_id: String,
773 pub p2key: String,
774}
775#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
776pub struct BlockHeaderView {
777 pub height: BlockHeight,
778 pub prev_height: Option<BlockHeight>,
779 pub epoch_id: CryptoHash,
780 pub next_epoch_id: CryptoHash,
781 pub hash: CryptoHash,
782 pub prev_hash: CryptoHash,
783 pub prev_state_root: CryptoHash,
784 pub block_body_hash: Option<CryptoHash>,
785 pub chunk_receipts_root: CryptoHash,
786 pub chunk_headers_root: CryptoHash,
787 pub chunk_tx_root: CryptoHash,
788 pub outcome_root: CryptoHash,
789 pub chunks_included: u64,
790 pub challenges_root: CryptoHash,
791 pub timestamp: u64,
793 #[serde(with = "dec_format")]
794 pub timestamp_nanosec: u64,
795 pub random_value: CryptoHash,
796 pub validator_power_proposals: Vec<ValidatorPowerView>,
797 pub validator_pledge_proposals: Vec<ValidatorPledgeView>,
798 pub chunk_mask: Vec<bool>,
799 #[serde(with = "dec_format")]
800 pub gas_price: Balance,
801 pub block_ordinal: Option<NumBlocks>,
802 #[serde(with = "dec_format")]
804 pub rent_paid: Balance,
805 #[serde(with = "dec_format")]
807 pub validator_reward: Balance,
808 #[serde(with = "dec_format")]
809 pub total_supply: Balance,
810 pub challenges_result: ChallengesResult,
811 pub last_final_block: CryptoHash,
812 pub last_ds_final_block: CryptoHash,
813 pub next_bp_hash: CryptoHash,
814 pub block_merkle_root: CryptoHash,
815 pub epoch_sync_data_hash: Option<CryptoHash>,
816 pub approvals: Vec<Option<Box<Signature>>>,
817 pub signature: Signature,
818 pub latest_protocol_version: ProtocolVersion,
819}
820
821impl From<BlockHeader> for BlockHeaderView {
822 fn from(header: BlockHeader) -> Self {
823 Self {
824 height: header.height(),
825 prev_height: header.prev_height(),
826 epoch_id: header.epoch_id().0,
827 next_epoch_id: header.next_epoch_id().0,
828 hash: *header.hash(),
829 prev_hash: *header.prev_hash(),
830 prev_state_root: *header.prev_state_root(),
831 block_body_hash: header.block_body_hash(),
832 chunk_receipts_root: *header.prev_chunk_outgoing_receipts_root(),
833 chunk_headers_root: *header.chunk_headers_root(),
834 chunk_tx_root: *header.chunk_tx_root(),
835 chunks_included: header.chunks_included(),
836 challenges_root: *header.challenges_root(),
837 outcome_root: *header.outcome_root(),
838 timestamp: header.raw_timestamp(),
839 timestamp_nanosec: header.raw_timestamp(),
840 random_value: *header.random_value(),
841 validator_power_proposals: header
842 .prev_validator_power_proposals()
843 .map(Into::into)
844 .collect(),
845 validator_pledge_proposals: header
846 .prev_validator_pledge_proposals()
847 .map(Into::into)
848 .collect(),
849 chunk_mask: header.chunk_mask().to_vec(),
850 block_ordinal: if header.block_ordinal() != 0 {
851 Some(header.block_ordinal())
852 } else {
853 None
854 },
855 gas_price: header.next_gas_price(),
856 rent_paid: 0,
857 validator_reward: 0,
858 total_supply: header.total_supply(),
859 challenges_result: header.challenges_result().clone(),
860 last_final_block: *header.last_final_block(),
861 last_ds_final_block: *header.last_ds_final_block(),
862 next_bp_hash: *header.next_bp_hash(),
863 block_merkle_root: *header.block_merkle_root(),
864 epoch_sync_data_hash: header.epoch_sync_data_hash(),
865 approvals: header.approvals().to_vec(),
866 signature: header.signature().clone(),
867 latest_protocol_version: header.latest_protocol_version(),
868 }
869 }
870}
871
872impl From<BlockHeaderView> for BlockHeader {
873 fn from(view: BlockHeaderView) -> Self {
874 let inner_lite = BlockHeaderInnerLite {
875 height: view.height,
876 epoch_id: EpochId(view.epoch_id),
877 next_epoch_id: EpochId(view.next_epoch_id),
878 prev_state_root: view.prev_state_root,
879 prev_outcome_root: view.outcome_root,
880 timestamp: view.timestamp,
881 next_bp_hash: view.next_bp_hash,
882 block_merkle_root: view.block_merkle_root,
883 };
884 const LAST_HEADER_V2_VERSION: ProtocolVersion =
885 crate::version::ProtocolFeature::BlockHeaderV3.protocol_version() - 1;
886 if view.latest_protocol_version <= 29 {
887 let validator_power_proposals = view
888 .validator_power_proposals
889 .into_iter()
890 .map(|v| v.into_validator_power().into_v1())
891 .collect();
892 let validator_pledge_proposals = view
893 .validator_pledge_proposals
894 .into_iter()
895 .map(|v| v.into_validator_pledge().into_v1())
896 .collect();
897 let mut header = BlockHeaderV1 {
898 prev_hash: view.prev_hash,
899 inner_lite,
900 inner_rest: BlockHeaderInnerRest {
901 prev_chunk_outgoing_receipts_root: view.chunk_receipts_root,
902 chunk_headers_root: view.chunk_headers_root,
903 chunk_tx_root: view.chunk_tx_root,
904 chunks_included: view.chunks_included,
905 challenges_root: view.challenges_root,
906 random_value: view.random_value,
907 prev_validator_power_proposals: validator_power_proposals,
908 prev_validator_pledge_proposals: validator_pledge_proposals,
909 chunk_mask: view.chunk_mask,
910 next_gas_price: view.gas_price,
911 total_supply: view.total_supply,
912 challenges_result: view.challenges_result,
913 last_final_block: view.last_final_block,
914 last_ds_final_block: view.last_ds_final_block,
915 approvals: view.approvals.clone(),
916 latest_protocol_version: view.latest_protocol_version,
917 },
918 signature: view.signature,
919 hash: CryptoHash::default(),
920 };
921 header.init();
922 BlockHeader::BlockHeaderV1(Arc::new(header))
923 } else if view.latest_protocol_version <= LAST_HEADER_V2_VERSION {
924 let validator_power_proposals = view
925 .validator_power_proposals
926 .into_iter()
927 .map(|v| v.into_validator_power().into_v1())
928 .collect();
929 let validator_pledge_proposals = view
930 .validator_pledge_proposals
931 .into_iter()
932 .map(|v| v.into_validator_pledge().into_v1())
933 .collect();
934 let mut header = BlockHeaderV2 {
935 prev_hash: view.prev_hash,
936 inner_lite,
937 inner_rest: BlockHeaderInnerRestV2 {
938 prev_chunk_outgoing_receipts_root: view.chunk_receipts_root,
939 chunk_headers_root: view.chunk_headers_root,
940 chunk_tx_root: view.chunk_tx_root,
941 challenges_root: view.challenges_root,
942 random_value: view.random_value,
943 prev_validator_power_proposals: validator_power_proposals,
944 prev_validator_pledge_proposals: validator_pledge_proposals,
945 chunk_mask: view.chunk_mask,
946 next_gas_price: view.gas_price,
947 total_supply: view.total_supply,
948 challenges_result: view.challenges_result,
949 last_final_block: view.last_final_block,
950 last_ds_final_block: view.last_ds_final_block,
951 approvals: view.approvals.clone(),
952 latest_protocol_version: view.latest_protocol_version,
953 },
954 signature: view.signature,
955 hash: CryptoHash::default(),
956 };
957 header.init();
958 BlockHeader::BlockHeaderV2(Arc::new(header))
959 } else if !checked_feature!("stable", BlockHeaderV4, view.latest_protocol_version) {
960 let mut header = BlockHeaderV3 {
961 prev_hash: view.prev_hash,
962 inner_lite,
963 inner_rest: BlockHeaderInnerRestV3 {
964 prev_chunk_outgoing_receipts_root: view.chunk_receipts_root,
965 chunk_headers_root: view.chunk_headers_root,
966 chunk_tx_root: view.chunk_tx_root,
967 challenges_root: view.challenges_root,
968 random_value: view.random_value,
969 prev_validator_power_proposals: view
970 .validator_power_proposals
971 .into_iter()
972 .map(Into::into)
973 .collect(),
974 prev_validator_pledge_proposals: view
975 .validator_pledge_proposals
976 .into_iter()
977 .map(Into::into)
978 .collect(),
979 chunk_mask: view.chunk_mask,
980 next_gas_price: view.gas_price,
981 block_ordinal: view.block_ordinal.unwrap_or(0),
982 total_supply: view.total_supply,
983 challenges_result: view.challenges_result,
984 last_final_block: view.last_final_block,
985 last_ds_final_block: view.last_ds_final_block,
986 prev_height: view.prev_height.unwrap_or_default(),
987 epoch_sync_data_hash: view.epoch_sync_data_hash,
988 approvals: view.approvals.clone(),
989 latest_protocol_version: view.latest_protocol_version,
990 },
991 signature: view.signature,
992 hash: CryptoHash::default(),
993 };
994 header.init();
995 BlockHeader::BlockHeaderV3(Arc::new(header))
996 } else {
997 let mut header = BlockHeaderV4 {
998 prev_hash: view.prev_hash,
999 inner_lite,
1000 inner_rest: BlockHeaderInnerRestV4 {
1001 block_body_hash: view.block_body_hash.unwrap_or_default(),
1002 prev_chunk_outgoing_receipts_root: view.chunk_receipts_root,
1003 chunk_headers_root: view.chunk_headers_root,
1004 chunk_tx_root: view.chunk_tx_root,
1005 challenges_root: view.challenges_root,
1006 random_value: view.random_value,
1007 prev_validator_power_proposals: view
1008 .validator_power_proposals
1009 .into_iter()
1010 .map(Into::into)
1011 .collect(),
1012 prev_validator_pledge_proposals: view
1013 .validator_pledge_proposals
1014 .into_iter()
1015 .map(Into::into)
1016 .collect(),
1017 chunk_mask: view.chunk_mask,
1018 next_gas_price: view.gas_price,
1019 block_ordinal: view.block_ordinal.unwrap_or(0),
1020 total_supply: view.total_supply,
1021 challenges_result: view.challenges_result,
1022 last_final_block: view.last_final_block,
1023 last_ds_final_block: view.last_ds_final_block,
1024 prev_height: view.prev_height.unwrap_or_default(),
1025 epoch_sync_data_hash: view.epoch_sync_data_hash,
1026 approvals: view.approvals.clone(),
1027 latest_protocol_version: view.latest_protocol_version,
1028 },
1029 signature: view.signature,
1030 hash: CryptoHash::default(),
1031 };
1032 header.init();
1033 BlockHeader::BlockHeaderV4(Arc::new(header))
1034 }
1035 }
1036}
1037
1038#[derive(
1039 PartialEq,
1040 Eq,
1041 Debug,
1042 Clone,
1043 BorshDeserialize,
1044 BorshSerialize,
1045 serde::Serialize,
1046 serde::Deserialize,
1047)]
1048pub struct BlockHeaderInnerLiteView {
1049 pub height: BlockHeight,
1050 pub epoch_id: CryptoHash,
1051 pub next_epoch_id: CryptoHash,
1052 pub prev_state_root: CryptoHash,
1053 pub outcome_root: CryptoHash,
1054 pub timestamp: u64,
1056 #[serde(with = "dec_format")]
1057 pub timestamp_nanosec: u64,
1058 pub next_bp_hash: CryptoHash,
1059 pub block_merkle_root: CryptoHash,
1060}
1061
1062impl From<BlockHeader> for BlockHeaderInnerLiteView {
1063 fn from(header: BlockHeader) -> Self {
1064 let inner_lite = match &header {
1065 BlockHeader::BlockHeaderV1(header) => &header.inner_lite,
1066 BlockHeader::BlockHeaderV2(header) => &header.inner_lite,
1067 BlockHeader::BlockHeaderV3(header) => &header.inner_lite,
1068 BlockHeader::BlockHeaderV4(header) => &header.inner_lite,
1069 };
1070 BlockHeaderInnerLiteView {
1071 height: inner_lite.height,
1072 epoch_id: inner_lite.epoch_id.0,
1073 next_epoch_id: inner_lite.next_epoch_id.0,
1074 prev_state_root: inner_lite.prev_state_root,
1075 outcome_root: inner_lite.prev_outcome_root,
1076 timestamp: inner_lite.timestamp,
1077 timestamp_nanosec: inner_lite.timestamp,
1078 next_bp_hash: inner_lite.next_bp_hash,
1079 block_merkle_root: inner_lite.block_merkle_root,
1080 }
1081 }
1082}
1083
1084impl From<BlockHeaderInnerLiteView> for BlockHeaderInnerLite {
1085 fn from(view: BlockHeaderInnerLiteView) -> Self {
1086 BlockHeaderInnerLite {
1087 height: view.height,
1088 epoch_id: EpochId(view.epoch_id),
1089 next_epoch_id: EpochId(view.next_epoch_id),
1090 prev_state_root: view.prev_state_root,
1091 prev_outcome_root: view.outcome_root,
1092 timestamp: view.timestamp_nanosec,
1093 next_bp_hash: view.next_bp_hash,
1094 block_merkle_root: view.block_merkle_root,
1095 }
1096 }
1097}
1098
1099#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
1100pub struct ChunkHeaderView {
1101 pub chunk_hash: CryptoHash,
1102 pub prev_block_hash: CryptoHash,
1103 pub outcome_root: CryptoHash,
1104 pub prev_state_root: StateRoot,
1105 pub encoded_merkle_root: CryptoHash,
1106 pub encoded_length: u64,
1107 pub height_created: BlockHeight,
1108 pub height_included: BlockHeight,
1109 pub shard_id: ShardId,
1110 pub gas_used: Gas,
1111 pub gas_limit: Gas,
1112 #[serde(with = "dec_format")]
1114 pub rent_paid: Balance,
1115 #[serde(with = "dec_format")]
1117 pub validator_reward: Balance,
1118 #[serde(with = "dec_format")]
1119 pub balance_burnt: Balance,
1120 pub outgoing_receipts_root: CryptoHash,
1121 pub tx_root: CryptoHash,
1122 pub validator_power_proposals: Vec<ValidatorPowerView>,
1123 pub validator_pledge_proposals: Vec<ValidatorPledgeView>,
1124 pub signature: Signature,
1125}
1126
1127impl From<ShardChunkHeader> for ChunkHeaderView {
1128 fn from(chunk: ShardChunkHeader) -> Self {
1129 let hash = chunk.chunk_hash();
1130 let signature = chunk.signature().clone();
1131 let height_included = chunk.height_included();
1132 let inner = chunk.take_inner();
1133 ChunkHeaderView {
1134 chunk_hash: hash.0,
1135 prev_block_hash: *inner.prev_block_hash(),
1136 outcome_root: *inner.prev_outcome_root(),
1137 prev_state_root: *inner.prev_state_root(),
1138 encoded_merkle_root: *inner.encoded_merkle_root(),
1139 encoded_length: inner.encoded_length(),
1140 height_created: inner.height_created(),
1141 height_included,
1142 shard_id: inner.shard_id(),
1143 gas_used: inner.prev_gas_used(),
1144 gas_limit: inner.gas_limit(),
1145 rent_paid: 0,
1146 validator_reward: 0,
1147 balance_burnt: inner.prev_balance_burnt(),
1148 outgoing_receipts_root: *inner.prev_outgoing_receipts_root(),
1149 tx_root: *inner.tx_root(),
1150 validator_power_proposals: inner
1151 .prev_validator_power_proposals()
1152 .map(Into::into)
1153 .collect(),
1154 validator_pledge_proposals: inner
1155 .prev_validator_pledge_proposals()
1156 .map(Into::into)
1157 .collect(),
1158 signature,
1159 }
1160 }
1161}
1162
1163impl From<ChunkHeaderView> for ShardChunkHeader {
1164 fn from(view: ChunkHeaderView) -> Self {
1165 let mut header = ShardChunkHeaderV3 {
1166 inner: ShardChunkHeaderInner::V2(ShardChunkHeaderInnerV2 {
1167 prev_block_hash: view.prev_block_hash,
1168 prev_state_root: view.prev_state_root,
1169 prev_outcome_root: view.outcome_root,
1170 encoded_merkle_root: view.encoded_merkle_root,
1171 encoded_length: view.encoded_length,
1172 height_created: view.height_created,
1173 shard_id: view.shard_id,
1174 prev_gas_used: view.gas_used,
1175 gas_limit: view.gas_limit,
1176 prev_balance_burnt: view.balance_burnt,
1177 prev_outgoing_receipts_root: view.outgoing_receipts_root,
1178 tx_root: view.tx_root,
1179 prev_validator_power_proposals: view
1180 .validator_power_proposals
1181 .into_iter()
1182 .map(Into::into)
1183 .collect(),
1184 prev_validator_pledge_proposals: view
1185 .validator_pledge_proposals
1186 .into_iter()
1187 .map(Into::into)
1188 .collect(),
1189 }),
1190 height_included: view.height_included,
1191 signature: view.signature,
1192 hash: ChunkHash::default(),
1193 };
1194 header.init();
1195 ShardChunkHeader::V3(header)
1196 }
1197}
1198
1199#[derive(serde::Serialize, serde::Deserialize, Debug)]
1200pub struct AllMinersView {
1201 pub total_power: Power,
1202 pub miners: Vec<ValidatorPowerView>,
1203}
1204
1205impl From<ValidatorPowerAndPledgeIter<'_>> for AllMinersView {
1206 fn from(iter: ValidatorPowerAndPledgeIter) -> Self {
1207 let mut total_power = 0; let mut miners = Vec::new(); for validator in iter {
1212 match validator {
1213 ValidatorPowerAndPledge::V1(v) => {
1215 total_power += v.power; let miner = ValidatorPowerView::V1(ValidatorPowerViewV1 {
1218 account_id: v.account_id,
1219 public_key: v.public_key,
1220 power: v.power,
1221 });
1222 miners.push(miner); } }
1225 }
1226
1227 AllMinersView { total_power, miners }
1229 }
1230}
1231
1232#[derive(serde::Serialize, serde::Deserialize, Debug)]
1233pub struct BlockView {
1234 pub author: AccountId,
1235 pub header: BlockHeaderView,
1236 pub chunks: Vec<ChunkHeaderView>,
1237}
1238
1239impl BlockView {
1240 pub fn from_author_block(author: AccountId, block: Block) -> Self {
1241 BlockView {
1242 author,
1243 header: block.header().clone().into(),
1244 chunks: block.chunks().iter().cloned().map(Into::into).collect(),
1245 }
1246 }
1247}
1248
1249#[derive(serde::Serialize, serde::Deserialize, Debug)]
1250pub struct ChunkView {
1251 pub author: AccountId,
1252 pub header: ChunkHeaderView,
1253 pub transactions: Vec<SignedTransactionView>,
1254 pub receipts: Vec<ReceiptView>,
1255}
1256
1257impl ChunkView {
1258 pub fn from_author_chunk(author: AccountId, chunk: ShardChunk) -> Self {
1259 match chunk {
1260 ShardChunk::V1(chunk) => Self {
1261 author,
1262 header: ShardChunkHeader::V1(chunk.header).into(),
1263 transactions: chunk.transactions.into_iter().map(Into::into).collect(),
1264 receipts: chunk.prev_outgoing_receipts.into_iter().map(Into::into).collect(),
1265 },
1266 ShardChunk::V2(chunk) => Self {
1267 author,
1268 header: chunk.header.into(),
1269 transactions: chunk.transactions.into_iter().map(Into::into).collect(),
1270 receipts: chunk.prev_outgoing_receipts.into_iter().map(Into::into).collect(),
1271 },
1272 }
1273 }
1274}
1275
1276#[serde_as]
1277#[derive(
1278 BorshSerialize,
1279 BorshDeserialize,
1280 Clone,
1281 Debug,
1282 PartialEq,
1283 Eq,
1284 serde::Serialize,
1285 serde::Deserialize,
1286)]
1287pub enum ActionView {
1288 CreateAccount,
1289 DeployContract {
1290 #[serde_as(as = "Base64")]
1291 code: Vec<u8>,
1292 },
1293 FunctionCall {
1294 method_name: String,
1295 args: FunctionArgs,
1296 gas: Gas,
1297 #[serde(with = "dec_format")]
1298 deposit: Balance,
1299 },
1300 Transfer {
1301 #[serde(with = "dec_format")]
1302 deposit: Balance,
1303 },
1304 Pledge {
1305 #[serde(with = "dec_format")]
1306 pledge: Balance,
1307 public_key: PublicKey,
1308 },
1309 AddKey {
1310 public_key: PublicKey,
1311 access_key: AccessKeyView,
1312 },
1313 DeleteKey {
1314 public_key: PublicKey,
1315 },
1316 DeleteAccount {
1317 beneficiary_id: AccountId,
1318 },
1319 Delegate {
1320 delegate_action: DelegateAction,
1321 signature: Signature,
1322 },
1323 RegisterRsa2048Keys {
1324 public_key: PublicKey,
1325 operation_type: u8,
1326 #[serde_as(as = "Base64")]
1327 args: Vec<u8>,
1328 },
1329 CreateRsa2048Challenge {
1330 public_key: PublicKey,
1331 challenge_key: PublicKey,
1332 #[serde_as(as = "Base64")]
1333 args: Vec<u8>,
1334 },
1335}
1336
1337impl From<Action> for ActionView {
1338 fn from(action: Action) -> Self {
1339 match action {
1340 Action::CreateAccount(_) => ActionView::CreateAccount,
1341 Action::DeployContract(action) => {
1342 let code = hash(&action.code).as_ref().to_vec();
1343 ActionView::DeployContract { code }
1344 }
1345 Action::FunctionCall(action) => ActionView::FunctionCall {
1346 method_name: action.method_name,
1347 args: action.args.into(),
1348 gas: action.gas,
1349 deposit: action.deposit,
1350 },
1351 Action::Transfer(action) => ActionView::Transfer { deposit: action.deposit },
1352 Action::Pledge(action) => {
1353 ActionView::Pledge { pledge: action.pledge, public_key: action.public_key }
1354 }
1355 Action::AddKey(action) => ActionView::AddKey {
1356 public_key: action.public_key,
1357 access_key: action.access_key.into(),
1358 },
1359 Action::DeleteKey(action) => ActionView::DeleteKey { public_key: action.public_key },
1360 Action::DeleteAccount(action) => {
1361 ActionView::DeleteAccount { beneficiary_id: action.beneficiary_id }
1362 }
1363 Action::Delegate(action) => ActionView::Delegate {
1364 delegate_action: action.delegate_action,
1365 signature: action.signature,
1366 },
1367 Action::RegisterRsa2048Keys(action) => ActionView::RegisterRsa2048Keys {
1368 public_key: action.public_key,
1369 operation_type: action.operation_type,
1370 args: action.args.into(),
1371 },
1372 Action::CreateRsa2048Challenge(action) => ActionView::CreateRsa2048Challenge {
1373 public_key: action.public_key,
1374 challenge_key: action.challenge_key,
1375 args: action.args.into(),
1376 },
1377 }
1378 }
1379}
1380
1381impl TryFrom<ActionView> for Action {
1382 type Error = Box<dyn std::error::Error + Send + Sync>;
1383
1384 fn try_from(action_view: ActionView) -> Result<Self, Self::Error> {
1385 Ok(match action_view {
1386 ActionView::CreateAccount => Action::CreateAccount(CreateAccountAction {}),
1387 ActionView::DeployContract { code } => {
1388 Action::DeployContract(DeployContractAction { code })
1389 }
1390 ActionView::FunctionCall { method_name, args, gas, deposit } => {
1391 Action::FunctionCall(Box::new(FunctionCallAction {
1392 method_name,
1393 args: args.into(),
1394 gas,
1395 deposit,
1396 }))
1397 }
1398 ActionView::Transfer { deposit } => Action::Transfer(TransferAction { deposit }),
1399 ActionView::Pledge { pledge, public_key } => {
1400 Action::Pledge(Box::new(PledgeAction { pledge, public_key }))
1401 }
1402 ActionView::AddKey { public_key, access_key } => {
1403 Action::AddKey(Box::new(AddKeyAction { public_key, access_key: access_key.into() }))
1404 }
1405 ActionView::DeleteKey { public_key } => {
1406 Action::DeleteKey(Box::new(DeleteKeyAction { public_key }))
1407 }
1408 ActionView::DeleteAccount { beneficiary_id } => {
1409 Action::DeleteAccount(DeleteAccountAction { beneficiary_id })
1410 }
1411 ActionView::Delegate { delegate_action, signature } => {
1412 Action::Delegate(Box::new(SignedDelegateAction { delegate_action, signature }))
1413 }
1414 ActionView::RegisterRsa2048Keys { public_key, operation_type, args } => {
1415 Action::RegisterRsa2048Keys(Box::new(RegisterRsa2048KeysAction {
1416 public_key,
1417 operation_type,
1418 args: args.into(),
1419 }))
1420 }
1421 ActionView::CreateRsa2048Challenge { public_key, challenge_key, args } => {
1422 Action::CreateRsa2048Challenge(Box::new(CreateRsa2048ChallengeAction {
1423 public_key,
1424 challenge_key,
1425 args: args.into(),
1426 }))
1427 }
1428 })
1429 }
1430}
1431
1432#[derive(
1433 BorshSerialize,
1434 BorshDeserialize,
1435 Debug,
1436 PartialEq,
1437 Eq,
1438 Clone,
1439 serde::Serialize,
1440 serde::Deserialize,
1441)]
1442pub struct SignedTransactionView {
1443 pub signer_id: AccountId,
1444 pub public_key: PublicKey,
1445 pub nonce: Nonce,
1446 pub receiver_id: AccountId,
1447 pub actions: Vec<ActionView>,
1448 pub signature: Signature,
1449 pub hash: CryptoHash,
1450}
1451
1452impl From<SignedTransaction> for SignedTransactionView {
1453 fn from(signed_tx: SignedTransaction) -> Self {
1454 let hash = signed_tx.get_hash();
1455 SignedTransactionView {
1456 signer_id: signed_tx.transaction.signer_id,
1457 public_key: signed_tx.transaction.public_key,
1458 nonce: signed_tx.transaction.nonce,
1459 receiver_id: signed_tx.transaction.receiver_id,
1460 actions: signed_tx
1461 .transaction
1462 .actions
1463 .into_iter()
1464 .map(|action| action.into())
1465 .collect(),
1466 signature: signed_tx.signature,
1467 hash,
1468 }
1469 }
1470}
1471
1472#[serde_as]
1473#[derive(
1474 BorshSerialize,
1475 BorshDeserialize,
1476 serde::Serialize,
1477 serde::Deserialize,
1478 PartialEq,
1479 Eq,
1480 Clone,
1481 Default,
1482)]
1483pub enum FinalExecutionStatus {
1484 #[default]
1486 NotStarted,
1487 Started,
1489 Failure(TxExecutionError),
1491 SuccessValue(#[serde_as(as = "Base64")] Vec<u8>),
1493}
1494
1495impl fmt::Debug for FinalExecutionStatus {
1496 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1497 match self {
1498 FinalExecutionStatus::NotStarted => f.write_str("NotStarted"),
1499 FinalExecutionStatus::Started => f.write_str("Started"),
1500 FinalExecutionStatus::Failure(e) => f.write_fmt(format_args!("Failure({:?})", e)),
1501 FinalExecutionStatus::SuccessValue(v) => {
1502 f.write_fmt(format_args!("SuccessValue({})", AbbrBytes(v)))
1503 }
1504 }
1505 }
1506}
1507
1508#[derive(
1509 BorshSerialize,
1510 BorshDeserialize,
1511 Debug,
1512 PartialEq,
1513 Eq,
1514 Clone,
1515 serde::Serialize,
1516 serde::Deserialize,
1517)]
1518pub enum ServerError {
1519 TxExecutionError(TxExecutionError),
1520 Timeout,
1521 Closed,
1522}
1523
1524#[serde_as]
1525#[derive(
1526 BorshSerialize, BorshDeserialize, serde::Serialize, serde::Deserialize, PartialEq, Eq, Clone,
1527)]
1528pub enum ExecutionStatusView {
1529 Unknown,
1531 Failure(TxExecutionError),
1533 SuccessValue(#[serde_as(as = "Base64")] Vec<u8>),
1535 SuccessReceiptId(CryptoHash),
1538}
1539
1540impl fmt::Debug for ExecutionStatusView {
1541 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1542 match self {
1543 ExecutionStatusView::Unknown => f.write_str("Unknown"),
1544 ExecutionStatusView::Failure(e) => f.write_fmt(format_args!("Failure({:?})", e)),
1545 ExecutionStatusView::SuccessValue(v) => {
1546 f.write_fmt(format_args!("SuccessValue({})", AbbrBytes(v)))
1547 }
1548 ExecutionStatusView::SuccessReceiptId(receipt_id) => {
1549 f.write_fmt(format_args!("SuccessReceiptId({})", receipt_id))
1550 }
1551 }
1552 }
1553}
1554
1555impl From<ExecutionStatus> for ExecutionStatusView {
1556 fn from(outcome: ExecutionStatus) -> Self {
1557 match outcome {
1558 ExecutionStatus::Unknown => ExecutionStatusView::Unknown,
1559 ExecutionStatus::Failure(e) => ExecutionStatusView::Failure(e),
1560 ExecutionStatus::SuccessValue(v) => ExecutionStatusView::SuccessValue(v),
1561 ExecutionStatus::SuccessReceiptId(receipt_id) => {
1562 ExecutionStatusView::SuccessReceiptId(receipt_id)
1563 }
1564 }
1565 }
1566}
1567
1568#[derive(
1569 BorshSerialize,
1570 BorshDeserialize,
1571 PartialEq,
1572 Clone,
1573 Eq,
1574 Debug,
1575 serde::Serialize,
1576 serde::Deserialize,
1577)]
1578pub struct CostGasUsed {
1579 pub cost_category: String,
1580 pub cost: String,
1581 #[serde(with = "dec_format")]
1582 pub gas_used: Gas,
1583}
1584
1585#[derive(
1586 BorshSerialize,
1587 BorshDeserialize,
1588 PartialEq,
1589 Clone,
1590 Eq,
1591 Debug,
1592 serde::Serialize,
1593 serde::Deserialize,
1594)]
1595pub struct ExecutionMetadataView {
1596 pub version: u32,
1597 pub gas_profile: Option<Vec<CostGasUsed>>,
1598}
1599
1600impl Default for ExecutionMetadataView {
1601 fn default() -> Self {
1602 ExecutionMetadata::V1.into()
1603 }
1604}
1605
1606impl From<ExecutionMetadata> for ExecutionMetadataView {
1607 fn from(metadata: ExecutionMetadata) -> Self {
1608 let version = match metadata {
1609 ExecutionMetadata::V1 => 1,
1610 ExecutionMetadata::V2(_) => 2,
1611 ExecutionMetadata::V3(_) => 3,
1612 };
1613 let mut gas_profile = match metadata {
1614 ExecutionMetadata::V1 => None,
1615 ExecutionMetadata::V2(profile_data) => {
1616 let mut costs: Vec<CostGasUsed> = profile_data
1622 .legacy_action_costs()
1623 .into_iter()
1624 .filter(|&(_, gas)| gas > 0)
1625 .map(|(name, gas)| CostGasUsed::action(name.to_string(), gas))
1626 .collect();
1627
1628 costs.push(CostGasUsed::wasm_host(
1630 "WASM_INSTRUCTION".to_string(),
1631 profile_data.get_wasm_cost(),
1632 ));
1633
1634 for ext_cost in ExtCosts::iter() {
1636 costs.push(CostGasUsed::wasm_host(
1637 format!("{:?}", ext_cost).to_ascii_uppercase(),
1638 profile_data.get_ext_cost(ext_cost),
1639 ));
1640 }
1641
1642 Some(costs)
1643 }
1644 ExecutionMetadata::V3(profile) => {
1645 let mut costs: Vec<CostGasUsed> = ActionCosts::iter()
1648 .flat_map(|cost| {
1649 let gas_used = profile.get_action_cost(cost);
1650 (gas_used > 0).then(|| {
1651 CostGasUsed::action(
1652 format!("{:?}", cost).to_ascii_uppercase(),
1653 gas_used,
1654 )
1655 })
1656 })
1657 .collect();
1658
1659 let wasm_gas_used = profile.get_wasm_cost();
1661 if wasm_gas_used > 0 {
1662 costs.push(CostGasUsed::wasm_host(
1663 "WASM_INSTRUCTION".to_string(),
1664 wasm_gas_used,
1665 ));
1666 }
1667
1668 for ext_cost in ExtCosts::iter() {
1670 let gas_used = profile.get_ext_cost(ext_cost);
1671 if gas_used > 0 {
1672 costs.push(CostGasUsed::wasm_host(
1673 format!("{:?}", ext_cost).to_ascii_uppercase(),
1674 gas_used,
1675 ));
1676 }
1677 }
1678
1679 Some(costs)
1680 }
1681 };
1682 if let Some(ref mut costs) = gas_profile {
1683 costs.sort_by(|lhs, rhs| {
1690 lhs.cost_category.cmp(&rhs.cost_category).then_with(|| lhs.cost.cmp(&rhs.cost))
1691 });
1692 }
1693 ExecutionMetadataView { version, gas_profile }
1694 }
1695}
1696
1697impl CostGasUsed {
1698 pub fn action(cost: String, gas_used: Gas) -> Self {
1699 Self { cost_category: "ACTION_COST".to_string(), cost, gas_used }
1700 }
1701
1702 pub fn wasm_host(cost: String, gas_used: Gas) -> Self {
1703 Self { cost_category: "WASM_HOST_COST".to_string(), cost, gas_used }
1704 }
1705}
1706
1707#[derive(
1708 BorshSerialize,
1709 BorshDeserialize,
1710 Debug,
1711 Clone,
1712 PartialEq,
1713 Eq,
1714 serde::Serialize,
1715 serde::Deserialize,
1716)]
1717pub struct ExecutionOutcomeView {
1718 pub logs: Vec<String>,
1720 pub receipt_ids: Vec<CryptoHash>,
1722 pub gas_burnt: Gas,
1724 #[serde(with = "dec_format")]
1728 pub tokens_burnt: Balance,
1729 pub executor_id: AccountId,
1732 pub status: ExecutionStatusView,
1734 #[serde(default)]
1736 pub metadata: ExecutionMetadataView,
1737}
1738
1739impl From<ExecutionOutcome> for ExecutionOutcomeView {
1740 fn from(outcome: ExecutionOutcome) -> Self {
1741 Self {
1742 logs: outcome.logs,
1743 receipt_ids: outcome.receipt_ids,
1744 gas_burnt: outcome.gas_burnt,
1745 tokens_burnt: outcome.tokens_burnt,
1746 executor_id: outcome.executor_id,
1747 status: outcome.status.into(),
1748 metadata: outcome.metadata.into(),
1749 }
1750 }
1751}
1752
1753impl From<&ExecutionOutcomeView> for PartialExecutionOutcome {
1754 fn from(outcome: &ExecutionOutcomeView) -> Self {
1755 Self {
1756 receipt_ids: outcome.receipt_ids.clone(),
1757 gas_burnt: outcome.gas_burnt,
1758 tokens_burnt: outcome.tokens_burnt,
1759 executor_id: outcome.executor_id.clone(),
1760 status: outcome.status.clone().into(),
1761 }
1762 }
1763}
1764impl From<ExecutionStatusView> for PartialExecutionStatus {
1765 fn from(status: ExecutionStatusView) -> PartialExecutionStatus {
1766 match status {
1767 ExecutionStatusView::Unknown => PartialExecutionStatus::Unknown,
1768 ExecutionStatusView::Failure(_) => PartialExecutionStatus::Failure,
1769 ExecutionStatusView::SuccessValue(value) => PartialExecutionStatus::SuccessValue(value),
1770 ExecutionStatusView::SuccessReceiptId(id) => {
1771 PartialExecutionStatus::SuccessReceiptId(id)
1772 }
1773 }
1774 }
1775}
1776
1777impl ExecutionOutcomeView {
1778 pub fn to_hashes(&self, id: CryptoHash) -> Vec<CryptoHash> {
1780 let mut result = Vec::with_capacity(self.logs.len().saturating_add(2));
1781 result.push(id);
1782 result.push(CryptoHash::hash_borsh(&PartialExecutionOutcome::from(self)));
1783 result.extend(self.logs.iter().map(|log| hash(log.as_bytes())));
1784 result
1785 }
1786}
1787
1788#[cfg_attr(feature = "deepsize_feature", derive(deepsize::DeepSizeOf))]
1789#[derive(
1790 BorshSerialize,
1791 BorshDeserialize,
1792 Debug,
1793 PartialEq,
1794 Eq,
1795 Clone,
1796 serde::Serialize,
1797 serde::Deserialize,
1798)]
1799pub struct ExecutionOutcomeWithIdView {
1800 pub proof: MerklePath,
1801 pub block_hash: CryptoHash,
1802 pub id: CryptoHash,
1803 pub outcome: ExecutionOutcomeView,
1804}
1805
1806impl From<ExecutionOutcomeWithIdAndProof> for ExecutionOutcomeWithIdView {
1807 fn from(outcome_with_id_and_proof: ExecutionOutcomeWithIdAndProof) -> Self {
1808 Self {
1809 proof: outcome_with_id_and_proof.proof,
1810 block_hash: outcome_with_id_and_proof.block_hash,
1811 id: outcome_with_id_and_proof.outcome_with_id.id,
1812 outcome: outcome_with_id_and_proof.outcome_with_id.outcome.into(),
1813 }
1814 }
1815}
1816
1817impl ExecutionOutcomeWithIdView {
1818 pub fn to_hashes(&self) -> Vec<CryptoHash> {
1819 self.outcome.to_hashes(self.id)
1820 }
1821}
1822#[derive(Clone, Debug)]
1823pub struct TxStatusView {
1824 pub execution_outcome: Option<FinalExecutionOutcomeViewEnum>,
1825 pub status: TxExecutionStatus,
1826}
1827
1828#[derive(
1829 BorshSerialize,
1830 BorshDeserialize,
1831 serde::Serialize,
1832 serde::Deserialize,
1833 Clone,
1834 Debug,
1835 Default,
1836 Eq,
1837 PartialEq,
1838)]
1839#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
1840pub enum TxExecutionStatus {
1841 None,
1843 Included,
1845 #[default]
1849 ExecutedOptimistic,
1850 IncludedFinal,
1852 Executed,
1856 Final,
1859}
1860
1861#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, serde::Deserialize, Debug, Clone)]
1862#[serde(untagged)]
1863pub enum FinalExecutionOutcomeViewEnum {
1864 FinalExecutionOutcome(FinalExecutionOutcomeView),
1865 FinalExecutionOutcomeWithReceipt(FinalExecutionOutcomeWithReceiptView),
1866}
1867
1868impl FinalExecutionOutcomeViewEnum {
1869 pub fn into_outcome(self) -> FinalExecutionOutcomeView {
1870 match self {
1871 Self::FinalExecutionOutcome(outcome) => outcome,
1872 Self::FinalExecutionOutcomeWithReceipt(outcome) => outcome.final_outcome,
1873 }
1874 }
1875}
1876
1877impl TxStatusView {
1878 pub fn into_outcome(self) -> Option<FinalExecutionOutcomeView> {
1879 self.execution_outcome.map(|outcome| match outcome {
1880 FinalExecutionOutcomeViewEnum::FinalExecutionOutcome(outcome) => outcome,
1881 FinalExecutionOutcomeViewEnum::FinalExecutionOutcomeWithReceipt(outcome) => {
1882 outcome.final_outcome
1883 }
1884 })
1885 }
1886}
1887
1888#[derive(
1891 BorshSerialize, BorshDeserialize, serde::Serialize, serde::Deserialize, PartialEq, Eq, Clone,
1892)]
1893pub struct FinalExecutionOutcomeView {
1894 pub status: FinalExecutionStatus,
1900 pub transaction: SignedTransactionView,
1902 pub transaction_outcome: ExecutionOutcomeWithIdView,
1904 pub receipts_outcome: Vec<ExecutionOutcomeWithIdView>,
1906}
1907
1908impl fmt::Debug for FinalExecutionOutcomeView {
1909 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1910 f.debug_struct("FinalExecutionOutcome")
1911 .field("status", &self.status)
1912 .field("transaction", &self.transaction)
1913 .field("transaction_outcome", &self.transaction_outcome)
1914 .field("receipts_outcome", &Slice(&self.receipts_outcome))
1915 .finish()
1916 }
1917}
1918
1919#[derive(
1922 BorshSerialize,
1923 BorshDeserialize,
1924 PartialEq,
1925 Eq,
1926 Clone,
1927 Debug,
1928 serde::Serialize,
1929 serde::Deserialize,
1930)]
1931pub struct FinalExecutionOutcomeWithReceiptView {
1932 #[serde(flatten)]
1934 pub final_outcome: FinalExecutionOutcomeView,
1935 pub receipts: Vec<ReceiptView>,
1937}
1938
1939pub mod validator_pledge_view {
1940 pub use super::ValidatorPowerViewV1;
1941 use crate::types::validator_stake::ValidatorPledge;
1942 use borsh::{BorshDeserialize, BorshSerialize};
1943 use serde::Deserialize;
1944 use unc_primitives_core::types::AccountId;
1945
1946 #[derive(
1947 BorshSerialize, BorshDeserialize, serde::Serialize, Deserialize, Debug, Clone, Eq, PartialEq,
1948 )]
1949 #[serde(tag = "validator_pledge_struct_version")]
1950 pub enum ValidatorPledgeView {
1951 V1(crate::views::ValidatorPledgeViewV1),
1952 }
1953
1954 impl crate::views::validator_pledge_view::ValidatorPledgeView {
1955 pub fn into_validator_pledge(self) -> ValidatorPledge {
1956 self.into()
1957 }
1958
1959 #[inline]
1960 pub fn take_account_id(self) -> AccountId {
1961 match self {
1962 Self::V1(v1) => v1.account_id,
1963 }
1964 }
1965
1966 #[inline]
1967 pub fn account_id(&self) -> &AccountId {
1968 match self {
1969 Self::V1(v1) => &v1.account_id,
1970 }
1971 }
1972 }
1973
1974 impl From<ValidatorPledge> for crate::views::validator_pledge_view::ValidatorPledgeView {
1975 fn from(pledge: ValidatorPledge) -> Self {
1976 match pledge {
1977 ValidatorPledge::V1(v1) => Self::V1(crate::views::ValidatorPledgeViewV1 {
1978 account_id: v1.account_id,
1979 public_key: v1.public_key,
1980 pledge: v1.pledge,
1981 }),
1982 }
1983 }
1984 }
1985
1986 impl From<crate::views::validator_pledge_view::ValidatorPledgeView> for ValidatorPledge {
1987 fn from(view: crate::views::validator_pledge_view::ValidatorPledgeView) -> Self {
1988 match view {
1989 crate::views::validator_pledge_view::ValidatorPledgeView::V1(v1) => {
1990 Self::new_v1(v1.account_id, v1.public_key, v1.pledge)
1991 }
1992 }
1993 }
1994 }
1995}
1996
1997#[derive(
1998 BorshSerialize,
1999 BorshDeserialize,
2000 Debug,
2001 Clone,
2002 Eq,
2003 PartialEq,
2004 serde::Serialize,
2005 serde::Deserialize,
2006)]
2007pub struct ValidatorPledgeViewV1 {
2008 pub account_id: AccountId,
2009 pub public_key: PublicKey,
2010 #[serde(with = "dec_format")]
2011 pub pledge: Balance,
2012}
2013pub mod validator_power_view {
2014 pub use super::ValidatorPowerViewV1;
2015 use crate::types::validator_power::ValidatorPower;
2016 use borsh::{BorshDeserialize, BorshSerialize};
2017 use serde::Deserialize;
2018 use unc_primitives_core::types::AccountId;
2019
2020 #[derive(
2021 BorshSerialize, BorshDeserialize, serde::Serialize, Deserialize, Debug, Clone, Eq, PartialEq,
2022 )]
2023 #[serde(tag = "validator_power_struct_version")]
2024 pub enum ValidatorPowerView {
2025 V1(ValidatorPowerViewV1),
2026 }
2027
2028 impl ValidatorPowerView {
2029 pub fn into_validator_power(self) -> ValidatorPower {
2030 self.into()
2031 }
2032
2033 #[inline]
2034 pub fn take_account_id(self) -> AccountId {
2035 match self {
2036 Self::V1(v1) => v1.account_id,
2037 }
2038 }
2039
2040 #[inline]
2041 pub fn account_id(&self) -> &AccountId {
2042 match self {
2043 Self::V1(v1) => &v1.account_id,
2044 }
2045 }
2046 }
2047
2048 impl From<ValidatorPower> for ValidatorPowerView {
2049 fn from(power: ValidatorPower) -> Self {
2050 match power {
2051 ValidatorPower::V1(v1) => Self::V1(ValidatorPowerViewV1 {
2052 account_id: v1.account_id,
2053 public_key: v1.public_key,
2054 power: v1.power,
2055 }),
2056 }
2057 }
2058 }
2059
2060 impl From<ValidatorPowerView> for ValidatorPower {
2061 fn from(view: ValidatorPowerView) -> Self {
2062 match view {
2063 ValidatorPowerView::V1(v1) => Self::new_v1(v1.account_id, v1.public_key, v1.power),
2064 }
2065 }
2066 }
2067}
2068
2069#[derive(
2070 BorshSerialize,
2071 BorshDeserialize,
2072 Debug,
2073 Clone,
2074 Eq,
2075 PartialEq,
2076 serde::Serialize,
2077 serde::Deserialize,
2078)]
2079pub struct ValidatorPowerViewV1 {
2080 pub account_id: AccountId,
2081 pub public_key: PublicKey,
2082 #[serde(with = "dec_format")]
2083 pub power: Power,
2084}
2085
2086pub mod validator_power_and_pledge_view {
2087 pub use super::ValidatorPowerViewV1;
2088 use crate::types::validator_power_and_pledge::ValidatorPowerAndPledge;
2089 use borsh::{BorshDeserialize, BorshSerialize};
2090 use serde::Deserialize;
2091 use unc_primitives_core::types::AccountId;
2092
2093 #[derive(
2094 BorshSerialize, BorshDeserialize, serde::Serialize, Deserialize, Debug, Clone, Eq, PartialEq,
2095 )]
2096 #[serde(tag = "validator_power_and_pledge_struct_version")]
2097 pub enum ValidatorPowerAndPledgeView {
2098 V1(crate::views::ValidatorPowerAndPledgeViewV1),
2099 }
2100
2101 impl crate::views::validator_power_and_pledge_view::ValidatorPowerAndPledgeView {
2102 pub fn into_validator_power_and_pledge(self) -> ValidatorPowerAndPledge {
2103 self.into()
2104 }
2105
2106 #[inline]
2107 pub fn take_account_id(self) -> AccountId {
2108 match self {
2109 Self::V1(v1) => v1.account_id,
2110 }
2111 }
2112
2113 #[inline]
2114 pub fn account_id(&self) -> &AccountId {
2115 match self {
2116 Self::V1(v1) => &v1.account_id,
2117 }
2118 }
2119 }
2120
2121 impl From<ValidatorPowerAndPledge>
2122 for crate::views::validator_power_and_pledge_view::ValidatorPowerAndPledgeView
2123 {
2124 fn from(power_pledge: ValidatorPowerAndPledge) -> Self {
2125 match power_pledge {
2126 ValidatorPowerAndPledge::V1(v1) => {
2127 Self::V1(crate::views::ValidatorPowerAndPledgeViewV1 {
2128 account_id: v1.account_id,
2129 public_key: v1.public_key,
2130 power: v1.power,
2131 pledge: v1.pledge,
2132 })
2133 }
2134 }
2135 }
2136 }
2137
2138 impl From<crate::views::validator_power_and_pledge_view::ValidatorPowerAndPledgeView>
2139 for ValidatorPowerAndPledge
2140 {
2141 fn from(
2142 view: crate::views::validator_power_and_pledge_view::ValidatorPowerAndPledgeView,
2143 ) -> Self {
2144 match view {
2145 crate::views::validator_power_and_pledge_view::ValidatorPowerAndPledgeView::V1(
2146 v1,
2147 ) => Self::new_v1(v1.account_id, v1.public_key, v1.power, v1.pledge),
2148 }
2149 }
2150 }
2151}
2152
2153#[derive(
2154 BorshSerialize,
2155 BorshDeserialize,
2156 Debug,
2157 Clone,
2158 Eq,
2159 PartialEq,
2160 serde::Serialize,
2161 serde::Deserialize,
2162)]
2163pub struct ValidatorPowerAndPledgeViewV1 {
2164 pub account_id: AccountId,
2165 pub public_key: PublicKey,
2166 #[serde(with = "dec_format")]
2167 pub power: Power,
2168 pub pledge: Balance,
2169}
2170
2171#[derive(
2172 BorshSerialize,
2173 BorshDeserialize,
2174 Clone,
2175 Debug,
2176 PartialEq,
2177 Eq,
2178 serde::Serialize,
2179 serde::Deserialize,
2180)]
2181pub struct ReceiptView {
2182 pub predecessor_id: AccountId,
2183 pub receiver_id: AccountId,
2184 pub receipt_id: CryptoHash,
2185
2186 pub receipt: ReceiptEnumView,
2187}
2188
2189#[derive(
2190 BorshSerialize,
2191 BorshDeserialize,
2192 Clone,
2193 Debug,
2194 PartialEq,
2195 Eq,
2196 serde::Serialize,
2197 serde::Deserialize,
2198)]
2199pub struct DataReceiverView {
2200 pub data_id: CryptoHash,
2201 pub receiver_id: AccountId,
2202}
2203
2204#[serde_as]
2205#[derive(
2206 BorshSerialize,
2207 BorshDeserialize,
2208 Clone,
2209 Debug,
2210 PartialEq,
2211 Eq,
2212 serde::Serialize,
2213 serde::Deserialize,
2214)]
2215pub enum ReceiptEnumView {
2216 Action {
2217 signer_id: AccountId,
2218 signer_public_key: PublicKey,
2219 #[serde(with = "dec_format")]
2220 gas_price: Balance,
2221 output_data_receivers: Vec<DataReceiverView>,
2222 input_data_ids: Vec<CryptoHash>,
2223 actions: Vec<ActionView>,
2224 },
2225 Data {
2226 data_id: CryptoHash,
2227 #[serde_as(as = "Option<Base64>")]
2228 data: Option<Vec<u8>>,
2229 },
2230}
2231
2232impl From<Receipt> for ReceiptView {
2233 fn from(receipt: Receipt) -> Self {
2234 ReceiptView {
2235 predecessor_id: receipt.predecessor_id,
2236 receiver_id: receipt.receiver_id,
2237 receipt_id: receipt.receipt_id,
2238 receipt: match receipt.receipt {
2239 ReceiptEnum::Action(action_receipt) => ReceiptEnumView::Action {
2240 signer_id: action_receipt.signer_id,
2241 signer_public_key: action_receipt.signer_public_key,
2242 gas_price: action_receipt.gas_price,
2243 output_data_receivers: action_receipt
2244 .output_data_receivers
2245 .into_iter()
2246 .map(|data_receiver| DataReceiverView {
2247 data_id: data_receiver.data_id,
2248 receiver_id: data_receiver.receiver_id,
2249 })
2250 .collect(),
2251 input_data_ids: action_receipt
2252 .input_data_ids
2253 .into_iter()
2254 .map(Into::into)
2255 .collect(),
2256 actions: action_receipt.actions.into_iter().map(Into::into).collect(),
2257 },
2258 ReceiptEnum::Data(data_receipt) => {
2259 ReceiptEnumView::Data { data_id: data_receipt.data_id, data: data_receipt.data }
2260 }
2261 },
2262 }
2263 }
2264}
2265
2266impl TryFrom<ReceiptView> for Receipt {
2267 type Error = Box<dyn std::error::Error + Send + Sync>;
2268
2269 fn try_from(receipt_view: ReceiptView) -> Result<Self, Self::Error> {
2270 Ok(Receipt {
2271 predecessor_id: receipt_view.predecessor_id,
2272 receiver_id: receipt_view.receiver_id,
2273 receipt_id: receipt_view.receipt_id,
2274 receipt: match receipt_view.receipt {
2275 ReceiptEnumView::Action {
2276 signer_id,
2277 signer_public_key,
2278 gas_price,
2279 output_data_receivers,
2280 input_data_ids,
2281 actions,
2282 } => ReceiptEnum::Action(ActionReceipt {
2283 signer_id,
2284 signer_public_key,
2285 gas_price,
2286 output_data_receivers: output_data_receivers
2287 .into_iter()
2288 .map(|data_receiver_view| DataReceiver {
2289 data_id: data_receiver_view.data_id,
2290 receiver_id: data_receiver_view.receiver_id,
2291 })
2292 .collect(),
2293 input_data_ids: input_data_ids.into_iter().map(Into::into).collect(),
2294 actions: actions
2295 .into_iter()
2296 .map(TryInto::try_into)
2297 .collect::<Result<Vec<_>, _>>()?,
2298 }),
2299 ReceiptEnumView::Data { data_id, data } => {
2300 ReceiptEnum::Data(DataReceipt { data_id, data })
2301 }
2302 },
2303 })
2304 }
2305}
2306
2307#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone)]
2309pub struct EpochValidatorInfo {
2310 pub current_validators: Vec<CurrentEpochValidatorInfo>,
2312 pub next_validators: Vec<NextEpochValidatorInfo>,
2314 pub current_fishermen: Vec<ValidatorPledgeView>,
2316 pub next_fishermen: Vec<ValidatorPledgeView>,
2318 pub current_power_proposals: Vec<ValidatorPowerView>,
2320 pub current_pledge_proposals: Vec<ValidatorPledgeView>,
2322 pub prev_epoch_kickout: Vec<ValidatorKickoutView>,
2324 pub epoch_start_height: BlockHeight,
2326 pub epoch_height: EpochHeight,
2328}
2329
2330#[derive(
2331 BorshSerialize,
2332 BorshDeserialize,
2333 Debug,
2334 PartialEq,
2335 Eq,
2336 Clone,
2337 serde::Serialize,
2338 serde::Deserialize,
2339)]
2340pub struct ValidatorKickoutView {
2341 pub account_id: AccountId,
2342 pub reason: ValidatorKickoutReason,
2343}
2344
2345#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone)]
2346pub struct CurrentEpochValidatorInfo {
2347 pub account_id: AccountId,
2348 pub public_key: PublicKey,
2349 pub is_slashed: bool,
2350 #[serde(with = "dec_format")]
2351 pub power: Power,
2352 #[serde(with = "dec_format")]
2353 pub pledge: Balance,
2354 pub shards: Vec<ShardId>,
2355 pub num_produced_blocks: NumBlocks,
2356 pub num_expected_blocks: NumBlocks,
2357 #[serde(default)]
2358 pub num_produced_chunks: NumBlocks,
2359 #[serde(default)]
2360 pub num_expected_chunks: NumBlocks,
2361 #[serde(default)]
2363 pub num_produced_chunks_per_shard: Vec<NumBlocks>,
2364 #[serde(default)]
2365 pub num_expected_chunks_per_shard: Vec<NumBlocks>,
2366}
2367
2368#[derive(
2369 BorshSerialize,
2370 BorshDeserialize,
2371 Debug,
2372 PartialEq,
2373 Eq,
2374 Clone,
2375 serde::Serialize,
2376 serde::Deserialize,
2377)]
2378pub struct NextEpochValidatorInfo {
2379 pub account_id: AccountId,
2380 pub public_key: PublicKey,
2381 #[serde(with = "dec_format")]
2382 pub power: Power,
2383 #[serde(with = "dec_format")]
2384 pub pledge: Balance,
2385 pub shards: Vec<ShardId>,
2386}
2387
2388#[derive(
2389 PartialEq,
2390 Eq,
2391 Debug,
2392 Clone,
2393 BorshDeserialize,
2394 BorshSerialize,
2395 serde::Serialize,
2396 serde::Deserialize,
2397)]
2398pub struct LightClientBlockView {
2399 pub prev_block_hash: CryptoHash,
2400 pub next_block_inner_hash: CryptoHash,
2401 pub inner_lite: BlockHeaderInnerLiteView,
2402 pub inner_rest_hash: CryptoHash,
2403 pub next_bps: Option<Vec<ValidatorPowerAndPledgeView>>,
2404 pub approvals_after_next: Vec<Option<Box<Signature>>>,
2405}
2406
2407#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, BorshDeserialize, BorshSerialize)]
2408pub struct LightClientBlockLiteView {
2409 pub prev_block_hash: CryptoHash,
2410 pub inner_rest_hash: CryptoHash,
2411 pub inner_lite: BlockHeaderInnerLiteView,
2412}
2413
2414impl From<BlockHeader> for LightClientBlockLiteView {
2415 fn from(header: BlockHeader) -> Self {
2416 Self {
2417 prev_block_hash: *header.prev_hash(),
2418 inner_rest_hash: hash(&header.inner_rest_bytes()),
2419 inner_lite: header.into(),
2420 }
2421 }
2422}
2423impl LightClientBlockLiteView {
2424 pub fn hash(&self) -> CryptoHash {
2425 let block_header_inner_lite: BlockHeaderInnerLite = self.inner_lite.clone().into();
2426 combine_hash(
2427 &combine_hash(
2428 &hash(&borsh::to_vec(&block_header_inner_lite).unwrap()),
2429 &self.inner_rest_hash,
2430 ),
2431 &self.prev_block_hash,
2432 )
2433 }
2434}
2435
2436#[derive(serde::Serialize, serde::Deserialize, Debug)]
2437pub struct GasPriceView {
2438 #[serde(with = "dec_format")]
2439 pub gas_price: Balance,
2440}
2441
2442#[derive(Debug, serde::Serialize, serde::Deserialize)]
2447#[serde(tag = "changes_type", rename_all = "snake_case")]
2448pub enum StateChangesRequestView {
2449 AccountChanges {
2450 account_ids: Vec<AccountId>,
2451 },
2452 SingleAccessKeyChanges {
2453 keys: Vec<AccountWithPublicKey>,
2454 },
2455 AllAccessKeyChanges {
2456 account_ids: Vec<AccountId>,
2457 },
2458 ContractCodeChanges {
2459 account_ids: Vec<AccountId>,
2460 },
2461 DataChanges {
2462 account_ids: Vec<AccountId>,
2463 #[serde(rename = "key_prefix_base64")]
2464 key_prefix: StoreKey,
2465 },
2466}
2467
2468impl From<StateChangesRequestView> for StateChangesRequest {
2469 fn from(request: StateChangesRequestView) -> Self {
2470 match request {
2471 StateChangesRequestView::AccountChanges { account_ids } => {
2472 Self::AccountChanges { account_ids }
2473 }
2474 StateChangesRequestView::SingleAccessKeyChanges { keys } => {
2475 Self::SingleAccessKeyChanges { keys }
2476 }
2477 StateChangesRequestView::AllAccessKeyChanges { account_ids } => {
2478 Self::AllAccessKeyChanges { account_ids }
2479 }
2480 StateChangesRequestView::ContractCodeChanges { account_ids } => {
2481 Self::ContractCodeChanges { account_ids }
2482 }
2483 StateChangesRequestView::DataChanges { account_ids, key_prefix } => {
2484 Self::DataChanges { account_ids, key_prefix }
2485 }
2486 }
2487 }
2488}
2489
2490#[derive(Debug, serde::Serialize, serde::Deserialize)]
2495#[serde(rename_all = "snake_case", tag = "type")]
2496pub enum StateChangeKindView {
2497 AccountTouched { account_id: AccountId },
2498 AccessKeyTouched { account_id: AccountId },
2499 DataTouched { account_id: AccountId },
2500 ContractCodeTouched { account_id: AccountId },
2501 RsaKeyTouched { account_id: AccountId },
2502}
2503
2504impl From<StateChangeKind> for StateChangeKindView {
2505 fn from(state_change_kind: StateChangeKind) -> Self {
2506 match state_change_kind {
2507 StateChangeKind::AccountTouched { account_id } => Self::AccountTouched { account_id },
2508 StateChangeKind::AccessKeyTouched { account_id } => {
2509 Self::AccessKeyTouched { account_id }
2510 }
2511 StateChangeKind::RsaKeyTouched { account_id } => Self::RsaKeyTouched { account_id },
2512 StateChangeKind::DataTouched { account_id } => Self::DataTouched { account_id },
2513 StateChangeKind::ContractCodeTouched { account_id } => {
2514 Self::ContractCodeTouched { account_id }
2515 }
2516 }
2517 }
2518}
2519
2520pub type StateChangesKindsView = Vec<StateChangeKindView>;
2521
2522#[derive(Debug, serde::Serialize, serde::Deserialize)]
2524#[serde(rename_all = "snake_case", tag = "type")]
2525pub enum StateChangeCauseView {
2526 NotWritableToDisk,
2527 InitialState,
2528 TransactionProcessing { tx_hash: CryptoHash },
2529 ActionReceiptProcessingStarted { receipt_hash: CryptoHash },
2530 ActionReceiptGasReward { receipt_hash: CryptoHash },
2531 ReceiptProcessing { receipt_hash: CryptoHash },
2532 PostponedReceipt { receipt_hash: CryptoHash },
2533 UpdatedDelayedReceipts,
2534 ValidatorAccountsUpdate,
2535 Migration,
2536 Resharding,
2537}
2538
2539impl From<StateChangeCause> for StateChangeCauseView {
2540 fn from(state_change_cause: StateChangeCause) -> Self {
2541 match state_change_cause {
2542 StateChangeCause::NotWritableToDisk => Self::NotWritableToDisk,
2543 StateChangeCause::InitialState => Self::InitialState,
2544 StateChangeCause::TransactionProcessing { tx_hash } => {
2545 Self::TransactionProcessing { tx_hash }
2546 }
2547 StateChangeCause::ActionReceiptProcessingStarted { receipt_hash } => {
2548 Self::ActionReceiptProcessingStarted { receipt_hash }
2549 }
2550 StateChangeCause::ActionReceiptGasReward { receipt_hash } => {
2551 Self::ActionReceiptGasReward { receipt_hash }
2552 }
2553 StateChangeCause::ReceiptProcessing { receipt_hash } => {
2554 Self::ReceiptProcessing { receipt_hash }
2555 }
2556 StateChangeCause::PostponedReceipt { receipt_hash } => {
2557 Self::PostponedReceipt { receipt_hash }
2558 }
2559 StateChangeCause::UpdatedDelayedReceipts => Self::UpdatedDelayedReceipts,
2560 StateChangeCause::ValidatorAccountsUpdate => Self::ValidatorAccountsUpdate,
2561 StateChangeCause::Migration => Self::Migration,
2562 StateChangeCause::Resharding => Self::Resharding,
2563 }
2564 }
2565}
2566
2567#[serde_as]
2568#[derive(Debug, serde::Serialize, serde::Deserialize)]
2569#[serde(rename_all = "snake_case", tag = "type", content = "change")]
2570pub enum StateChangeValueView {
2571 AccountUpdate {
2572 account_id: AccountId,
2573 #[serde(flatten)]
2574 account: AccountView,
2575 },
2576 AccountDeletion {
2577 account_id: AccountId,
2578 },
2579 AccessKeyUpdate {
2580 account_id: AccountId,
2581 public_key: PublicKey,
2582 access_key: AccessKeyView,
2583 },
2584 AccessKeyDeletion {
2585 account_id: AccountId,
2586 public_key: PublicKey,
2587 },
2588 DataUpdate {
2589 account_id: AccountId,
2590 #[serde(rename = "key_base64")]
2591 key: StoreKey,
2592 #[serde(rename = "value_base64")]
2593 value: StoreValue,
2594 },
2595 DataDeletion {
2596 account_id: AccountId,
2597 #[serde(rename = "key_base64")]
2598 key: StoreKey,
2599 },
2600 ContractCodeUpdate {
2601 account_id: AccountId,
2602 #[serde(rename = "code_base64")]
2603 #[serde_as(as = "Base64")]
2604 code: Vec<u8>,
2605 },
2606 ContractCodeDeletion {
2607 account_id: AccountId,
2608 },
2609 RsaKeyUpdate {
2610 account_id: AccountId,
2611 public_key: PublicKey,
2612 rsa_key: RegisterRsa2048KeysAction,
2613 },
2614 RsaKeyDeletion {
2615 account_id: AccountId,
2616 public_key: PublicKey,
2617 },
2618}
2619
2620impl From<StateChangeValue> for StateChangeValueView {
2621 fn from(state_change: StateChangeValue) -> Self {
2622 match state_change {
2623 StateChangeValue::AccountUpdate { account_id, account } => {
2624 Self::AccountUpdate { account_id, account: account.into() }
2625 }
2626 StateChangeValue::AccountDeletion { account_id } => {
2627 Self::AccountDeletion { account_id }
2628 }
2629 StateChangeValue::AccessKeyUpdate { account_id, public_key, access_key } => {
2630 Self::AccessKeyUpdate { account_id, public_key, access_key: access_key.into() }
2631 }
2632 StateChangeValue::AccessKeyDeletion { account_id, public_key } => {
2633 Self::AccessKeyDeletion { account_id, public_key }
2634 }
2635 StateChangeValue::DataUpdate { account_id, key, value } => {
2636 Self::DataUpdate { account_id, key, value }
2637 }
2638 StateChangeValue::DataDeletion { account_id, key } => {
2639 Self::DataDeletion { account_id, key }
2640 }
2641 StateChangeValue::ContractCodeUpdate { account_id, code } => {
2642 Self::ContractCodeUpdate { account_id, code }
2643 }
2644 StateChangeValue::ContractCodeDeletion { account_id } => {
2645 Self::ContractCodeDeletion { account_id }
2646 }
2647 StateChangeValue::RsaKeyUpdate { account_id, public_key, rsa_key } => {
2648 Self::RsaKeyUpdate { account_id, public_key, rsa_key: rsa_key.into() }
2649 }
2650 StateChangeValue::RsaKeyDeletion { account_id, public_key } => {
2651 Self::RsaKeyDeletion { account_id, public_key }
2652 }
2653 }
2654 }
2655}
2656
2657#[derive(Debug, serde::Serialize, serde::Deserialize)]
2658pub struct StateChangeWithCauseView {
2659 pub cause: StateChangeCauseView,
2660 #[serde(flatten)]
2661 pub value: StateChangeValueView,
2662}
2663
2664impl From<StateChangeWithCause> for StateChangeWithCauseView {
2665 fn from(state_change_with_cause: StateChangeWithCause) -> Self {
2666 let StateChangeWithCause { cause, value } = state_change_with_cause;
2667 Self { cause: cause.into(), value: value.into() }
2668 }
2669}
2670
2671pub type StateChangesView = Vec<StateChangeWithCauseView>;
2672
2673pub type MaintenanceWindowsView = Vec<Range<BlockHeight>>;
2675
2676#[derive(serde::Serialize, serde::Deserialize, Debug)]
2678pub struct SplitStorageInfoView {
2679 pub head_height: Option<BlockHeight>,
2680 pub final_head_height: Option<BlockHeight>,
2681 pub cold_head_height: Option<BlockHeight>,
2682
2683 pub hot_db_kind: Option<String>,
2684}
2685
2686#[cfg(test)]
2687mod tests {
2688 use super::ExecutionMetadataView;
2689 use crate::transaction::ExecutionMetadata;
2690 use unc_vm_runner::{ProfileDataV2, ProfileDataV3};
2691
2692 #[test]
2695 #[cfg_attr(feature = "nightly", ignore)]
2696 fn test_runtime_config_view() {
2697 use unc_parameters::{RuntimeConfig, RuntimeConfigStore, RuntimeConfigView};
2698 use unc_primitives_core::version::PROTOCOL_VERSION;
2699
2700 let config_store = RuntimeConfigStore::new(None);
2701 let config = config_store.get_config(PROTOCOL_VERSION);
2702 let view = RuntimeConfigView::from(RuntimeConfig::clone(config));
2703 insta::assert_json_snapshot!(&view, { ".wasm_config.vm_kind" => "<REDACTED>"});
2704 }
2705
2706 #[test]
2708 #[cfg_attr(feature = "nightly", ignore)]
2709 fn test_exec_metadata_v1_view() {
2710 let metadata = ExecutionMetadata::V1;
2711 let view = ExecutionMetadataView::from(metadata);
2712 insta::assert_json_snapshot!(view);
2713 }
2714
2715 #[test]
2717 #[cfg_attr(feature = "nightly", ignore)]
2718 fn test_exec_metadata_v2_view() {
2719 let metadata = ExecutionMetadata::V2(ProfileDataV2::test());
2720 let view = ExecutionMetadataView::from(metadata);
2721 insta::assert_json_snapshot!(view);
2722 }
2723
2724 #[test]
2726 #[cfg_attr(feature = "nightly", ignore)]
2727 fn test_exec_metadata_v3_view() {
2728 let metadata = ExecutionMetadata::V3(ProfileDataV3::test().into());
2729 let view = ExecutionMetadataView::from(metadata);
2730 insta::assert_json_snapshot!(view);
2731 }
2732}