1use crate::hash::CryptoHash;
2use crate::serialize::dec_format;
3use crate::transaction::{Action, TransferAction};
4use crate::types::{AccountId, Balance, ShardId};
5use borsh::{BorshDeserialize, BorshSerialize};
6use serde_with::base64::Base64;
7use serde_with::serde_as;
8use std::borrow::Borrow;
9use std::collections::HashMap;
10use std::fmt;
11use unc_crypto::{KeyType, PublicKey};
12use unc_fmt::AbbrBytes;
13
14pub use unc_vm_runner::logic::DataReceiver;
15
16#[derive(
19 BorshSerialize,
20 BorshDeserialize,
21 Debug,
22 PartialEq,
23 Eq,
24 Clone,
25 serde::Serialize,
26 serde::Deserialize,
27)]
28pub struct Receipt {
29 pub predecessor_id: AccountId,
32 pub receiver_id: AccountId,
34 pub receipt_id: CryptoHash,
36 pub receipt: ReceiptEnum,
38}
39
40impl Borrow<CryptoHash> for Receipt {
41 fn borrow(&self) -> &CryptoHash {
42 &self.receipt_id
43 }
44}
45
46impl Receipt {
47 pub fn get_hash(&self) -> CryptoHash {
49 self.receipt_id
50 }
51
52 pub fn new_balance_refund(receiver_id: &AccountId, refund: Balance) -> Self {
56 Receipt {
57 predecessor_id: "system".parse().unwrap(),
58 receiver_id: receiver_id.clone(),
59 receipt_id: CryptoHash::default(),
60
61 receipt: ReceiptEnum::Action(ActionReceipt {
62 signer_id: "system".parse().unwrap(),
63 signer_public_key: PublicKey::empty(KeyType::ED25519),
64 gas_price: 0,
65 output_data_receivers: vec![],
66 input_data_ids: vec![],
67 actions: vec![Action::Transfer(TransferAction { deposit: refund })],
68 }),
69 }
70 }
71
72 pub fn new_gas_refund(
79 receiver_id: &AccountId,
80 refund: Balance,
81 signer_public_key: PublicKey,
82 ) -> Self {
83 Receipt {
84 predecessor_id: "system".parse().unwrap(),
85 receiver_id: receiver_id.clone(),
86 receipt_id: CryptoHash::default(),
87
88 receipt: ReceiptEnum::Action(ActionReceipt {
89 signer_id: receiver_id.clone(),
90 signer_public_key,
91 gas_price: 0,
92 output_data_receivers: vec![],
93 input_data_ids: vec![],
94 actions: vec![Action::Transfer(TransferAction { deposit: refund })],
95 }),
96 }
97 }
98}
99
100#[derive(
102 BorshSerialize,
103 BorshDeserialize,
104 Clone,
105 Debug,
106 PartialEq,
107 Eq,
108 serde::Serialize,
109 serde::Deserialize,
110)]
111pub enum ReceiptEnum {
112 Action(ActionReceipt),
113 Data(DataReceipt),
114}
115
116#[derive(
118 BorshSerialize,
119 BorshDeserialize,
120 Debug,
121 PartialEq,
122 Eq,
123 Clone,
124 serde::Serialize,
125 serde::Deserialize,
126)]
127pub struct ActionReceipt {
128 pub signer_id: AccountId,
130 pub signer_public_key: PublicKey,
132 #[serde(with = "dec_format")]
134 pub gas_price: Balance,
135 pub output_data_receivers: Vec<DataReceiver>,
137 pub input_data_ids: Vec<CryptoHash>,
143 pub actions: Vec<Action>,
145}
146
147#[serde_as]
150#[derive(
151 BorshSerialize,
152 BorshDeserialize,
153 Hash,
154 PartialEq,
155 Eq,
156 Clone,
157 serde::Serialize,
158 serde::Deserialize,
159)]
160pub struct DataReceipt {
161 pub data_id: CryptoHash,
162 #[serde_as(as = "Option<Base64>")]
163 pub data: Option<Vec<u8>>,
164}
165
166impl fmt::Debug for DataReceipt {
167 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
168 f.debug_struct("DataReceipt")
169 .field("data_id", &self.data_id)
170 .field("data", &format_args!("{}", AbbrBytes(self.data.as_deref())))
171 .finish()
172 }
173}
174
175#[derive(BorshSerialize, BorshDeserialize, Hash, PartialEq, Eq, Clone)]
180pub struct ReceivedData {
181 pub data: Option<Vec<u8>>,
182}
183
184impl fmt::Debug for ReceivedData {
185 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
186 f.debug_struct("ReceivedData")
187 .field("data", &format_args!("{}", AbbrBytes(self.data.as_deref())))
188 .finish()
189 }
190}
191
192#[derive(Default, BorshSerialize, BorshDeserialize, Clone, PartialEq, Debug)]
194pub struct DelayedReceiptIndices {
195 pub first_index: u64,
197 pub next_available_index: u64,
199}
200
201impl DelayedReceiptIndices {
202 pub fn len(&self) -> u64 {
203 self.next_available_index - self.first_index
204 }
205}
206
207pub type ReceiptResult = HashMap<ShardId, Vec<Receipt>>;