mina_tree/account/legacy.rs
1use std::borrow::Cow;
2
3use ark_ff::Zero;
4use mina_hasher::{create_legacy, Fp, Hashable, Hasher, ROInput};
5use mina_signer::CompressedPubKey;
6use o1_utils::FieldHelpers;
7
8use crate::scan_state::currency::{Balance, Magnitude, Nonce};
9
10use super::common::*;
11
12#[derive(Clone, Debug, Hash, PartialEq, Eq)]
13pub struct TokenIdLegacy(pub u64);
14
15impl Default for TokenIdLegacy {
16 fn default() -> Self {
17 Self(1)
18 }
19}
20
21#[derive(Clone, Debug)]
22pub struct PermissionsLegacy<Controller> {
23 pub stake: bool,
24 pub edit_state: Controller,
25 pub send: Controller,
26 pub receive: Controller,
27 pub set_delegate: Controller,
28 pub set_permissions: Controller,
29 pub set_verification_key: Controller,
30}
31
32impl PermissionsLegacy<AuthRequired> {
33 pub fn user_default() -> Self {
34 use AuthRequired::*;
35
36 Self {
37 stake: true,
38 edit_state: Signature,
39 send: Signature,
40 receive: None,
41 set_delegate: Signature,
42 set_permissions: Signature,
43 set_verification_key: Signature,
44 }
45 }
46
47 pub fn empty() -> Self {
48 use AuthRequired::*;
49
50 Self {
51 stake: false,
52 edit_state: None,
53 send: None,
54 receive: None,
55 set_delegate: None,
56 set_permissions: None,
57 set_verification_key: None,
58 }
59 }
60}
61
62impl Default for PermissionsLegacy<AuthRequired> {
63 fn default() -> Self {
64 Self::user_default()
65 }
66}
67
68#[derive(Clone, Debug)]
69pub struct SnappAccount {
70 pub app_state: Vec<Fp>,
71 pub verification_key: Option<Fp>,
72}
73
74impl Default for SnappAccount {
75 fn default() -> Self {
76 Self {
77 app_state: vec![Fp::zero(); 8],
78 verification_key: None,
79 }
80 }
81}
82
83impl Hashable for SnappAccount {
84 type D = ();
85
86 fn to_roinput(&self) -> ROInput {
87 let mut roi = ROInput::new();
88
89 if let Some(vk) = self.verification_key.as_ref() {
90 roi = roi.append_field(*vk);
91 } else {
92 roi = roi.append_field(
93 // Value of `dummy_vk_hash`:
94 // <https://github.com/MinaProtocol/mina/blob/4f765c866b81fa6fed66be52707fd91fd915041d/src/lib/mina_base/snapp_account.ml#L116>
95 Fp::from_hex("77a430a03efafd14d72e1a3c45a1fdca8267fcce9a729a1d25128bb5dec69d3f")
96 .unwrap(),
97 );
98 }
99
100 for field in &self.app_state {
101 roi = roi.append_field(*field);
102 }
103
104 // elog!("ROInput={:?}", roi);
105
106 roi
107 }
108
109 fn domain_string(_domain_param: Self::D) -> Option<String> {
110 Some("CodaSnappAccount****".to_string())
111 }
112}
113
114// <https://github.com/MinaProtocol/mina/blob/1765ba6bdfd7c454e5ae836c49979fa076de1bea/src/lib/mina_base/account.ml#L368>
115#[derive(Clone, Debug)]
116pub struct AccountLegacy {
117 pub public_key: CompressedPubKey, // Public_key.Compressed.t
118 pub token_id: TokenIdLegacy, // Token_id.t
119 pub token_permissions: TokenPermissions, // Token_permissions.t
120 pub balance: Balance, // Balance.t
121 pub nonce: Nonce, // Nonce.t
122 pub receipt_chain_hash: ReceiptChainHash, // Receipt.Chain_hash.t
123 pub delegate: Option<CompressedPubKey>, // Public_key.Compressed.t option
124 pub voting_for: VotingFor, // State_hash.t
125 pub timing: Timing, // Timing.t
126 pub permissions: PermissionsLegacy<AuthRequired>, // Permissions.t
127 pub snap: Option<SnappAccount>,
128 // Below fields are for `develop` branch
129 // pub token_symbol: TokenSymbol, // Token_symbol.t
130 // pub zkapp: Option<ZkAppAccount>, // Zkapp_account.t
131 // pub zkapp_uri: String, // string
132}
133
134pub fn get_legacy_hash_of<T: Hashable>(init_value: T::D, item: &T) -> Fp {
135 let mut hasher = create_legacy::<T>(init_value);
136 hasher.update(item);
137 hasher.digest()
138}
139
140impl Hashable for AccountLegacy {
141 type D = ();
142
143 fn to_roinput(&self) -> ROInput {
144 let mut roi = ROInput::new();
145
146 // Self::token_symbol
147
148 // <https://github.com/MinaProtocol/mina/blob/2fac5d806a06af215dbab02f7b154b4f032538b7/src/lib/mina_base/account.ml#L97>
149 // assert!(self.token_symbol.len() <= 6);
150
151 // if !self.token_symbol.is_empty() {
152 // let mut s = <[u8; 6]>::default();
153 // let len = self.token_symbol.len();
154
155 // s[..len].copy_from_slice(&self.token_symbol.as_bytes());
156 // roi.append_bytes(self.token_symbol.as_bytes());
157 // } else {
158 // roi.append_bytes(&[0; 6]);
159 // }
160
161 // Self::snapp
162 let snapp_accout = match self.snap.as_ref() {
163 Some(snapp) => Cow::Borrowed(snapp),
164 None => Cow::Owned(SnappAccount::default()),
165 };
166 let snapp_digest = get_legacy_hash_of((), snapp_accout.as_ref());
167
168 roi = roi.append_field(snapp_digest);
169
170 // elog!("ROINPUT={:?}", roi);
171
172 // Self::permissions
173 for auth in [
174 self.permissions.set_verification_key,
175 self.permissions.set_permissions,
176 self.permissions.set_delegate,
177 self.permissions.receive,
178 self.permissions.send,
179 self.permissions.edit_state,
180 ] {
181 for bit in auth.encode().to_bits() {
182 roi = roi.append_bool(bit);
183 }
184 }
185 roi = roi.append_bool(self.permissions.stake);
186
187 // Self::timing
188 match &self.timing {
189 Timing::Untimed => {
190 roi = roi.append_bool(false);
191 roi = roi.append_u64(0); // initial_minimum_balance
192 roi = roi.append_u32(0); // cliff_time
193 roi = roi.append_u64(0); // cliff_amount
194 roi = roi.append_u32(1); // vesting_period
195 roi = roi.append_u64(0); // vesting_increment
196 }
197 Timing::Timed {
198 initial_minimum_balance,
199 cliff_time,
200 cliff_amount,
201 vesting_period,
202 vesting_increment,
203 } => {
204 roi = roi.append_bool(true);
205 roi = roi.append_u64(initial_minimum_balance.as_u64());
206 roi = roi.append_u32(cliff_time.as_u32());
207 roi = roi.append_u64(cliff_amount.as_u64());
208 roi = roi.append_u32(vesting_period.as_u32());
209 roi = roi.append_u64(vesting_increment.as_u64());
210 }
211 }
212
213 // Self::voting_for
214 roi = roi.append_field(self.voting_for.0);
215
216 // Self::delegate
217 match self.delegate.as_ref() {
218 Some(delegate) => {
219 roi = roi.append_field(delegate.x);
220 roi = roi.append_bool(delegate.is_odd);
221 }
222 None => {
223 // Public_key.Compressed.empty
224 roi = roi.append_field(Fp::zero());
225 roi = roi.append_bool(false);
226 }
227 }
228
229 // Self::receipt_chain_hash
230 roi = roi.append_field(self.receipt_chain_hash.0);
231
232 // Self::nonce
233 roi = roi.append_u32(self.nonce.as_u32());
234
235 // Self::balance
236 roi = roi.append_u64(self.balance.as_u64());
237
238 // Self::token_permissions
239 match self.token_permissions {
240 TokenPermissions::TokenOwned {
241 disable_new_accounts,
242 } => {
243 roi = roi.append_bool(true);
244 roi = roi.append_bool(disable_new_accounts);
245 }
246 TokenPermissions::NotOwned { account_disabled } => {
247 roi = roi.append_bool(false);
248 roi = roi.append_bool(account_disabled);
249 }
250 }
251
252 // Self::token_id
253 roi = roi.append_u64(self.token_id.0);
254
255 // Self::public_key
256 roi = roi.append_field(self.public_key.x);
257 roi = roi.append_bool(self.public_key.is_odd);
258
259 roi
260 }
261
262 // fn to_roinput(&self) -> ROInput {
263 // let mut roi = ROInput::new();
264
265 // // Self::public_key
266 // roi.append_field(self.public_key.x);
267 // roi.append_bool(self.public_key.is_odd);
268
269 // // Self::token_id
270 // roi.append_u64(self.token_id.0);
271
272 // // Self::token_permissions
273 // match self.token_permissions {
274 // TokenPermissions::TokenOwned { disable_new_accounts } => {
275 // roi.append_bool(true);
276 // roi.append_bool(disable_new_accounts);
277 // },
278 // TokenPermissions::NotOwned { account_disabled } => {
279 // roi.append_bool(false);
280 // roi.append_bool(account_disabled);
281 // },
282 // }
283
284 // // Self::balance
285 // roi.append_u64(self.balance);
286
287 // // Self::token_symbol
288
289 // // <https://github.com/MinaProtocol/mina/blob/2fac5d806a06af215dbab02f7b154b4f032538b7/src/lib/mina_base/account.ml#L97>
290 // // assert!(self.token_symbol.len() <= 6);
291
292 // // if !self.token_symbol.is_empty() {
293 // // let mut s = <[u8; 6]>::default();
294 // // let len = self.token_symbol.len();
295
296 // // s[..len].copy_from_slice(&self.token_symbol.as_bytes());
297 // // roi.append_bytes(self.token_symbol.as_bytes());
298 // // } else {
299 // // roi.append_bytes(&[0; 6]);
300 // // }
301
302 // // Self::nonce
303 // roi.append_u32(self.nonce);
304
305 // // Self::receipt_chain_hash
306 // roi.append_field(self.receipt_chain_hash.0);
307
308 // // Self::delegate
309 // match self.delegate.as_ref() {
310 // Some(delegate) => {
311 // roi.append_field(delegate.x);
312 // roi.append_bool(delegate.is_odd);
313 // },
314 // None => {
315 // // Public_key.Compressed.empty
316 // roi.append_field(Fp::zero());
317 // roi.append_bool(false);
318 // },
319 // }
320
321 // // Self::voting_for
322 // roi.append_field(self.voting_for.0);
323
324 // // Self::timing
325 // match self.timing {
326 // Timing::Untimed => {
327 // roi.append_bool(false);
328 // roi.append_u64(0); // initial_minimum_balance
329 // roi.append_u32(0); // cliff_time
330 // roi.append_u64(0); // cliff_amount
331 // roi.append_u32(1); // vesting_period
332 // roi.append_u64(0); // vesting_increment
333 // },
334 // Timing::Timed { initial_minimum_balance, cliff_time, cliff_amount, vesting_period, vesting_increment } => {
335 // roi.append_bool(true);
336 // roi.append_u64(initial_minimum_balance);
337 // roi.append_u32(cliff_time);
338 // roi.append_u64(cliff_amount);
339 // roi.append_u32(vesting_period);
340 // roi.append_u64(vesting_increment);
341 // },
342 // }
343
344 // // Self::permissions
345 // for auth in [
346 // self.permissions.set_verification_key,
347 // self.permissions.set_permissions,
348 // self.permissions.set_delegate,
349 // self.permissions.receive,
350 // self.permissions.send,
351 // self.permissions.edit_state,
352 // ] {
353 // for bit in auth.encode().to_bits() {
354 // roi.append_bool(bit);
355 // }
356 // }
357 // roi.append_bool(self.permissions.stake);
358
359 // // Self::snapp
360 // let snapp_accout = match self.snap.as_ref() {
361 // Some(snapp) => Cow::Borrowed(snapp),
362 // None => Cow::Owned(SnappAccount::default()),
363 // };
364 // let mut hasher = create_legacy::<SnappAccount>(());
365 // hasher.update(snapp_accout.as_ref());
366 // let snapp_digest = hasher.digest();
367
368 // roi.append_field(snapp_digest);
369
370 // elog!("ROINPUT={:?}", roi);
371
372 // roi
373 // }
374
375 fn domain_string(_: ()) -> Option<String> {
376 Some("CodaAccount*********".to_string())
377 }
378}
379
380// mina_hasher::poseidon::
381
382impl AccountLegacy {
383 pub fn create() -> Self {
384 // use o1_utils::field_helpers::FieldHelpers;
385
386 // let token_id = bs58::decode("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf").into_vec().unwrap();
387 // let token_id = Fp::from_bytes(&token_id).unwrap();
388
389 // elog!("token_id={:?}", token_id.to_string());
390
391 // let t = bs58::encode(token_id).into_string();
392 // let t = bs58::encode(token_id.to_bytes()).into_string();
393 // elog!("token_id={:?}", t);
394
395 let pubkey = CompressedPubKey::from_address(
396 "B62qnzbXmRNo9q32n4SNu2mpB8e7FYYLH8NmaX6oFCBYjjQ8SbD7uzV",
397 // "B62qiTKpEPjGTSHZrtM8uXiKgn8So916pLmNJKDhKeyBQL9TDb3nvBG", // Public_key.Compressed.empty
398 )
399 .unwrap();
400
401 Self {
402 public_key: pubkey.clone(),
403 token_id: TokenIdLegacy::default(),
404 token_permissions: TokenPermissions::NotOwned {
405 account_disabled: false,
406 },
407 // token_symbol: "".to_string(),
408 // token_symbol: String::new(),
409 balance: Balance::from_u64(10101),
410 nonce: Nonce::from_u32(62772),
411 receipt_chain_hash: ReceiptChainHash::default(),
412 delegate: Some(pubkey),
413 // delegate: None,
414 voting_for: VotingFor::default(),
415 timing: Timing::Untimed,
416 permissions: PermissionsLegacy::user_default(),
417 snap: None,
418 // zkapp: None,
419 // zkapp_uri: String::new(),
420 }
421 }
422
423 pub fn empty() -> Self {
424 Self {
425 public_key: CompressedPubKey {
426 x: Fp::zero(),
427 is_odd: false,
428 },
429 token_id: TokenIdLegacy::default(),
430 token_permissions: TokenPermissions::default(),
431 balance: Balance::zero(),
432 nonce: Nonce::zero(),
433 receipt_chain_hash: ReceiptChainHash::empty_legacy(),
434 delegate: None,
435 voting_for: VotingFor::dummy(),
436 timing: Timing::Untimed,
437 permissions: PermissionsLegacy::user_default(),
438 snap: None,
439 }
440 }
441}