diff --git a/Cargo.lock b/Cargo.lock index 1629fc80d..3f77bb0d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2068,12 +2068,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "cty" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" - [[package]] name = "curve25519-dalek" version = "4.1.2" @@ -5231,7 +5225,6 @@ dependencies = [ "mina-signer", "num-bigint", "o1-utils", - "ocaml-interop", "once_cell", "openmina-core", "openmina-macros", @@ -5874,34 +5867,6 @@ dependencies = [ "ruzstd", ] -[[package]] -name = "ocaml-boxroot-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5186393bfbee4ce2bc5bbb82beafb77e85c1d0a557e3cfc8c8a0d63d7845fed5" -dependencies = [ - "cc", -] - -[[package]] -name = "ocaml-interop" -version = "0.8.8" -source = "git+https://github.com/sebastiencs/ocaml-interop.git?branch=closure-values#f9ecf016e725589a402f3d61e120d96b8284d506" -dependencies = [ - "ocaml-boxroot-sys", - "ocaml-sys", - "static_assertions", -] - -[[package]] -name = "ocaml-sys" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73ec6ca7d41458442627435afb8f4671e83fd642e8a560171d671a1f679aa3cf" -dependencies = [ - "cty", -] - [[package]] name = "oid-registry" version = "0.6.1" diff --git a/ledger/Cargo.toml b/ledger/Cargo.toml index 7401eed92..86e12338a 100644 --- a/ledger/Cargo.toml +++ b/ledger/Cargo.toml @@ -83,9 +83,7 @@ wasm-bindgen-futures = "0.4" [target.'cfg(not(target_family = "wasm"))'.dependencies] zstd = { version = "0.12", optional = true } -# ocaml-interop = { path = "/home/sebastien/github/ocaml-interop", optional = true } -ocaml-interop = { git = "https://github.com/sebastiencs/ocaml-interop.git", branch = "closure-values", optional = true } -# ocaml-interop = { git = "https://github.com/tizoc/ocaml-interop.git", branch = "closure-values", optional = true } + reqwest = { version = "0.11.24", features = ["blocking"] } [dev-dependencies] diff --git a/ledger/src/ffi/block.rs b/ledger/src/ffi/block.rs deleted file mode 100644 index 3a370cfff..000000000 --- a/ledger/src/ffi/block.rs +++ /dev/null @@ -1,112 +0,0 @@ -use ocaml_interop::*; - -use crate::ffi::util::*; -use crate::{MessagesForNextStepProof, MessagesForNextWrapProof}; - -ocaml_export! { - fn rust_hash_message_for_next_step_proof( - rt, - bytes: OCamlRef, - ocaml_hash: OCamlRef>, - ) { - let mut ocaml_hash_ref = rt.get(ocaml_hash); - - let mut ocaml_hash = Vec::with_capacity(2048); - while let Some((head, tail)) = ocaml_hash_ref.uncons() { - let limb: String = head.to_rust(); - let limb: i64 = limb.parse().unwrap(); - ocaml_hash.push(limb as u64); - ocaml_hash_ref = tail; - } - - elog!("RESULT_OCAML={:?}", ocaml_hash); - - let bytes = rt.get(bytes); - - let msg: MessagesForNextStepProof = deserialize(bytes.as_bytes()); - let rust_hash = msg.hash(); - - elog!("RESULT_RUST_={:?}", rust_hash); - - assert_eq!(&rust_hash[..], ocaml_hash); - - OCaml::unit() - } - - fn rust_get_random_message( - rt, - _validate_msg: OCamlRef ()>, - ) -> OCaml { - let msg = MessagesForNextStepProof::rand(); - let bytes = serialize(&msg); - - // let s = bytes.iter().map(|b| format!("{:02X}", b)).collect::>().join(""); - // elog!("BYTES={:?}", s); - - bytes.to_ocaml(rt) - } - - fn rust_get_random_wrap_message( - rt, - _validate_msg: OCamlRef ()>, - ) -> OCaml { - let msg = MessagesForNextWrapProof::rand(); - let bytes = serialize(&msg); - - // let s = bytes.iter().map(|b| format!("{:02X}", b)).collect::>().join(""); - // elog!("BYTES={:?}", s); - - bytes.to_ocaml(rt) - } - - fn rust_hash_message_for_next_wrap_proof( - rt, - bytes: OCamlRef, - ocaml_hash: OCamlRef>, - ) { - let mut ocaml_hash_ref = rt.get(ocaml_hash); - - let mut ocaml_hash = Vec::with_capacity(2048); - while let Some((head, tail)) = ocaml_hash_ref.uncons() { - let limb: String = head.to_rust(); - let limb: i64 = limb.parse().unwrap(); - ocaml_hash.push(limb as u64); - ocaml_hash_ref = tail; - } - - elog!("RESULT_OCAML={:?}", ocaml_hash); - - let bytes = rt.get(bytes); - - let msg: MessagesForNextWrapProof = deserialize(bytes.as_bytes()); - let rust_hash = msg.hash(); - - elog!("RESULT_RUST_={:?}", rust_hash); - - assert_eq!(&rust_hash[..], ocaml_hash); - - OCaml::unit() - } - - // fn rust_get_random_message( - // rt, - // validate_msg: OCamlRef ()>, - // ) -> OCaml { - // let mut msg; - // let mut bytes; - // let validate_msg = validate_msg.to_boxroot(rt); - - // loop { - // msg = MessagesForNextStepProof::rand(); - // bytes = serialize(&msg); - - // elog!("LOOP"); - - // if validate_msg.try_call(rt, &bytes).is_ok() { - // break; - // } - // } - - // bytes.to_ocaml(rt) - // } -} diff --git a/ledger/src/ffi/database.rs b/ledger/src/ffi/database.rs deleted file mode 100644 index d2b280d5d..000000000 --- a/ledger/src/ffi/database.rs +++ /dev/null @@ -1,1252 +0,0 @@ -use std::{ - borrow::Borrow, - cell::{Ref, RefCell}, - collections::HashMap, - path::PathBuf, - rc::Rc, - str::FromStr, - sync::Mutex, -}; - -use ark_ff::BigInteger256; -use binprot::BinProtWrite; -use mina_hasher::Fp; -use mina_p2p_messages::{ - bigint::BigInt, - binprot, - v2::{MinaBaseAccountUpdateTStableV1, NonZeroCurvePointUncompressedStableV1}, -}; -use ocaml_interop::{ - impl_to_ocaml_polymorphic_variant, impl_to_ocaml_variant, ocaml_export, DynBox, OCaml, - OCamlBytes, OCamlInt, OCamlList, OCamlRef, OCamlRuntime, RawOCaml, ToOCaml, -}; -use once_cell::sync::Lazy; - -use crate::{ - account::{Account, AccountId}, - address::Address, - base::{AccountIndex, BaseLedger, MerklePath}, - database::Database, - ffi::util::*, - scan_state::transaction_logic::zkapp_command::AccountUpdate, - short_backtrace, - tree_version::V2, - TokenId, -}; - -static DATABASE: Lazy>> = Lazy::new(|| Mutex::new(Database::create(30))); - -// #[derive(Clone)] -pub struct DatabaseFFI(pub Rc>>>); - -impl Drop for DatabaseFFI { - fn drop(&mut self) { - let mask_id = RefCell::borrow(&self.0) - .as_ref() - .map(|mask| mask.get_uuid()); - elog!("rust_database_drop {:?}", mask_id); - } -} - -fn with_db(rt: &mut &mut OCamlRuntime, db: OCamlRef>, fun: F) -> R -where - F: FnOnce(&mut Database) -> R, -{ - let db = rt.get(db); - let db: &DatabaseFFI = db.borrow(); - let mut db = db.0.borrow_mut(); - - fun(db.as_mut().unwrap()) -} - -struct MyOCamlClosure(*const RawOCaml); - -// external database_get_or_create_account : database -> account_id -> account -> (([ `Added | `Existed ] * addr), rust_dberror) result = "rust_database_get_or_create_account" - -pub enum PolymorphicGetOrAdded { - Added, - Existed, -} - -impl_to_ocaml_polymorphic_variant! { - PolymorphicGetOrAdded { - PolymorphicGetOrAdded::Added, - PolymorphicGetOrAdded::Existed, - } -} - -pub enum PolymorphicPath { - Left(Vec), - Right(Vec), -} - -impl_to_ocaml_polymorphic_variant! { - PolymorphicPath { - PolymorphicPath::Left(hash: OCamlBytes), - PolymorphicPath::Right(hash: OCamlBytes), - } -} - -#[derive(Debug, PartialEq, Eq)] -pub enum DatabaseErrorFFI { - OutOfLeaves, -} - -impl_to_ocaml_variant! { - DatabaseErrorFFI { - DatabaseErrorFFI::OutOfLeaves, - } -} - -static DB_CLOSED: Lazy>>> = - Lazy::new(|| Mutex::new(HashMap::with_capacity(16))); - -// static DB_CLOSED: Arc>>>> = Arc::new(Mutex::new(None)); - -fn get_cloned_db( - rt: &mut &mut OCamlRuntime, - db: OCamlRef>, -) -> Rc>>> { - let db = rt.get(db); - let db: &DatabaseFFI = db.borrow(); - // let mut db = db.0.borrow_mut(); - Rc::clone(&db.0) -} - -ocaml_export! { - fn rust_database_create( - rt, - depth: OCamlRef, - dir_name: OCamlRef> - ) -> OCaml> { - elog!("backtrace=\n{}", short_backtrace()); - - let depth: i64 = depth.to_rust(rt); - let depth: u8 = depth.try_into().unwrap(); - - let dir_name = rt.get(dir_name); - let dir_name = dir_name.to_rust::>().map(PathBuf::from); - - let mut closed = DB_CLOSED.try_lock().unwrap(); - - let db = dir_name.as_ref().and_then(|dir_name| closed.remove(dir_name)); - - elog!("rust_database_create={:?} reuse={:?}", dir_name, db.is_some()); - - let db = match db { - Some(db) => { - assert_eq!(db.depth(), depth); - db - }, - None => { - Database::::create_with_dir(depth, dir_name) - } - }; - - let db = DatabaseFFI(Rc::new(RefCell::new(Some(db)))); - - OCaml::box_value(rt, db) - } - - fn rust_database_get_uuid( - rt, - db: OCamlRef> - ) -> OCaml { - let uuid = with_db(rt, db, |db| { - db.get_uuid() - }); - - uuid.to_ocaml(rt) - } - - fn rust_database_get_directory( - rt, - db: OCamlRef> - ) -> OCaml> { - let dir = with_db(rt, db, |db| { - db.get_directory().map(|d| d.into_os_string().into_string().unwrap()) - }); - - dir.to_ocaml(rt) - } - - fn rust_database_depth( - rt, - db: OCamlRef> - ) -> OCaml { - let depth = with_db(rt, db, |db| { - db.depth() as i64 - }); - - depth.to_ocaml(rt) - } - - fn rust_database_create_checkpoint( - rt, - db: OCamlRef>, - directory_name: OCamlRef, - ) -> OCaml> { - let db = { - let db = rt.get(db); - let db: &DatabaseFFI = db.borrow(); - - let directory_name: String = directory_name.to_rust(rt); - - { - let mut db = db.0.borrow_mut(); - let db = db.as_mut().unwrap(); - db.create_checkpoint(directory_name.clone()); - } - - let directory_name = PathBuf::from(directory_name); - - let db: Ref>> = (*db.0).borrow(); - let db_clone = db.as_ref().unwrap().clone_db(directory_name); - - DatabaseFFI(Rc::new(RefCell::new(Some(db_clone)))) - }; - - OCaml::box_value(rt, db) - } - - fn rust_database_make_checkpoint( - rt, - db: OCamlRef>, - directory_name: OCamlRef, - ) { - let db = rt.get(db); - let db: &DatabaseFFI = db.borrow(); - - let directory_name: String = directory_name.to_rust(rt); - - { - let mut db = db.0.borrow_mut(); - let db = db.as_mut().unwrap(); - db.make_checkpoint(directory_name.clone()); - } - - let directory_name = PathBuf::from(directory_name); - - let db: Ref>> = (*db.0).borrow(); - let db_clone = db.as_ref().unwrap().clone_db(directory_name.clone()); - - let mut closed_dbs = DB_CLOSED.try_lock().unwrap(); - closed_dbs.insert(directory_name, db_clone); - - OCaml::unit() - } - - fn rust_database_close( - rt, - db: OCamlRef> - ) { - let db = rt.get(db); - let db: &DatabaseFFI = db.borrow(); - - let path = { - let mut db_ref = db.0.borrow_mut(); - let db_ref = db_ref.as_mut().unwrap(); - db_ref.close(); - db_ref.get_directory().unwrap() - }; - - elog!("rust_database_close={:?}", path); - - let db = db.0.take().unwrap(); - // let db: RefCell> = Rc::try_unwrap(db).ok().unwrap(); - // let db = db.into_inner(); - - let mut closed_dbs = DB_CLOSED.try_lock().unwrap(); - closed_dbs.insert(path, db); - - // with_db(rt, db, |db| { - // }); - - OCaml::unit() - } - - fn rust_add_account( - rt, - account: OCamlRef, - ) { - elog!("RUST BEGIN"); - let account_ref = rt.get(account); - let account = account_ref.as_bytes(); - - let account: Account = Account::deserialize(account); - - elog!("account={:?}", account); - elog!("account_hash={:?}", account.hash().to_string()); - - elog!("RUST END 1"); - OCaml::unit() - } - - fn rust_get_random_account_id( - rt, - _unused: OCamlRef ()>, - ) -> OCaml { - let account_id = AccountId::rand(); - let bytes = serialize(&account_id); - - bytes.to_ocaml(rt) - } - - fn rust_get_random_account( - rt, - validate_account: OCamlRef ()>, - ) -> OCaml { - let mut account; - let mut bytes; - let validate_account = validate_account.to_boxroot(rt); - - loop { - account = Account::rand(); - bytes = account.serialize(); - - if validate_account.try_call(rt, &bytes).is_ok() { - break; - } - } - - elog!("account={:?}", account.id()); - // thread::sleep_ms(2000); - - bytes.to_ocaml(rt) - } - - fn rust_test_random_accounts( - rt, - get_hash_fun: OCamlRef OCamlBytes>, - ) { - let get_hash_fun = get_hash_fun.to_boxroot(rt); - let mut nchecked = 0; - - for _ in 0..10_000 { - let account = Account::rand(); - let rust_hash = account.hash(); - - let bytes = account.serialize(); - let ocaml_hash: OCaml = match get_hash_fun.try_call(rt, &bytes) { - Ok(hash) => hash, - Err(_) => continue, // random account is invalid - }; - - let ocaml_hash: Vec = ocaml_hash.to_rust(); - let ocaml_hash: BigInt = deserialize(&ocaml_hash); - let ocaml_hash: Fp = ocaml_hash.into(); - - if ocaml_hash != rust_hash { - elog!("different hash ! bytes={:?}", account); - elog!("ocaml_hash={}", ocaml_hash); - elog!("rust_hash ={}", rust_hash); - panic!("account={:#?}", account); - } - - nchecked += 1; - } - - elog!("nchecked={:?}", nchecked); - - OCaml::unit() - } - - fn rust_test_random_account_ids( - rt, - fun: OCamlRef OCamlInt>, - ) { - let fun = fun.to_boxroot(rt); - let mut nchecked = 0; - - let now = redux::Instant::now(); - - for _ in 0..20_000 { - let account_id = AccountId::rand(); - let bytes = serialize(&account_id); - - let ocaml_hash: OCaml = fun.try_call(rt, &bytes).unwrap(); - let ocaml_hash: i64 = ocaml_hash.to_rust(); - let ocaml_hash: u32 = ocaml_hash.try_into().unwrap(); - - let rust_hash = account_id.ocaml_hash(); - - if ocaml_hash != rust_hash { - elog!("different hash ! id={:?}", account_id); - elog!("ocaml_hash={}", ocaml_hash); - elog!("rust_hash ={}", rust_hash); - panic!("bytes={:#?}", bytes); - } - - nchecked += 1; - } - - eprintln!("nchecked={:?} in {:?}", nchecked, now.elapsed()); - - OCaml::unit() - } - - fn rust_test_random_account_id_order( - rt, - fun: OCamlRef) -> OCamlList>, - ) { - let fun = fun.to_boxroot(rt); - - let mut compare_with_ocaml = |ids: Vec| { - let serialized: Vec> = ids.iter().map(AccountId::serialize).collect(); - - let ocaml_list: OCaml> = fun.try_call(rt, &serialized).unwrap(); - let ocaml_list: Vec> = ocaml_list.to_rust(); - let ocaml_list: Vec = ocaml_list.iter().map(|b| deserialize(b)).collect(); - - let mut table = crate::port_ocaml::HashTable::create(); - for id in ids { - table.update(id, |_| Some(1)); - } - let ids: Vec<_> = table.to_alist().into_iter().map(|(id, _)| id).collect(); - - if ids != ocaml_list { - eprintln!("different order ! nids={}", 2); - eprintln!("rust={:#?}", ids); - eprintln!("ocaml={:#?}", ocaml_list); - panic!(); - } - }; - - let ids: Vec = (0..100).map(|_| AccountId::rand()).collect(); - let ids: Vec = ids.into_iter().enumerate().map(|(index, mut id)| { - // Reach corner cases in `port_ocaml::hash::hash_field` - let token_id = match index % 5 { - 0 => BigInteger256([0, 0, 0, 1]), - 1 => BigInteger256([0, 0, 1, 0]), - 2 => BigInteger256([0, 1, 0, 0]), - 3 => BigInteger256([1, 0, 0, 0]), - _ => BigInteger256([0, 0, 0, 0]), - }; - id.token_id = TokenId(token_id.into()); - id - }).collect(); - - compare_with_ocaml(ids); - - for nids in 1..100 { - let ids: Vec = (0..nids).map(|_| AccountId::rand()).collect(); - compare_with_ocaml(ids); - } - - OCaml::unit() - } - - fn rust_test_random_account_updates( - rt, - get_hash_fun: OCamlRef OCamlBytes>, - ) { - let get_hash_fun = get_hash_fun.to_boxroot(rt); - let mut nchecked = 0; - - for _ in 0..10_000 { - let account = AccountUpdate::rand(); - let rust_hash = account.digest(); - - let bytes = { - let account: MinaBaseAccountUpdateTStableV1 = (&account).into(); - let mut bytes = Vec::with_capacity(10000); - account.binprot_write(&mut bytes).unwrap(); - bytes - }; - - { - let mut cursor = std::io::Cursor::new(&bytes); - let acc = ::binprot_read(&mut cursor).unwrap(); - let acc: AccountUpdate = (&acc).into(); - - assert_eq!(account, acc); - } - - let ocaml_hash: OCaml = match get_hash_fun.try_call(rt, &bytes) { - Ok(hash) => hash, - Err(_) => continue, // random account is invalid - }; - - let ocaml_hash: Vec = ocaml_hash.to_rust(); - let ocaml_hash: BigInt = deserialize(&ocaml_hash); - let ocaml_hash: Fp = ocaml_hash.into(); - - if ocaml_hash != rust_hash { - eprintln!("ocaml_hash={}", ocaml_hash); - eprintln!("rust_hash ={}", rust_hash); - eprintln!("bytes={:?}", bytes); - panic!("account={:#?}", account); - } - - nchecked += 1; - } - - eprintln!("nchecked={}", nchecked); - - OCaml::unit() - } - - fn rust_add_account_with_hash( - rt, - account: OCamlRef, - hash: OCamlRef, - ) { - // elog!("RUST BEGIN"); - let account_ref = rt.get(account); - let account = account_ref.as_bytes(); - let account_bytes = account; - let _account_len = account.len(); - let hash: String = hash.to_rust(rt); - let hash = Fp::from_str(&hash).unwrap(); - - let account: Account = Account::deserialize(account); - let account_hash = account.hash(); - - if hash != account_hash { - elog!("different hash ! bytes={:?}", account_bytes); - elog!("ocaml_hash={:?}", hash.to_string()); - elog!("rust_hash ={:?}", account_hash.to_string()); - assert_eq!(hash, account_hash); - } - - // elog!("hash={:?}", hash.to_string()); - // elog!("provided={:?}", hash.to_string()); - // elog!("computed={:?}", account_hash.to_string()); - - let ser = account.serialize(); - - // elog!("from_ocaml={:?}", account_bytes); - // elog!("rust_ocaml={:?}", ser); - - // assert_eq!(account_len, ser.len()); - - let account2: Account = Account::deserialize(&ser); - let account_hash2 = account2.hash(); - assert_eq!(account_hash, account_hash2); - - // elog!("account={:?}", account); - // elog!("account_hash={:?}", account.hash().to_string()); - - let mut db = DATABASE.try_lock().unwrap(); - let id = account.id(); - db.get_or_create_account(id, account).unwrap(); - - // elog!("RUST END"); - OCaml::unit() - } - - fn rust_root_hash(rt, ocaml_hash: OCamlRef) { - let mut db = DATABASE.try_lock().unwrap(); - let hash = db.root_hash(); - - let ocaml_hash: String = ocaml_hash.to_rust(rt); - let ocaml_hash = Fp::from_str(&ocaml_hash).unwrap(); - - elog!("naccounts ={:?}", db.naccounts()); - elog!("rust_root_hash ={:?}", hash.to_string()); - elog!("ocaml_root_hash={:?}", ocaml_hash.to_string()); - - assert_eq!(hash, ocaml_hash); - - OCaml::unit() - } - - fn rust_random_account(rt, _unused: OCamlRef) -> OCaml { - let res = impl_rust_random_account(); - // elog!("rust_random_account begin"); - - // // let account = Account::rand(); - // // let ser = serde_binprot::to_vec(&account).unwrap(); - - // let ser: Vec = vec![178, 29, 73, 50, 85, 80, 131, 166, 53, 11, 48, 224, 103, 89, 161, 207, 149, 31, 170, 21, 165, 181, 94, 18, 149, 177, 54, 71, 185, 77, 109, 49, 1, 144, 247, 164, 171, 110, 24, 3, 12, 25, 163, 63, 125, 83, 66, 174, 2, 160, 62, 45, 137, 185, 47, 16, 129, 145, 190, 203, 124, 35, 119, 251, 26, 1, 1, 6, 49, 50, 56, 54, 56, 56, 252, 29, 154, 218, 214, 79, 98, 177, 181, 253, 181, 152, 127, 0, 145, 177, 91, 155, 59, 239, 161, 174, 217, 42, 201, 30, 46, 11, 187, 88, 49, 5, 111, 254, 222, 87, 42, 45, 90, 1, 236, 173, 205, 215, 241, 20, 0, 77, 12, 197, 234, 69, 202, 22, 55, 50, 183, 255, 238, 8, 29, 79, 199, 92, 12, 146, 223, 105, 45, 135, 77, 89, 73, 141, 11, 137, 28, 54, 21, 0, 1, 4, 4, 1, 0, 4, 3, 4, 3, 2, 3, 0, 6, 49, 49, 56, 54, 54, 51]; - - // let mut account2: Account = serde_binprot::from_slice(&ser).unwrap(); - - // let account_hash2 = account2.hash(); - - // elog!("HASH2={:?}", account_hash2.to_string()); - - // let ser = serde_binprot::to_vec(&account2).unwrap(); - - - // elog!("rust_random_account end"); - - res.to_ocaml(rt) - } - - fn rust_database_get( - rt, - db: OCamlRef>, - addr: OCamlRef, - ) -> OCaml> { - let addr = get_addr(rt, addr); - - let account = with_db(rt, db, |db| { - db.get(addr) - }).map(|account| { - account.serialize() - }); - - account.to_ocaml(rt) - } - - fn rust_database_get_batch( - rt, - db: OCamlRef>, - addrs: OCamlRef>, - ) -> OCaml)>> { - let mut addrs_ref = rt.get(addrs); - - let mut addrs = Vec::with_capacity(2048); - while let Some((head, tail)) = addrs_ref.uncons() { - let addr = Address::try_from(head.as_str()).unwrap(); - addrs.push(addr); - addrs_ref = tail; - } - - let accounts: Vec<(String, Option>)> = with_db(rt, db, |db| { - db.get_batch(&addrs) - }).into_iter() - .map(|(addr, opt_account)| { - let addr = addr.to_string(); - let opt_account = opt_account.map(|acc| acc.serialize()); - (addr, opt_account) - }) - .collect(); - - accounts.to_ocaml(rt) - } - - fn rust_database_get_list( - rt, - db: OCamlRef>, - ) -> OCaml> { - - let accounts: Vec> = with_db(rt, db, |db| { - db.to_list() - }).into_iter() - .map(|account| { - account.serialize() - }) - .collect(); - - accounts.to_ocaml(rt) - } - - fn rust_database_accounts( - rt, - db: OCamlRef>, - ) -> OCaml> { - - let accounts: Vec> = with_db(rt, db, |db| { - db.accounts() - }).into_iter() - .map(|account_id| { - serialize(&account_id) - }) - .collect(); - - accounts.to_ocaml(rt) - } - - fn rust_database_get_inner_hash_at_addr( - rt, - db: OCamlRef>, - addr: OCamlRef, - ) -> OCaml { - let addr = get_addr(rt, addr); - - let hash = with_db(rt, db, |db| { - db.get_inner_hash_at_addr(addr) - }).map(|hash| { - hash_to_ocaml(hash) - }) - .unwrap(); - - hash.to_ocaml(rt) - } - - fn rust_database_set_inner_hash_at_addr( - rt, - db: OCamlRef>, - addr: OCamlRef, - hash: OCamlRef, - ) { - let addr = get_addr(rt, addr); - - let hash: String = hash.to_rust(rt); - let hash = Fp::from_str(&hash).unwrap(); - - with_db(rt, db, |db| { - db.set_inner_hash_at_addr(addr, hash).unwrap() - }); - - OCaml::unit() - } - - fn rust_database_get_at_index( - rt, - db: OCamlRef>, - index: OCamlRef - ) -> OCaml { - let index = get_index(rt, index); - - let account = with_db(rt, db, |db| { - db.get_at_index(index).unwrap() - }); - let account = account.serialize(); - - account.to_ocaml(rt) - } - - fn rust_database_location_of_account( - rt, - db: OCamlRef>, - account_id: OCamlRef - ) -> OCaml> { - let account_id = get(rt, account_id); - - // eprintln!("database_location_of_account={:?}", account_id); - - let addr = with_db(rt, db, |db| { - db.location_of_account(&account_id) - }).map(|addr| { - addr.to_string() - }); - - addr.to_ocaml(rt) - } - - fn rust_database_location_of_account_batch( - rt, - db: OCamlRef>, - account_ids: OCamlRef> - ) -> OCaml)>> { - let account_ids = get_list_of::(rt, account_ids); - - // eprintln!("database_location_of_account_batch={:?}", account_ids); - - let addrs = with_db(rt, db, |db| { - db.location_of_account_batch(&account_ids) - }).into_iter() - .map(|(account_id, opt_addr)| { - let account_id = serialize(&account_id); - let addr = opt_addr.map(|addr| addr.to_string()); - (account_id, addr) - }) - .collect::>(); - - addrs.to_ocaml(rt) - } - - fn rust_database_last_filled( - rt, - db: OCamlRef>, - ) -> OCaml> { - let addr = with_db(rt, db, |db| { - db.last_filled() - }).map(|addr| { - addr.to_string() - }); - - addr.to_ocaml(rt) - } - - fn rust_database_token_owners( - rt, - db: OCamlRef>, - ) -> OCaml> { - let owners = with_db(rt, db, |db| { - db.token_owners() - }).iter() - .map(|account_id| { - serialize(account_id) - }) - .collect::>(); - - owners.to_ocaml(rt) - } - - fn rust_database_token_owner( - rt, - db: OCamlRef>, - token_id: OCamlRef, - ) -> OCaml> { - let token_id = get(rt, token_id); - - let owner = with_db(rt, db, |db| { - db.token_owner(token_id) - }).map(|account_id| { - serialize(&account_id) - }); - - owner.to_ocaml(rt) - } - - fn rust_database_tokens( - rt, - db: OCamlRef>, - pubkey: OCamlRef, - ) -> OCaml> { - let pubkey: NonZeroCurvePointUncompressedStableV1 = get(rt, pubkey); - - let tokens = with_db(rt, db, |db| { - db.tokens(pubkey.into()) - }).iter() - .map(|token_id| { - serialize(token_id) - }) - .collect::>(); - - tokens.to_ocaml(rt) - } - - fn rust_database_set( - rt, - db: OCamlRef>, - addr: OCamlRef, - account: OCamlRef, - ) { - let addr = get_addr(rt, addr); - let account = get(rt, account); - - with_db(rt, db, |db| { - db.set(addr, account) - }); - - OCaml::unit() - } - - fn rust_database_index_of_account( - rt, - db: OCamlRef>, - account_id: OCamlRef - ) -> OCaml { - let account_id = get(rt, account_id); - - // eprintln!("database_index_of_account={:?}", account_id); - - let index = with_db(rt, db, |db| { - db.index_of_account(account_id) - }).map(|index| { - index.0 as i64 - }) - .unwrap(); - - index.to_ocaml(rt) - } - - fn rust_database_set_at_index( - rt, - db: OCamlRef>, - index: OCamlRef, - account: OCamlRef, - ) { - let index = get_index(rt, index); - let account = get(rt, account); - - with_db(rt, db, |db| { - db.set_at_index(index, account) - }).unwrap(); - - OCaml::unit() - } - - fn rust_database_get_or_create_account( - rt, - db: OCamlRef>, - account_id: OCamlRef, - account: OCamlRef, - ) -> OCaml> { - let account_id = get(rt, account_id); - let account = get(rt, account); - - // eprintln!("database_get_or_create_account={:?}", account_id); - - let result = with_db(rt, db, |db| { - db.get_or_create_account(account_id, account) - }); - - use crate::base::GetOrCreated::*; - use crate::database::DatabaseError::*; - - let result = match result { - Ok(value) => { - let get_or_added = match value { - Added(_) => PolymorphicGetOrAdded::Added, - Existed(_) => PolymorphicGetOrAdded::Existed, - }; - let addr = value.addr(); - Ok((get_or_added, addr.to_string())) - }, - Err(e) => match e { - OutOfLeaves => Err(DatabaseErrorFFI::OutOfLeaves), - }, - }; - - result.to_ocaml(rt) - } - - fn rust_database_num_accounts( - rt, - db: OCamlRef> - ) -> OCaml { - let num_accounts = with_db(rt, db, |db| { - db.num_accounts() as i64 - }); - - num_accounts.to_ocaml(rt) - } - - fn rust_database_iter( - rt, - db: OCamlRef>, - ocaml_method: OCamlRef, - ) { - let (num_accounts, depth) = with_db(rt, db, |db| { - (db.num_accounts(), db.depth()) - }); - - let ocaml_method = ocaml_method.to_boxroot(rt); - - for index in 0..num_accounts { - let index = AccountIndex(index as u64); - let addr = Address::from_index(index, depth as usize); - - let account = with_db(rt, db, |db| { - db.get(addr) - }); - - let account = match account { - Some(account) => account, - None => continue, - }; - - let account = account.serialize(); - - let _: Result, _> = ocaml_method.try_call(rt, &account); - } - - OCaml::unit() - } - - fn rust_database_foldi( - rt, - db: OCamlRef>, - ocaml_method: OCamlRef, - ) { - let (num_accounts, depth) = with_db(rt, db, |db| { - (db.num_accounts(), db.depth()) - }); - - let ocaml_method = ocaml_method.to_boxroot(rt); - - for index in 0..num_accounts { - let index = AccountIndex(index as u64); - let addr = Address::from_index(index, depth as usize); - - let account = with_db(rt, db, |db| { - db.get(addr.clone()) - }); - - let account = match account { - Some(account) => account, - None => continue, - }; - - let account = serialize(&account); - let addr = addr.to_string(); - - let _: Result, _> = ocaml_method.try_call(rt, &addr, &account); - } - - OCaml::unit() - } - - fn rust_database_foldi_with_ignored_accounts( - rt, - db: OCamlRef>, - ignored_accounts: OCamlRef>, - ocaml_method: OCamlRef, - ) { - let (num_accounts, depth) = with_db(rt, db, |db| { - (db.num_accounts(), db.depth()) - }); - - let ignored_accounts = get_set_of::(rt, ignored_accounts); - let ocaml_method = ocaml_method.to_boxroot(rt); - - for index in 0..num_accounts { - let index = AccountIndex(index as u64); - let addr = Address::from_index(index, depth as usize); - - let account = with_db(rt, db, |db| { - db.get(addr.clone()) - }); - - let account = match account { - Some(account) => account, - None => continue, - }; - - if ignored_accounts.contains(&account.id()) { - continue; - } - - let account = serialize(&account); - let addr = addr.to_string(); - - let _: Result, _> = ocaml_method.try_call(rt, &addr, &account); - } - - OCaml::unit() - } - - fn rust_database_merkle_root( - rt, - db: OCamlRef>, - ) -> OCaml { - let hash = with_db(rt, db, |db| { - db.merkle_root() - }); - - let hash = hash_to_ocaml(hash); - - hash.to_ocaml(rt) - } - - fn rust_database_remove_accounts( - rt, - db: OCamlRef>, - account_ids: OCamlRef>, - ) { - let account_ids = get_list_of(rt, account_ids); - - // eprintln!("database_remove_account={:?}", account_ids); - - with_db(rt, db, |db| { - db.remove_accounts(&account_ids) - }); - - OCaml::unit() - } - - fn rust_database_set_all_accounts_rooted_at( - rt, - db: OCamlRef>, - addr: OCamlRef, - accounts: OCamlRef>, - ) { - let addr = get_addr(rt, addr); - let accounts = get_list_of(rt, accounts); - - with_db(rt, db, |db| { - db.set_all_accounts_rooted_at(addr, &accounts).unwrap() - }); - - OCaml::unit() - } - - fn rust_database_set_batch_accounts( - rt, - db: OCamlRef>, - accounts: OCamlRef>, - ) { - let accounts = get_list_addr_account(rt, accounts); - - with_db(rt, db, |db| { - db.set_batch_accounts(&accounts) - }); - - OCaml::unit() - } - - fn rust_database_get_all_accounts_rooted_at( - rt, - db: OCamlRef>, - addr: OCamlRef, - ) -> OCaml> { - let addr = get_addr(rt, addr); - - let accounts = with_db(rt, db, |db| { - db.get_all_accounts_rooted_at(addr) - }).unwrap_or_default() - .iter() - .map(|(addr, account)| { - let addr = addr.to_string(); - let account = serialize(account); - (addr, account) - }) - .collect::>(); - - accounts.to_ocaml(rt) - } - - fn rust_database_merkle_path( - rt, - db: OCamlRef>, - addr: OCamlRef, - ) -> OCaml> { - let addr = get_addr(rt, addr); - - let path = with_db(rt, db, |db| { - db.merkle_path(addr) - }).into_iter() - .map(|path| { - match path { - MerklePath::Left(hash) => PolymorphicPath::Left(hash_to_ocaml(hash)), - MerklePath::Right(hash) => PolymorphicPath::Right(hash_to_ocaml(hash)), - } - }) - .collect::>(); - - path.to_ocaml(rt) - } - - fn rust_database_merkle_path_at_addr( - rt, - db: OCamlRef>, - addr: OCamlRef, - ) -> OCaml> { - let addr = get_addr(rt, addr); - - let path = with_db(rt, db, |db| { - db.merkle_path(addr) - }).into_iter() - .map(|path| { - match path { - MerklePath::Left(hash) => PolymorphicPath::Left(hash_to_ocaml(hash)), - MerklePath::Right(hash) => PolymorphicPath::Right(hash_to_ocaml(hash)), - } - }) - .collect::>(); - - path.to_ocaml(rt) - } - - fn rust_database_merkle_path_at_index( - rt, - db: OCamlRef>, - index: OCamlRef, - ) -> OCaml> { - let index = get_index(rt, index); - - let path = with_db(rt, db, |db| { - let depth = db.depth(); - let addr = Address::from_index(index, depth as usize); - db.merkle_path(addr) - }).into_iter() - .map(|path| { - match path { - MerklePath::Left(hash) => PolymorphicPath::Left(hash_to_ocaml(hash)), - MerklePath::Right(hash) => PolymorphicPath::Right(hash_to_ocaml(hash)), - // MerklePath::Left(hash) => PolymorphicPath::Left(hash.to_string()), - // MerklePath::Right(hash) => PolymorphicPath::Right(hash.to_string()), - } - }) - .collect::>(); - - path.to_ocaml(rt) - } -} - -// database_create : int -> database = "rust_database_create" -// database_get_uuid : database -> string = "rust_database_get_uuid" -// database_depth : database -> int = "rust_database_depth" -// database_create_checkpoint : database -> database = "rust_database_create_checkpoint" -// database_make_checkpoint : database -> unit = "rust_database_make_checkpoint" -// database_close : database -> unit = "rust_database_close" -// database_get : database -> addr -> account option = "rust_database_get" -// database_get_batch : database -> addr list -> (addr * (account option)) list = "rust_database_get_batch" -// database_get_list : database -> bytes list = "rust_database_get_list" -// database_accounts : database -> bytes list = "rust_database_accounts" -// database_get_inner_hash_at_addr : database -> addr -> bytes = "rust_database_get_inner_hash_at_addr" -// database_set_inner_hash_at_addr : database -> addr -> bytes -> unit = "rust_database_set_inner_hash_at_addr" -// database_get_at_index : database -> int -> account = "rust_database_get_at_index" -// database_iter : database -> (int -> bytes -> unit) -> unit = "rust_database_iter" -// database_location_of_account : database -> account_id -> addr option = "rust_database_location_of_account" -// database_location_of_account_batch : database -> account_id list -> (account_id * (addr option)) list = "rust_database_location_of_account_batch" - -// database_last_filled : database -> addr option = "rust_database_last_filled" -// database_token_owners : database -> bytes list = "rust_database_token_owners" -// database_token_owner : database -> token_id -> account_id option = "rust_database_token_owner" -// database_tokens : database -> pubkey -> token_id list = "rust_database_tokens" -// database_set : database -> addr -> account -> unit = "rust_database_set" -// database_index_of_account : database -> account_id -> int = "rust_database_index_of_account" -// database_set_at_index : database -> int -> account -> unit = "rust_database_set_at_index" -// database_get_or_create_account : database -> account_id -> account -> (([ `Added | `Existed ] * addr), rust_dberror) result = "rust_database_get_or_create_account" -// database_num_accounts : database -> int = "rust_database_num_accounts" -// database_fold_with_account_ids : database -> bytes list -> bytes -> (bytes -> unit) -> bytes = "rust_database_fold_with_ignored_accounts" -// database_fold : database -> bytes -> (bytes -> unit) -> bytes = "rust_database_fold" -// database_fold_until : database -> bytes -> (bytes -> bool) -> bytes = "rust_database_fold_until" -// database_merkle_root : database -> bytes = "rust_database_merkle_root" -// database_remove_accounts : database -> account_id list -> unit = "rust_database_remove_accounts" -// database_merkle_path : database -> addr -> bytes list = "rust_database_merkle_path" -// database_merkle_path_at_addr : database -> bytes -> bytes list = "rust_database_merkle_path_at_addr" -// database_merkle_path_at_index : database -> int -> bytes list = "rust_database_merkle_path_at_index" -// database_set_all_accounts_rooted_at : database -> addr -> bytes list -> unit = "rust_database_set_all_accounts_rooted_at" -// database_set_batch_accounts : database -> (addr * account) list -> unit = "rust_database_set_batch_accounts" -// database_get_all_accounts_rooted_at : database -> addr -> (addr * account) list = "rust_database_get_all_accounts_rooted_at" - -// (* TODO: Make those method *) -// database_foldi : database -> (addr -> bytes -> unit) -> unit = "rust_database_foldi" -// database_foldi_with_ignored_accounts : database -> account list -> (addr -> bytes -> unit) -> unit = "rust_database_foldi_with_ignored_accounts" - -#[allow(clippy::let_and_return)] -fn impl_rust_random_account() -> Vec { - // elog!("rust_random_account begin"); - - let account = Account::rand(); - let ser = serialize(&account); - - // let ser: Vec = vec![ - // 178, 29, 73, 50, 85, 80, 131, 166, 53, 11, 48, 224, 103, 89, 161, 207, 149, 31, 170, 21, - // 165, 181, 94, 18, 149, 177, 54, 71, 185, 77, 109, 49, 1, 144, 247, 164, 171, 110, 24, 3, - // 12, 25, 163, 63, 125, 83, 66, 174, 2, 160, 62, 45, 137, 185, 47, 16, 129, 145, 190, 203, - // 124, 35, 119, 251, 26, 1, 1, 6, 49, 50, 56, 54, 56, 56, 252, 29, 154, 218, 214, 79, 98, - // 177, 181, 253, 181, 152, 127, 0, 145, 177, 91, 155, 59, 239, 161, 174, 217, 42, 201, 30, - // 46, 11, 187, 88, 49, 5, 111, 254, 222, 87, 42, 45, 90, 1, 236, 173, 205, 215, 241, 20, 0, - // 77, 12, 197, 234, 69, 202, 22, 55, 50, 183, 255, 238, 8, 29, 79, 199, 92, 12, 146, 223, - // 105, 45, 135, 77, 89, 73, 141, 11, 137, 28, 54, 21, 0, 1, 4, 4, 1, 0, 4, 3, 4, 3, 2, 3, 0, - // 6, 49, 49, 56, 54, 54, 51, - // ]; - - // let account: Account = serde_binprot::from_slice(&ser).unwrap(); - - // // account2.permissions = Permissions::user_default(); - - // // let account_hash2 = account2.hash(); - - // // elog!("HASH2={:?}", account_hash2.to_string()); - - // // let mut account2 = Account::empty(); - - // // account2.public_key = account.public_key; - // // account2.token_id = account.token_id; - // // // account2.token_permissions = account.token_permissions; - // // account2.token_permissions = TokenPermissions::TokenOwned { disable_new_accounts: false }; - - // // elog!("ACCOUNT={:#?}", account2); - - // let ser = serialize(&account) - - // elog!("rust_random_account end"); - - ser -} - -// pub struct Account { -// pub public_key: CompressedPubKey, // Public_key.Compressed.t -// pub token_id: TokenId, // Token_id.t -// pub token_permissions: TokenPermissions, // Token_permissions.t -// pub token_symbol: TokenSymbol, // Token_symbol.t -// pub balance: Balance, // Balance.t -// pub nonce: Nonce, // Nonce.t -// pub receipt_chain_hash: ReceiptChainHash, // Receipt.Chain_hash.t -// pub delegate: Option, // Public_key.Compressed.t option -// pub voting_for: VotingFor, // State_hash.t -// pub timing: Timing, // Timing.t -// pub permissions: Permissions, // Permissions.t -// pub zkapp: Option, // Zkapp_account.t -// pub zkapp_uri: String, // string -// } diff --git a/ledger/src/ffi/mask.rs b/ledger/src/ffi/mask.rs deleted file mode 100644 index 5a47e732c..000000000 --- a/ledger/src/ffi/mask.rs +++ /dev/null @@ -1,1118 +0,0 @@ -use std::{borrow::Borrow, cell::RefCell, rc::Rc, str::FromStr}; - -use mina_hasher::Fp; -use mina_p2p_messages::v2::NonZeroCurvePointUncompressedStableV1; -use ocaml_interop::{ - impl_to_ocaml_polymorphic_variant, impl_to_ocaml_variant, ocaml_export, DynBox, OCaml, - OCamlBytes, OCamlException, OCamlInt, OCamlList, OCamlRef, OCamlRuntime, ToOCaml, -}; - -use crate::{ - account::{Account, AccountId}, - address::Address, - base::{AccountIndex, BaseLedger, MerklePath}, - ffi::{util::*, DatabaseFFI}, - short_backtrace, Mask, UnregisterBehavior, -}; - -// #[derive(Clone)] -struct MaskFFI(Rc>>); - -impl Drop for MaskFFI { - fn drop(&mut self) { - let mask_id = RefCell::borrow(&self.0).as_ref().map(|mask| mask.short()); - elog!("rust_mask_drop {:?}", mask_id); - } -} - -fn with_mask(rt: &mut &mut OCamlRuntime, mask: OCamlRef>, fun: F) -> R -where - F: FnOnce(&mut Mask) -> R, -{ - // elog!("111"); - let mask = rt.get(mask); - // elog!("222"); - let mask: &MaskFFI = mask.borrow(); - // elog!("333"); - let mut mask = mask.0.borrow_mut(); - - // elog!( - // "with_mask {:p}", - // Arc::as_ptr(&mask.borrow().as_ref().unwrap().inner) - // ); - - // let mut db = db.0.borrow_mut(); - - fun(mask.as_mut().unwrap()) -} - -pub enum PolymorphicGetOrAdded { - Added, - Existed, -} - -impl_to_ocaml_polymorphic_variant! { - PolymorphicGetOrAdded { - PolymorphicGetOrAdded::Added, - PolymorphicGetOrAdded::Existed, - } -} - -pub enum PolymorphicPath { - Left(Vec), - Right(Vec), -} - -impl_to_ocaml_polymorphic_variant! { - PolymorphicPath { - PolymorphicPath::Left(hash: OCamlBytes), - PolymorphicPath::Right(hash: OCamlBytes), - } -} - -#[derive(Debug, PartialEq, Eq)] -pub enum DatabaseErrorFFI { - OutOfLeaves, -} - -impl_to_ocaml_variant! { - DatabaseErrorFFI { - DatabaseErrorFFI::OutOfLeaves, - } -} - -// type rust_grandchildren = [ `Check | `Recursive | `I_promise_I_am_reparenting_this_mask ] -#[allow(non_camel_case_types)] -pub enum PolymorphicGrandchildren { - Check, - Recursive, - I_promise_I_am_reparenting_this_mask, -} - -// static DB_CLOSED: Lazy>>> = -// Lazy::new(|| Mutex::new(HashMap::with_capacity(16))); - -// static DB_CLOSED: Arc>>>> = Arc::new(Mutex::new(None)); - -// fn get_list_of<'a, T>( -// rt: &'a mut &mut OCamlRuntime, -// list: OCamlRef>, -// ) -> Vec -// where -// T: BinProtRead, -// { -// let mut list_ref = rt.get(list); -// let mut list = Vec::with_capacity(2048); - -// while let Some((head, tail)) = list_ref.uncons() { -// let object: T = serde_binprot::from_slice(head.as_bytes()).unwrap(); -// list.push(object); -// list_ref = tail; -// } - -// list -// } - -// fn get_set_of<'a, T>( -// rt: &'a mut &mut OCamlRuntime, -// list: OCamlRef>, -// ) -> HashSet -// where -// T: Deserialize<'a> + Hash + Eq, -// { -// let mut list_ref = rt.get(list); -// let mut set = HashSet::with_capacity(2048); - -// while let Some((head, tail)) = list_ref.uncons() { -// let object: T = serde_binprot::from_slice(head.as_bytes()).unwrap(); -// set.insert(object); -// list_ref = tail; -// } - -// set -// } - -// fn get_list_addr_account<'a>( -// rt: &'a mut &mut OCamlRuntime, -// list: OCamlRef>, -// ) -> Vec<(Address, Account)> { -// let mut list_ref = rt.get(list); -// let mut list = Vec::with_capacity(2048); - -// while let Some((head, tail)) = list_ref.uncons() { -// let addr = head.fst().as_str(); -// let account = head.snd().as_bytes(); - -// let addr = Address::try_from(addr).unwrap(); -// let object: Account = serde_binprot::from_slice(account).unwrap(); -// list.push((addr, object)); - -// list_ref = tail; -// } - -// list -// } - -// fn get_addr(rt: &mut &mut OCamlRuntime, addr: OCamlRef) -> Address { -// let addr_ref = rt.get(addr); -// Address::try_from(addr_ref.as_str()).unwrap() -// } - -// fn get<'a, T>(rt: &'a mut &mut OCamlRuntime, object: OCamlRef) -> T -// where -// T: Deserialize<'a>, -// { -// let object_ref = rt.get(object); -// serde_binprot::from_slice(object_ref.as_bytes()).unwrap() -// } - -// fn get_index(rt: &mut &mut OCamlRuntime, index: OCamlRef) -> AccountIndex { -// let index: i64 = index.to_rust(rt); -// let index: u64 = index.try_into().unwrap(); -// AccountIndex(index) -// } - -// fn hash_to_ocaml(hash: Fp) -> Vec { -// let hash: BigInt = hash.into(); -// serialize(&hash).unwrap() -// } - -fn get_cloned_mask( - rt: &mut &mut OCamlRuntime, - mask: OCamlRef>, -) -> Rc>> { - let mask = rt.get(mask); - let mask: &MaskFFI = mask.borrow(); - // let mut mask = mask.0.borrow_mut(); - Rc::clone(&mask.0) -} - -ocaml_export! { - fn rust_mask_create( - rt, - depth: OCamlRef, - ) -> OCaml> { - elog!("backtrace=\n{}", short_backtrace()); - - let depth: i64 = depth.to_rust(rt); - let depth: usize = depth.try_into().unwrap(); - - let mask = Mask::new_unattached(depth); - - let mask = MaskFFI(Rc::new(RefCell::new(Some(mask)))); - - OCaml::box_value(rt, mask) - } - - fn rust_cast_database_to_mask( - rt, - db: OCamlRef> - ) -> OCaml> { - // let bt = backtrace::Backtrace::new(); - // elog!("rust_cast_database_to_mask bt={:#?}", bt); - - let db = { - let db = rt.get(db); - let db: &DatabaseFFI = db.borrow(); - - // elog!("CAST_DATABASE_TO_MASK PTR={:p}", Rc::as_ptr(&db.0)); - - let db = db.0.borrow_mut(); - let db = db.as_ref().unwrap().clone(); - - db - }; - - // elog!("AAA"); - let mask = Mask::new_root(db); - let mask = MaskFFI(Rc::new(RefCell::new(Some(mask)))); - // elog!("BBB"); - - OCaml::box_value(rt, mask) - } - - fn rust_cast( - rt, - mask: OCamlRef> - ) -> OCaml> { - // let bt = backtrace::Backtrace::new(); - // elog!("rust_cast bt={:#?}", bt); - - let mask = rt.get(mask); - - // let mask = with_mask(rt, mask, |mask| { - // mask.clone() - // }); - // let mask = MaskFFI(Rc::new(RefCell::new(Some(mask)))); - - mask - // OCaml::box_value(rt, mask) - } - - fn rust_mask_copy( - rt, - mask: OCamlRef> - ) -> OCaml> { - let mask = with_mask(rt, mask, |mask| { - let uuid = mask.get_uuid(); - let copy = mask.copy(); - assert_ne!(uuid, copy.get_uuid()); - copy - }); - let mask = MaskFFI(Rc::new(RefCell::new(Some(mask)))); - - OCaml::box_value(rt, mask) - } - - fn rust_mask_set_parent( - rt, - mask: OCamlRef>, - parent: OCamlRef> - ) -> OCaml> { - let parent = { - let parent = rt.get(parent); - let parent: &MaskFFI = parent.borrow(); - let parent = parent.0.borrow_mut(); - (*parent).as_ref().unwrap().clone() - }; - - let mask = with_mask(rt, mask, |mask| { - mask.set_parent(parent, None) - }); - let mask = MaskFFI(Rc::new(RefCell::new(Some(mask)))); - - OCaml::box_value(rt, mask) - } - - fn rust_mask_register_mask( - rt, - mask: OCamlRef>, - mask2: OCamlRef> - ) -> OCaml> { - // let bt = backtrace::Backtrace::new(); - - // elog!("AAA bt={:#?}", bt); - let mask2 = { - let mask2 = rt.get(mask2); - let mask2: &MaskFFI = mask2.borrow(); - let mask2 = mask2.0.borrow_mut(); - // elog!("BBB {:p}", Arc::as_ptr(&mask2.borrow().as_ref().unwrap().inner)); - (*mask2).as_ref().unwrap().clone() - }; - // elog!("CCC"); - - let mask = with_mask(rt, mask, |mask| { - mask.register_mask(mask2) - }); - // elog!("DDD"); - - let mask = MaskFFI(Rc::new(RefCell::new(Some(mask)))); - - OCaml::box_value(rt, mask) - } - - fn rust_mask_unregister_mask( - rt, - mask: OCamlRef>, - behavior: OCamlRef - ) -> OCaml> { - let behavior = rt.get(behavior); - - let behavior = ocaml_interop::ocaml_unpack_polymorphic_variant! { - behavior => { - Check => UnregisterBehavior::Check, - Recursive => UnregisterBehavior::Recursive, - I_promise_I_am_reparenting_this_mask => UnregisterBehavior::IPromiseIAmReparentingThisMask, - } - }.unwrap(); - - let mask = with_mask(rt, mask, |mask| { - mask.unregister_mask(behavior) - }); - - let mask = MaskFFI(Rc::new(RefCell::new(Some(mask)))); - - OCaml::box_value(rt, mask) - } - - fn rust_mask_remove_and_reparent( - rt, - mask: OCamlRef> - ) { - with_mask(rt, mask, |mask| { - mask.remove_and_reparent() - }); - - OCaml::unit() - } - - fn rust_mask_commit( - rt, - mask: OCamlRef> - ) { - with_mask(rt, mask, |mask| { - mask.commit() - }); - - OCaml::unit() - } - - fn rust_print_backtrace( - rt, - _int: OCamlRef - ) { - eprintln!("rust_print_backtrace=\n{}", short_backtrace()); - - OCaml::unit() - } - - fn rust_mask_get_uuid( - rt, - mask: OCamlRef> - ) -> OCaml { - let uuid = with_mask(rt, mask, |mask| { - mask.get_uuid() - }); - - uuid.to_ocaml(rt) - } - - fn rust_mask_get_directory( - rt, - mask: OCamlRef> - ) -> OCaml> { - let dir = with_mask(rt, mask, |mask| { - mask.get_directory().map(|d| d.into_os_string().into_string().unwrap()) - }); - - dir.to_ocaml(rt) - } - - fn rust_mask_depth( - rt, - mask: OCamlRef> - ) -> OCaml { - let depth = with_mask(rt, mask, |mask| { - mask.depth() as i64 - }); - - depth.to_ocaml(rt) - } - - fn rust_mask_close( - rt, - mask: OCamlRef> - ) { - // let mask = rt.get(mask); - // let mask: &MaskFFI = mask.borrow(); - - with_mask(rt, mask, |mask| { - mask.close(); - }); - - OCaml::unit() - } - - fn rust_mask_get( - rt, - mask: OCamlRef>, - addr: OCamlRef, - ) -> OCaml> { - elog!("backtrace=\n{}", short_backtrace()); - - let addr = get_addr(rt, addr); - - let mut acc = None; - - let account = with_mask(rt, mask, |mask| { - mask.get(addr.clone()) - }).map(|account| { - acc = Some(account.clone()); - account.serialize() - }); - - elog!("rust_mask_get is_some={:?} addr={:?} account={:?}", account.is_some(), addr, acc); - - account.to_ocaml(rt) - } - - fn rust_mask_get_batch( - rt, - mask: OCamlRef>, - addrs: OCamlRef>, - ) -> OCaml)>> { - let mut addrs_ref = rt.get(addrs); - - let mut addrs = Vec::with_capacity(2048); - while let Some((head, tail)) = addrs_ref.uncons() { - let addr = Address::try_from(head.as_str()).unwrap(); - addrs.push(addr); - addrs_ref = tail; - } - - let accounts: Vec<(String, Option>)> = with_mask(rt, mask, |mask| { - mask.get_batch(&addrs) - }).into_iter() - .map(|(addr, opt_account)| { - let addr = addr.to_string(); - let opt_account = opt_account.map(|acc| acc.serialize()); - (addr, opt_account) - }) - .collect(); - - accounts.to_ocaml(rt) - } - - fn rust_mask_get_list( - rt, - mask: OCamlRef>, - ) -> OCaml> { - - let accounts: Vec> = with_mask(rt, mask, |mask| { - mask.to_list() - }).into_iter() - .map(|account| { - serialize(&account) - }) - .collect(); - - accounts.to_ocaml(rt) - } - - fn rust_mask_accounts( - rt, - mask: OCamlRef>, - ) -> OCaml> { - - let accounts: Vec> = with_mask(rt, mask, |mask| { - mask.accounts() - }).into_iter() - .map(|account_id| { - serialize(&account_id) - }) - .collect(); - - accounts.to_ocaml(rt) - } - - fn rust_mask_get_inner_hash_at_addr( - rt, - mask: OCamlRef>, - addr: OCamlRef, - ) -> OCaml { - let addr = get_addr(rt, addr); - - let hash = with_mask(rt, mask, |mask| { - mask.get_inner_hash_at_addr(addr) - }).map(|hash| { - hash_to_ocaml(hash) - }) - .unwrap(); - - hash.to_ocaml(rt) - } - - fn rust_mask_set_inner_hash_at_addr( - rt, - mask: OCamlRef>, - addr: OCamlRef, - hash: OCamlRef, - ) { - let addr = get_addr(rt, addr); - - let hash: String = hash.to_rust(rt); - let hash = Fp::from_str(&hash).unwrap(); - - with_mask(rt, mask, |mask| { - mask.set_inner_hash_at_addr(addr, hash).unwrap() - }); - - OCaml::unit() - } - - fn rust_mask_get_at_index( - rt, - mask: OCamlRef>, - index: OCamlRef - ) -> OCaml { - let index = get_index(rt, index); - - let account = with_mask(rt, mask, |mask| { - mask.get_at_index(index).unwrap() - }); - let account = serialize(&account); - - account.to_ocaml(rt) - } - - fn rust_mask_location_of_account( - rt, - mask: OCamlRef>, - account_id: OCamlRef - ) -> OCaml> { - elog!("backtrace=\n{}", short_backtrace()); - - let account_id = get(rt, account_id); - - let mut a = None; - let mut acc = None; - - let addr = with_mask(rt, mask, |mask| { - mask.location_of_account(&account_id) - }).map(|addr| { - a = Some(addr.clone()); - acc = Some(with_mask(rt, mask, |mask| mask.get(addr.clone()).unwrap())); - - addr.to_string() - }); - - // eprintln!("rust_mask_location_of_account is_some={:?} account_id={:?} addr={:?}", addr.is_some(), account_id, a); - - // eprintln!("rust_mask_location_of_account is_some={:?} addr={:?} account={:?}", addr.is_some(), a, acc); - - addr.to_ocaml(rt) - } - - fn rust_mask_location_of_account_batch( - rt, - mask: OCamlRef>, - account_ids: OCamlRef> - ) -> OCaml)>> { - elog!("backtrace=\n{}", short_backtrace()); - - let account_ids = get_list_of::(rt, account_ids); - - // eprintln!("mask_location_of_account_batch={:?}", account_ids); - - let addrs = with_mask(rt, mask, |mask| { - mask.location_of_account_batch(&account_ids) - }).into_iter() - .map(|(account_id, opt_addr)| { - let account_id = serialize(&account_id); - let addr = opt_addr.map(|addr| addr.to_string()); - (account_id, addr) - }) - .collect::>(); - - addrs.to_ocaml(rt) - } - - fn rust_mask_last_filled( - rt, - mask: OCamlRef>, - ) -> OCaml> { - let addr = with_mask(rt, mask, |mask| { - mask.last_filled() - }).map(|addr| { - addr.to_string() - }); - - addr.to_ocaml(rt) - } - - fn rust_mask_token_owners( - rt, - mask: OCamlRef>, - ) -> OCaml> { - let owners = with_mask(rt, mask, |mask| { - mask.token_owners() - }).iter() - .map(|account_id| { - serialize(account_id) - }) - .collect::>(); - - owners.to_ocaml(rt) - } - - fn rust_mask_token_owner( - rt, - mask: OCamlRef>, - token_id: OCamlRef, - ) -> OCaml> { - let token_id = get(rt, token_id); - - let owner = with_mask(rt, mask, |mask| { - mask.token_owner(token_id) - }).map(|account_id| { - serialize(&account_id) - }); - - owner.to_ocaml(rt) - } - - fn rust_mask_tokens( - rt, - mask: OCamlRef>, - pubkey: OCamlRef, - ) -> OCaml> { - let pubkey: NonZeroCurvePointUncompressedStableV1 = get(rt, pubkey); - - let tokens = with_mask(rt, mask, |mask| { - mask.tokens(pubkey.into()) - }).iter() - .map(|token_id| { - serialize(token_id) - }) - .collect::>(); - - tokens.to_ocaml(rt) - } - - fn rust_mask_set( - rt, - mask: OCamlRef>, - addr: OCamlRef, - account: OCamlRef, - ) { - elog!("backtrace=\n{}", short_backtrace()); - - let addr = get_addr(rt, addr); - let account = get(rt, account); - - elog!("rust_mask_set addr={:?}", addr); - - with_mask(rt, mask, |mask| { - mask.set(addr, account) - }); - - OCaml::unit() - } - - fn rust_mask_index_of_account( - rt, - mask: OCamlRef>, - account_id: OCamlRef - ) -> OCaml { - let account_id = get(rt, account_id); - - // eprintln!("mask_index_of_account={:?}", account_id); - - let index = with_mask(rt, mask, |mask| { - mask.index_of_account(account_id) - }).map(|index| { - index.0 as i64 - }) - .unwrap(); - - index.to_ocaml(rt) - } - - fn rust_mask_set_at_index( - rt, - mask: OCamlRef>, - index: OCamlRef, - account: OCamlRef, - ) { - let index = get_index(rt, index); - let account = get(rt, account); - - with_mask(rt, mask, |mask| { - mask.set_at_index(index, account) - }).unwrap(); - - OCaml::unit() - } - - fn rust_mask_get_or_create_account( - rt, - mask: OCamlRef>, - account_id: OCamlRef, - account: OCamlRef, - ) -> OCaml> { - let account_id = get(rt, account_id); - let account = get(rt, account); - - // eprintln!("mask_get_or_create_account={:?}", account_id); - // eprintln!("backtrace=\n{}", short_backtrace()); - - let result = with_mask(rt, mask, |mask| { - mask.get_or_create_account(account_id, account) - }); - - use crate::base::GetOrCreated::*; - use crate::database::DatabaseError::*; - - let result = match result { - Ok(value) => { - let get_or_added = match value { - Added(_) => PolymorphicGetOrAdded::Added, - Existed(_) => PolymorphicGetOrAdded::Existed, - }; - let addr = value.addr(); - Ok((get_or_added, addr.to_string())) - }, - Err(e) => match e { - OutOfLeaves => Err(DatabaseErrorFFI::OutOfLeaves), - }, - }; - - result.to_ocaml(rt) - } - - fn rust_mask_num_accounts( - rt, - mask: OCamlRef> - ) -> OCaml { - let num_accounts = with_mask(rt, mask, |mask| { - mask.num_accounts() as i64 - }); - - num_accounts.to_ocaml(rt) - } - - fn rust_mask_iter( - rt, - mask: OCamlRef>, - ocaml_method: OCamlRef, - ) { - let (num_accounts, depth) = with_mask(rt, mask, |mask| { - (mask.num_accounts(), mask.depth()) - }); - - let ocaml_method = ocaml_method.to_boxroot(rt); - - for index in 0..num_accounts { - let account_index = AccountIndex(index as u64); - let addr = Address::from_index(account_index, depth as usize); - - let account = with_mask(rt, mask, |mask| { - mask.get(addr) - }); - - let account = match account { - Some(account) => account, - None => continue, - }; - - let account = serialize(&account); - - let index = index as i64; - let _: Result, OCamlException> = ocaml_method.try_call(rt, &index, &account); - } - - OCaml::unit() - } - - fn rust_mask_foldi( - rt, - mask: OCamlRef>, - ocaml_method: OCamlRef, - ) { - let (num_accounts, depth) = with_mask(rt, mask, |mask| { - (mask.num_accounts(), mask.depth()) - }); - - let ocaml_method = ocaml_method.to_boxroot(rt); - - for index in 0..num_accounts { - let index = AccountIndex(index as u64); - let addr = Address::from_index(index, depth as usize); - - let account = with_mask(rt, mask, |mask| { - mask.get(addr.clone()) - }); - - let account = match account { - Some(account) => account, - None => continue, - }; - - let account = serialize(&account); - let addr = addr.to_string(); - - let _: Result, _> = ocaml_method.try_call(rt, &addr, &account); - } - - OCaml::unit() - } - - fn rust_mask_foldi_with_ignored_accounts( - rt, - mask: OCamlRef>, - ignored_accounts: OCamlRef>, - ocaml_method: OCamlRef, - ) { - let (num_accounts, depth) = with_mask(rt, mask, |mask| { - (mask.num_accounts(), mask.depth()) - }); - - let ignored_accounts = get_set_of::(rt, ignored_accounts); - let ocaml_method = ocaml_method.to_boxroot(rt); - - for index in 0..num_accounts { - let index = AccountIndex(index as u64); - let addr = Address::from_index(index, depth as usize); - - let account = with_mask(rt, mask, |mask| { - mask.get(addr.clone()) - }); - - let account = match account { - Some(account) => account, - None => continue, - }; - - if ignored_accounts.contains(&account.id()) { - continue; - } - - let account = serialize(&account); - let addr = addr.to_string(); - - let _: Result, _> = ocaml_method.try_call(rt, &addr, &account); - } - - OCaml::unit() - } - - fn rust_mask_merkle_root( - rt, - mask: OCamlRef>, - ) -> OCaml { - elog!("backtrace=\n{}", short_backtrace()); - - let hash = with_mask(rt, mask, |mask| { - mask.merkle_root() - }); - - let hash = hash_to_ocaml(hash); - - hash.to_ocaml(rt) - } - - fn rust_mask_remove_accounts( - rt, - mask: OCamlRef>, - account_ids: OCamlRef>, - ) { - let account_ids = get_list_of(rt, account_ids); - - // eprintln!("remove_accounts={:?}", account_ids); - - with_mask(rt, mask, |mask| { - mask.remove_accounts(&account_ids) - }); - - OCaml::unit() - } - - fn rust_mask_set_all_accounts_rooted_at( - rt, - mask: OCamlRef>, - addr: OCamlRef, - accounts: OCamlRef>, - ) { - let addr = get_addr(rt, addr); - let accounts = get_list_of(rt, accounts); - - with_mask(rt, mask, |mask| { - mask.set_all_accounts_rooted_at(addr, &accounts).unwrap() - }); - - OCaml::unit() - } - - fn rust_mask_set_batch_accounts( - rt, - mask: OCamlRef>, - accounts: OCamlRef>, - ) { - let accounts = get_list_addr_account(rt, accounts); - - with_mask(rt, mask, |mask| { - mask.set_batch_accounts(&accounts) - }); - - OCaml::unit() - } - - fn rust_mask_get_all_accounts_rooted_at( - rt, - mask: OCamlRef>, - addr: OCamlRef, - ) -> OCaml> { - let addr = get_addr(rt, addr); - - let accounts = with_mask(rt, mask, |mask| { - mask.get_all_accounts_rooted_at(addr) - }).unwrap_or_default() - .iter() - .map(|(addr, account)| { - let addr = addr.to_string(); - let account = serialize(account); - (addr, account) - }) - .collect::>(); - - accounts.to_ocaml(rt) - } - - fn rust_mask_merkle_path( - rt, - mask: OCamlRef>, - addr: OCamlRef, - ) -> OCaml> { - let addr = get_addr(rt, addr); - - let path = with_mask(rt, mask, |mask| { - mask.merkle_path(addr) - }).into_iter() - .map(|path| { - match path { - MerklePath::Left(hash) => PolymorphicPath::Left(hash_to_ocaml(hash)), - MerklePath::Right(hash) => PolymorphicPath::Right(hash_to_ocaml(hash)), - } - }) - .collect::>(); - - path.to_ocaml(rt) - } - - fn rust_mask_merkle_path_at_addr( - rt, - mask: OCamlRef>, - addr: OCamlRef, - ) -> OCaml> { - let addr = get_addr(rt, addr); - - let path = with_mask(rt, mask, |mask| { - mask.merkle_path(addr) - }).into_iter() - .map(|path| { - match path { - MerklePath::Left(hash) => PolymorphicPath::Left(hash_to_ocaml(hash)), - MerklePath::Right(hash) => PolymorphicPath::Right(hash_to_ocaml(hash)), - } - }) - .collect::>(); - - path.to_ocaml(rt) - } - - fn rust_mask_merkle_path_at_index( - rt, - mask: OCamlRef>, - index: OCamlRef, - ) -> OCaml> { - let index = get_index(rt, index); - - let path = with_mask(rt, mask, |mask| { - let depth = mask.depth(); - let addr = Address::from_index(index, depth as usize); - mask.merkle_path(addr) - }).into_iter() - .map(|path| { - match path { - MerklePath::Left(hash) => PolymorphicPath::Left(hash_to_ocaml(hash)), - MerklePath::Right(hash) => PolymorphicPath::Right(hash_to_ocaml(hash)), - // MerklePath::Left(hash) => PolymorphicPath::Left(hash.to_string()), - // MerklePath::Right(hash) => PolymorphicPath::Right(hash.to_string()), - } - }) - .collect::>(); - - path.to_ocaml(rt) - } -} - -// database_create : int -> database = "rust_mask_create" -// database_get_uuid : database -> string = "rust_mask_get_uuid" -// database_depth : database -> int = "rust_mask_depth" -// database_create_checkpoint : database -> database = "rust_mask_create_checkpoint" -// database_make_checkpoint : database -> unit = "rust_mask_make_checkpoint" -// database_close : database -> unit = "rust_mask_close" -// database_get : database -> addr -> account option = "rust_mask_get" -// database_get_batch : database -> addr list -> (addr * (account option)) list = "rust_mask_get_batch" -// database_get_list : database -> bytes list = "rust_mask_get_list" -// database_accounts : database -> bytes list = "rust_mask_accounts" -// database_get_inner_hash_at_addr : database -> addr -> bytes = "rust_mask_get_inner_hash_at_addr" -// database_set_inner_hash_at_addr : database -> addr -> bytes -> unit = "rust_mask_set_inner_hash_at_addr" -// database_get_at_index : database -> int -> account = "rust_mask_get_at_index" -// database_iter : database -> (int -> bytes -> unit) -> unit = "rust_mask_iter" -// database_location_of_account : database -> account_id -> addr option = "rust_mask_location_of_account" -// database_location_of_account_batch : database -> account_id list -> (account_id * (addr option)) list = "rust_mask_location_of_account_batch" - -// database_last_filled : database -> addr option = "rust_mask_last_filled" -// database_token_owners : database -> bytes list = "rust_mask_token_owners" -// database_token_owner : database -> token_id -> account_id option = "rust_mask_token_owner" -// database_tokens : database -> pubkey -> token_id list = "rust_mask_tokens" -// database_set : database -> addr -> account -> unit = "rust_mask_set" -// database_index_of_account : database -> account_id -> int = "rust_mask_index_of_account" -// database_set_at_index : database -> int -> account -> unit = "rust_mask_set_at_index" -// database_get_or_create_account : database -> account_id -> account -> (([ `Added | `Existed ] * addr), rust_maskerror) result = "rust_mask_get_or_create_account" -// database_num_accounts : database -> int = "rust_mask_num_accounts" -// database_fold_with_account_ids : database -> bytes list -> bytes -> (bytes -> unit) -> bytes = "rust_mask_fold_with_ignored_accounts" -// database_fold : database -> bytes -> (bytes -> unit) -> bytes = "rust_mask_fold" -// database_fold_until : database -> bytes -> (bytes -> bool) -> bytes = "rust_mask_fold_until" -// database_merkle_root : database -> bytes = "rust_mask_merkle_root" -// database_remove_accounts : database -> account_id list -> unit = "rust_mask_remove_accounts" -// database_merkle_path : database -> addr -> bytes list = "rust_mask_merkle_path" -// database_merkle_path_at_addr : database -> bytes -> bytes list = "rust_mask_merkle_path_at_addr" -// database_merkle_path_at_index : database -> int -> bytes list = "rust_mask_merkle_path_at_index" -// database_set_all_accounts_rooted_at : database -> addr -> bytes list -> unit = "rust_mask_set_all_accounts_rooted_at" -// database_set_batch_accounts : database -> (addr * account) list -> unit = "rust_mask_set_batch_accounts" -// database_get_all_accounts_rooted_at : database -> addr -> (addr * account) list = "rust_mask_get_all_accounts_rooted_at" - -// (* TODO: Make those method *) -// database_foldi : database -> (addr -> bytes -> unit) -> unit = "rust_mask_foldi" -// database_foldi_with_ignored_accounts : database -> account list -> (addr -> bytes -> unit) -> unit = "rust_mask_foldi_with_ignored_accounts" - -#[allow(clippy::let_and_return)] -fn impl_rust_random_account() -> Vec { - // elog!("rust_random_account begin"); - - let account = Account::rand(); - let ser = serialize(&account); - - // let ser: Vec = vec![ - // 178, 29, 73, 50, 85, 80, 131, 166, 53, 11, 48, 224, 103, 89, 161, 207, 149, 31, 170, 21, - // 165, 181, 94, 18, 149, 177, 54, 71, 185, 77, 109, 49, 1, 144, 247, 164, 171, 110, 24, 3, - // 12, 25, 163, 63, 125, 83, 66, 174, 2, 160, 62, 45, 137, 185, 47, 16, 129, 145, 190, 203, - // 124, 35, 119, 251, 26, 1, 1, 6, 49, 50, 56, 54, 56, 56, 252, 29, 154, 218, 214, 79, 98, - // 177, 181, 253, 181, 152, 127, 0, 145, 177, 91, 155, 59, 239, 161, 174, 217, 42, 201, 30, - // 46, 11, 187, 88, 49, 5, 111, 254, 222, 87, 42, 45, 90, 1, 236, 173, 205, 215, 241, 20, 0, - // 77, 12, 197, 234, 69, 202, 22, 55, 50, 183, 255, 238, 8, 29, 79, 199, 92, 12, 146, 223, - // 105, 45, 135, 77, 89, 73, 141, 11, 137, 28, 54, 21, 0, 1, 4, 4, 1, 0, 4, 3, 4, 3, 2, 3, 0, - // 6, 49, 49, 56, 54, 54, 51, - // ]; - - // let account: Account = serde_binprot::from_slice(&ser).unwrap(); - - // // account2.permissions = Permissions::user_default(); - - // // let account_hash2 = account2.hash(); - - // // elog!("HASH2={:?}", account_hash2.to_string()); - - // // let mut account2 = Account::empty(); - - // // account2.public_key = account.public_key; - // // account2.token_id = account.token_id; - // // // account2.token_permissions = account.token_permissions; - // // account2.token_permissions = TokenPermissions::TokenOwned { disable_new_accounts: false }; - - // // elog!("ACCOUNT={:#?}", account2); - - // let ser = serialize(&account).unwrap(); - - // elog!("rust_random_account end"); - - ser -} - -// pub struct Account { -// pub public_key: CompressedPubKey, // Public_key.Compressed.t -// pub token_id: TokenId, // Token_id.t -// pub token_permissions: TokenPermissions, // Token_permissions.t -// pub token_symbol: TokenSymbol, // Token_symbol.t -// pub balance: Balance, // Balance.t -// pub nonce: Nonce, // Nonce.t -// pub receipt_chain_hash: ReceiptChainHash, // Receipt.Chain_hash.t -// pub delegate: Option, // Public_key.Compressed.t option -// pub voting_for: VotingFor, // State_hash.t -// pub timing: Timing, // Timing.t -// pub permissions: Permissions, // Permissions.t -// pub zkapp: Option, // Zkapp_account.t -// pub zkapp_uri: String, // string -// } diff --git a/ledger/src/ffi/mod.rs b/ledger/src/ffi/mod.rs deleted file mode 100644 index 5e813202a..000000000 --- a/ledger/src/ffi/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -// mod block; -mod database; -mod mask; -mod ondisk; -// mod transaction_fuzzer; -//mod util; - -use database::*; diff --git a/ledger/src/ffi/ondisk.rs b/ledger/src/ffi/ondisk.rs deleted file mode 100644 index 4344360f2..000000000 --- a/ledger/src/ffi/ondisk.rs +++ /dev/null @@ -1,326 +0,0 @@ -use std::{borrow::Borrow, cell::RefCell, rc::Rc}; - -use ocaml_interop::{ - bigarray::Array1, ocaml_export, DynBox, FromOCaml, OCaml, OCamlInt, OCamlList, OCamlRef, - OCamlRuntime, ToOCaml, -}; - -use crate::ondisk::{batch::Batch, Database}; - -pub struct DatabaseFFI(pub Rc>>); -pub struct BatchFFI(pub Rc>); - -type OCamlBigstring = Array1; - -fn with_db( - rt: &mut &mut OCamlRuntime, - db: OCamlRef>, - fun: F, -) -> std::io::Result -where - F: FnOnce(&mut Database) -> std::io::Result, -{ - let db = rt.get(db); - let db: &DatabaseFFI = db.borrow(); - let mut db = db.0.borrow_mut(); - let db = db - .as_mut() - .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, "Database was closed"))?; - - fun(db) -} - -fn with_batch(rt: &mut &mut OCamlRuntime, db: OCamlRef>, fun: F) -> R -where - F: FnOnce(&mut Batch) -> R, -{ - let db = rt.get(db); - let db: &BatchFFI = db.borrow(); - let mut db = db.0.borrow_mut(); - - fun(&mut db) -} - -fn get>(rt: &mut &mut OCamlRuntime, value: OCamlRef) -> T { - let value = rt.get(value); - value.to_rust::() -} - -fn get_bigstring(rt: &mut &mut OCamlRuntime, value: OCamlRef>) -> Box<[u8]> { - let value = rt.get(value); - Box::<[u8]>::from(value.as_slice()) -} - -fn get_list_of( - rt: &mut &mut OCamlRuntime, - values: OCamlRef>, - fun: F, -) -> Vec -where - F: Fn(OCaml) -> T, -{ - let mut values_ref = rt.get(values); - - let mut values = Vec::with_capacity(2048); - while let Some((head, tail)) = values_ref.uncons() { - let key: T = fun(head); - - values.push(key); - values_ref = tail; - } - - values -} - -ocaml_export! { - fn rust_ondisk_database_create( - rt, - dir_name: OCamlRef - ) -> OCaml, String>> { - let dir_name: String = get(rt, dir_name); - - elog!("rust_ondisk_database_create={:?}", dir_name); - - Database::create(dir_name) - .map(|db| DatabaseFFI(Rc::new(RefCell::new(Some(db))))) - .map(|db| OCaml::box_value(rt, db).root()) - .map_err(|e| format!("{:?}", e)) - .to_ocaml(rt) - } - - fn rust_ondisk_database_get_uuid( - rt, - db: OCamlRef> - ) -> OCaml> { - with_db(rt, db, |db| { - Ok(db.get_uuid().clone()) - }) - .map_err(|e| format!("{:?}", e)) - .to_ocaml(rt) - } - - fn rust_ondisk_database_close( - rt, - db: OCamlRef> - ) -> OCaml> { - { - let db = rt.get(db); - let db: &DatabaseFFI = db.borrow(); - let mut db = db.0.borrow_mut(); - let db = db.take().unwrap(); - db.close(); - - std::mem::drop(db); - } - - Ok::<_, String>(()).to_ocaml(rt) - } - - fn rust_ondisk_database_get( - rt, - db: OCamlRef>, - key: OCamlRef, - ) -> OCaml, String>> { - // We avoid to copy the key here - let db = { - let db = rt.get(db); - let db: &DatabaseFFI = db.borrow(); - Rc::clone(&db.0) - }; - - let mut db = db.borrow_mut(); - - db.as_mut() - .ok_or_else(|| "Database was closed".to_string()) - .and_then(|db| { - let key: OCaml = rt.get(key); - let key: &[u8] = key.as_slice(); - - db.get(key).map_err(|e| format!("{:?}", e)) - }) - .to_ocaml(rt) - } - - fn rust_ondisk_database_set( - rt, - db: OCamlRef>, - key: OCamlRef, - value: OCamlRef, - ) -> OCaml> { - let key: Box<[u8]> = get_bigstring(rt, key); - let value: Box<[u8]> = get_bigstring(rt, value); - - with_db(rt, db, |db| { - db.set(key, value) - }) - .map_err(|e| format!("{:?}", e)) - .to_ocaml(rt) - } - - fn rust_ondisk_database_get_batch( - rt, - db: OCamlRef>, - keys: OCamlRef>, - ) -> OCaml>, String>> { - let keys: Vec> = get_list_of(rt, keys, |v| v.as_slice().into()); - - with_db(rt, db, |db| { - db.get_batch(keys) - }) - .map_err(|e| format!("{:?}", e)) - .to_ocaml(rt) - } - - fn rust_ondisk_database_set_batch( - rt, - db: OCamlRef>, - remove_keys: OCamlRef>, - key_data_pairs: OCamlRef>, - ) -> OCaml> { - let remove_keys: Vec> = get_list_of(rt, remove_keys, |v| { - v.as_slice().into() - }); - - let key_data_pairs: Vec<(Box<[u8]>, Box<[u8]>)> = get_list_of(rt, key_data_pairs, |v| { - let (key, value) = v.to_tuple(); - - let key = key.as_slice().into(); - let value = value.as_slice().into(); - - (key, value) - }); - - with_db(rt, db, |db| { - db.set_batch(key_data_pairs, remove_keys) - }) - .map_err(|e| format!("{:?}", e)) - .to_ocaml(rt) - } - - fn rust_ondisk_database_make_checkpoint( - rt, - db: OCamlRef>, - directory: OCamlRef - ) -> OCaml> { - let directory: String = get(rt, directory); - - with_db(rt, db, |db| { - db.make_checkpoint(directory.as_str()) - }) - .map_err(|e| format!("{:?}", e)) - .to_ocaml(rt) - } - - fn rust_ondisk_database_create_checkpoint( - rt, - db: OCamlRef>, - directory: OCamlRef - ) -> OCaml, String>> { - let directory: String = get(rt, directory); - - with_db(rt, db, |db| { - db.create_checkpoint(directory.as_str()) - }) - .map(|checkpoint| DatabaseFFI(Rc::new(RefCell::new(Some(checkpoint))))) - .map(|checkpoint| OCaml::box_value(rt, checkpoint).root()) - .map_err(|e| format!("{:?}", e)) - .to_ocaml(rt) - } - - fn rust_ondisk_database_remove( - rt, - db: OCamlRef>, - key: OCamlRef, - ) -> OCaml> { - let key: Box<[u8]> = get_bigstring(rt, key); - - with_db(rt, db, |db| { - db.remove(key) - }) - .map_err(|e| format!("{:?}", e)) - .to_ocaml(rt) - } - - fn rust_ondisk_database_to_alist( - rt, - db: OCamlRef>, - ) -> OCaml, String>> { - with_db(rt, db, |db| { - db.to_alist() - }) - .map_err(|e| format!("{:?}", e)) - .to_ocaml(rt) - } - - fn rust_ondisk_database_batch_create( - rt, - _index: OCamlRef, - ) -> OCaml> { - let batch: Batch = Batch::new(); - let batch: BatchFFI = BatchFFI(Rc::new(RefCell::new(batch))); - OCaml::box_value(rt, batch) - } - - fn rust_ondisk_database_batch_set( - rt, - batch: OCamlRef>, - key: OCamlRef, - value: OCamlRef, - ) { - let key: Box<[u8]> = get_bigstring(rt, key); - let value: Box<[u8]> = get_bigstring(rt, value); - - with_batch(rt, batch, |batch| { - batch.set(key, value) - }); - - OCaml::unit() - } - - fn rust_ondisk_database_batch_remove( - rt, - batch: OCamlRef>, - key: OCamlRef, - ) { - let key: Box<[u8]> = get_bigstring(rt, key); - - with_batch(rt, batch, |batch| { - batch.remove(key) - }); - - OCaml::unit() - } - - fn rust_ondisk_database_batch_run( - rt, - db: OCamlRef>, - batch: OCamlRef>, - ) -> OCaml> { - let result = { - let db = rt.get(db); - let db: &DatabaseFFI = db.borrow(); - let mut db = db.0.borrow_mut(); - let db = db.as_mut().unwrap(); - - let batch = rt.get(batch); - let batch: &BatchFFI = batch.borrow(); - let mut batch = batch.0.borrow_mut(); - - db.run_batch(&mut batch) - }; - - result.map_err(|e| format!("{:?}", e)) - .to_ocaml(rt) - } - - fn rust_ondisk_database_gc( - rt, - db: OCamlRef>, - ) -> OCaml> { - with_db(rt, db, |db| { - db.gc() - }) - .map_err(|e| format!("{:?}", e)) - .to_ocaml(rt) - } -} diff --git a/ledger/src/lib.rs b/ledger/src/lib.rs index b43029f81..8366b7fe8 100644 --- a/ledger/src/lib.rs +++ b/ledger/src/lib.rs @@ -37,9 +37,6 @@ mod wasm { #[macro_use] mod cache; -#[cfg(all(not(target_family = "wasm"), feature = "ocaml-interop"))] -mod ffi; - #[cfg(any(test, feature = "fuzzing"))] pub mod generators;