1use super::common::*;
2use crate::scan_state::currency::{Balance, Magnitude, Nonce};
3use ark_ff::Zero;
4use mina_hasher::{create_legacy, Fp, Hashable, Hasher, ROInput};
5use mina_signer::CompressedPubKey;
6use o1_utils::FieldHelpers;
7use std::borrow::Cow;
8
9#[derive(Clone, Debug, Hash, PartialEq, Eq)]
10pub struct TokenIdLegacy(pub u64);
11
12impl Default for TokenIdLegacy {
13 fn default() -> Self {
14 Self(1)
15 }
16}
17
18#[derive(Clone, Debug)]
19pub struct PermissionsLegacy<Controller> {
20 pub stake: bool,
21 pub edit_state: Controller,
22 pub send: Controller,
23 pub receive: Controller,
24 pub set_delegate: Controller,
25 pub set_permissions: Controller,
26 pub set_verification_key: Controller,
27}
28
29impl PermissionsLegacy<AuthRequired> {
30 pub fn user_default() -> Self {
31 use AuthRequired::*;
32
33 Self {
34 stake: true,
35 edit_state: Signature,
36 send: Signature,
37 receive: None,
38 set_delegate: Signature,
39 set_permissions: Signature,
40 set_verification_key: Signature,
41 }
42 }
43
44 pub fn empty() -> Self {
45 use AuthRequired::*;
46
47 Self {
48 stake: false,
49 edit_state: None,
50 send: None,
51 receive: None,
52 set_delegate: None,
53 set_permissions: None,
54 set_verification_key: None,
55 }
56 }
57}
58
59impl Default for PermissionsLegacy<AuthRequired> {
60 fn default() -> Self {
61 Self::user_default()
62 }
63}
64
65#[derive(Clone, Debug)]
66pub struct SnappAccount {
67 pub app_state: Vec<Fp>,
68 pub verification_key: Option<Fp>,
69}
70
71impl Default for SnappAccount {
72 fn default() -> Self {
73 Self {
74 app_state: vec![Fp::zero(); 8],
75 verification_key: None,
76 }
77 }
78}
79
80impl Hashable for SnappAccount {
81 type D = ();
82
83 fn to_roinput(&self) -> ROInput {
84 let mut roi = ROInput::new();
85
86 if let Some(vk) = self.verification_key.as_ref() {
87 roi = roi.append_field(*vk);
88 } else {
89 roi = roi.append_field(
90 Fp::from_hex("77a430a03efafd14d72e1a3c45a1fdca8267fcce9a729a1d25128bb5dec69d3f")
93 .unwrap(),
94 );
95 }
96
97 for field in &self.app_state {
98 roi = roi.append_field(*field);
99 }
100
101 roi
102 }
103
104 fn domain_string(_domain_param: Self::D) -> Option<String> {
105 Some("CodaSnappAccount****".to_string())
106 }
107}
108
109#[derive(Clone, Debug)]
111pub struct AccountLegacy {
112 pub public_key: CompressedPubKey, pub token_id: TokenIdLegacy, pub token_permissions: TokenPermissions, pub balance: Balance, pub nonce: Nonce, pub receipt_chain_hash: ReceiptChainHash, pub delegate: Option<CompressedPubKey>, pub voting_for: VotingFor, pub timing: Timing, pub permissions: PermissionsLegacy<AuthRequired>, pub snap: Option<SnappAccount>,
123}
124
125pub fn get_legacy_hash_of<T: Hashable>(init_value: T::D, item: &T) -> Fp {
126 let mut hasher = create_legacy::<T>(init_value);
127 hasher.update(item);
128 hasher.digest()
129}
130
131impl Hashable for AccountLegacy {
132 type D = ();
133
134 fn to_roinput(&self) -> ROInput {
135 let mut roi = ROInput::new();
136
137 let snapp_accout = match self.snap.as_ref() {
139 Some(snapp) => Cow::Borrowed(snapp),
140 None => Cow::Owned(SnappAccount::default()),
141 };
142 let snapp_digest = get_legacy_hash_of((), snapp_accout.as_ref());
143
144 roi = roi.append_field(snapp_digest);
145
146 for auth in [
148 self.permissions.set_verification_key,
149 self.permissions.set_permissions,
150 self.permissions.set_delegate,
151 self.permissions.receive,
152 self.permissions.send,
153 self.permissions.edit_state,
154 ] {
155 for bit in auth.encode().to_bits() {
156 roi = roi.append_bool(bit);
157 }
158 }
159 roi = roi.append_bool(self.permissions.stake);
160
161 match &self.timing {
163 Timing::Untimed => {
164 roi = roi.append_bool(false);
165 roi = roi.append_u64(0); roi = roi.append_u32(0); roi = roi.append_u64(0); roi = roi.append_u32(1); roi = roi.append_u64(0); }
171 Timing::Timed {
172 initial_minimum_balance,
173 cliff_time,
174 cliff_amount,
175 vesting_period,
176 vesting_increment,
177 } => {
178 roi = roi.append_bool(true);
179 roi = roi.append_u64(initial_minimum_balance.as_u64());
180 roi = roi.append_u32(cliff_time.as_u32());
181 roi = roi.append_u64(cliff_amount.as_u64());
182 roi = roi.append_u32(vesting_period.as_u32());
183 roi = roi.append_u64(vesting_increment.as_u64());
184 }
185 }
186
187 roi = roi.append_field(self.voting_for.0);
189
190 match self.delegate.as_ref() {
192 Some(delegate) => {
193 roi = roi.append_field(delegate.x);
194 roi = roi.append_bool(delegate.is_odd);
195 }
196 None => {
197 roi = roi.append_field(Fp::zero());
199 roi = roi.append_bool(false);
200 }
201 }
202
203 roi = roi.append_field(self.receipt_chain_hash.0);
205
206 roi = roi.append_u32(self.nonce.as_u32());
208
209 roi = roi.append_u64(self.balance.as_u64());
211
212 match self.token_permissions {
214 TokenPermissions::TokenOwned {
215 disable_new_accounts,
216 } => {
217 roi = roi.append_bool(true);
218 roi = roi.append_bool(disable_new_accounts);
219 }
220 TokenPermissions::NotOwned { account_disabled } => {
221 roi = roi.append_bool(false);
222 roi = roi.append_bool(account_disabled);
223 }
224 }
225
226 roi = roi.append_u64(self.token_id.0);
228
229 roi = roi.append_field(self.public_key.x);
231 roi = roi.append_bool(self.public_key.is_odd);
232
233 roi
234 }
235
236 fn domain_string(_: ()) -> Option<String> {
237 Some("CodaAccount*********".to_string())
238 }
239}
240
241impl AccountLegacy {
242 pub fn create() -> Self {
243 let pubkey = CompressedPubKey::from_address(
244 "B62qnzbXmRNo9q32n4SNu2mpB8e7FYYLH8NmaX6oFCBYjjQ8SbD7uzV",
245 )
246 .unwrap();
247
248 Self {
249 public_key: pubkey.clone(),
250 token_id: TokenIdLegacy::default(),
251 token_permissions: TokenPermissions::NotOwned {
252 account_disabled: false,
253 },
254 balance: Balance::from_u64(10101),
255 nonce: Nonce::from_u32(62772),
256 receipt_chain_hash: ReceiptChainHash::default(),
257 delegate: Some(pubkey),
258 voting_for: VotingFor::default(),
259 timing: Timing::Untimed,
260 permissions: PermissionsLegacy::user_default(),
261 snap: None,
262 }
263 }
264
265 pub fn empty() -> Self {
266 Self {
267 public_key: CompressedPubKey {
268 x: Fp::zero(),
269 is_odd: false,
270 },
271 token_id: TokenIdLegacy::default(),
272 token_permissions: TokenPermissions::default(),
273 balance: Balance::zero(),
274 nonce: Nonce::zero(),
275 receipt_chain_hash: ReceiptChainHash::empty_legacy(),
276 delegate: None,
277 voting_for: VotingFor::dummy(),
278 timing: Timing::Untimed,
279 permissions: PermissionsLegacy::user_default(),
280 snap: None,
281 }
282 }
283}