-
Notifications
You must be signed in to change notification settings - Fork 54
feat(swift-sdk,platform-wallet): wire shielded send end-to-end (all 4 transitions) #3603
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
QuantumExplorer
wants to merge
85
commits into
v3.1-dev
Choose a base branch
from
platform-wallet/shielded-spend-ffi
base: v3.1-dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 7 commits
Commits
Show all changes
85 commits
Select commit
Hold shift + click to select a range
1e83b53
feat(swift-sdk,platform-wallet): wire shielded transfer/unshield/with…
QuantumExplorer 2180c68
feat(swift-sdk,platform-wallet): wire shield (Platform → Shielded, Ty…
QuantumExplorer c15a175
fix(swift-sdk,platform-wallet): hydrate persisted address balances on…
QuantumExplorer a8d9b14
fix(platform-wallet-ffi): run shielded proof on worker thread
QuantumExplorer dfbb2f8
fix(platform-wallet): surface Platform's per-input view on shield bro…
QuantumExplorer 6c72239
fix(platform-wallet): reserve fee headroom on shield input 0
QuantumExplorer 6e4931c
fix(swift-sdk,platform-wallet): address PR review feedback
QuantumExplorer 3627d0f
fix(platform-wallet): wire shielded spend Merkle witnesses through Sh…
QuantumExplorer 9211a0d
fix(swift-example-app): per-wallet shielded commitment-tree DB
QuantumExplorer 3ffce1a
fix(swift-example-app): repoint ShieldedService when opening a wallet…
QuantumExplorer 4ba2c42
feat(platform-wallet,swift-sdk): multi-account shielded wallet (Desig…
QuantumExplorer 771b01c
feat(platform-wallet): shielded changeset + per-subwallet restore-on-…
QuantumExplorer 784ce02
feat(swift-sdk,platform-wallet-ffi): SwiftData persistence for shield…
QuantumExplorer 589ee68
feat(swift-example-app): storage explorer rows for shielded notes + s…
QuantumExplorer 9ab48e3
feat(swift-example-app): multi-account shielded UI in WalletDetailView
QuantumExplorer 2daf333
fix(platform-wallet): derive shielded spend anchor from witness paths
QuantumExplorer 44f9f57
fix(platform-wallet): use monotonic checkpoint id in shielded sync
QuantumExplorer 515a694
fix(swift-example-app): route orphan recovery to the wallet's intende…
QuantumExplorer a3f4edd
fix(swift-example-app): aggregate orphan-recovery failures with actio…
QuantumExplorer 00624ad
fix(swift-example-app): log orphan-recovery errors via SDKLogger
QuantumExplorer ed30077
fix(swift-sdk,swift-example-app): always log orphan-recovery failures
QuantumExplorer 83054cb
fix(platform-wallet): validate spend anchor against Platform's record…
QuantumExplorer e532eef
fix(platform-wallet,sdk): fall back to most-recent shielded anchor wh…
QuantumExplorer 9609aee
Merge remote-tracking branch 'origin/v3.1-dev' into platform-wallet/s…
QuantumExplorer 497b74f
docs(claude): fix iOS framework build path in project CLAUDE.md
QuantumExplorer d6a890a
fix(swift-example-app): only overlay shielded-notes empty state when …
QuantumExplorer 6cc4d9a
fix(swift-example-app): add storage-explorer detail views for shielde…
QuantumExplorer 1911d73
revert(platform-wallet): drop spend-side anchor pre-flight, trust dep…
QuantumExplorer 9e4ecdf
feat(swift-example-app): show per-account synced index in shielded sy…
QuantumExplorer 532b886
fix(swift-example-app): use renamed boundWalletId in shielded sync ev…
QuantumExplorer 33267c5
fix(swift-example-app): show persisted balance per shielded account, …
QuantumExplorer c1bb53a
Merge remote-tracking branch 'origin/v3.1-dev' into platform-wallet/s…
QuantumExplorer c1b0eaf
Merge remote-tracking branch 'origin/v3.1-dev' into platform-wallet/s…
QuantumExplorer aea6dd1
fix(platform-wallet,swift-sdk): pending-then-confirm shielded spends …
QuantumExplorer 1e22b90
Merge remote-tracking branch 'origin/v3.1-dev' into platform-wallet/s…
QuantumExplorer 64f8edd
Merge remote-tracking branch 'origin/v3.1-dev' into platform-wallet/s…
QuantumExplorer 39b9917
fix(platform-wallet-ffi): include shielded callbacks in PersistenceCa…
QuantumExplorer c031340
Merge remote-tracking branch 'origin/v3.1-dev' into platform-wallet/s…
QuantumExplorer e233bc5
fix(swift-example-app): drop leftover unused `amount` guard in coreTo…
QuantumExplorer 51da731
fix(swift-example-app): include shielded balance in Wallets row total
QuantumExplorer b0fa943
fix(swift-example-app): make shielded-sync Clear button actually wipe…
QuantumExplorer 15650d3
fix(swift-example-app): shielded Clear should stop, not auto-rebind
QuantumExplorer 4d7d7ff
fix(swift-example-app): shielded-only wallets show their balance, not…
QuantumExplorer d4323c0
fix(swift-example-app): Clear wipes all shielded state, not just boun…
QuantumExplorer 9f664de
fix(swift-example-app): stop manager-wide shielded sync before wiping…
QuantumExplorer 3da3fc0
fix(swift-example-app): make post-Clear shielded state look intention…
QuantumExplorer 6673cc2
fix(platform-wallet): shielded sync stops re-counting + re-fetching t…
QuantumExplorer 2e7d392
fix(swift-example-app): gate shielded Clear on isSyncing
QuantumExplorer 81addc9
fix(platform-wallet): drop MutexGuard before await in shielded sync c…
QuantumExplorer c3faf57
style(platform-wallet): apply rustfmt to sync.rs cooldown closure
QuantumExplorer d3673f2
fix(swift-example-app): post-Clear Sync Now self-binds + syncs from t…
QuantumExplorer 524a722
fix(swift-example-app): stop deleting per-network SQLite tree on shie…
QuantumExplorer bf16bc8
fix(swift-example-app): restart manager-wide shielded sync after Clea…
QuantumExplorer 848c905
fix(swift-example-app): run manual shielded sync before restarting ba…
QuantumExplorer b398e1f
fix(swift-example-app): don't tick shielded sync counter/timestamp on…
QuantumExplorer 7897f2d
fix(platform-wallet,swift-sdk): plumb cooldown-skip flag through FFI …
QuantumExplorer c2db315
fix(platform-wallet,swift-sdk): make shielded cooldown skip infallibl…
QuantumExplorer 6cfbdbf
refactor(platform-wallet): Phase 0 — shielded coordinator skeleton + …
QuantumExplorer 30bf425
refactor(platform-wallet,ffi,swift-sdk): Phase 1 — share network SQLi…
QuantumExplorer 000882c
refactor(platform-wallet): Phase 2a — coordinator owns network cooldo…
QuantumExplorer aeaa861
refactor(platform-wallet): Phase 2b — collapse N→1 SDK calls per shie…
QuantumExplorer b908651
feat(platform-wallet,ffi,swift-sdk): Phase 3 — single platform_wallet…
QuantumExplorer 1c56d31
refactor(platform-wallet): Phase 4a — remove dead per-wallet shielded…
QuantumExplorer 6043c35
refactor(platform-wallet): Phase 4c — collapse AccountState wrapper i…
QuantumExplorer a7dee49
refactor(platform-wallet): Phase 4d.1 — delete dead fallback paths in…
QuantumExplorer 18448c8
refactor(platform-wallet): Phase 4d.2 — drop now-orphaned per-wallet …
QuantumExplorer 27ad86d
refactor(platform-wallet): Phase 4b — lift restore_from_snapshot to c…
QuantumExplorer 2eaffb5
refactor(platform-wallet): Phase 4d.3 — delete ShieldedWallet; lift s…
QuantumExplorer 6e66e65
fix(platform-wallet): shielded spend witness + lifecycle regressions …
QuantumExplorer fd934ba
fix(platform-wallet): rebind is replace-not-merge; reject amount==0 i…
QuantumExplorer f9810d4
Merge branch 'v3.1-dev' into platform-wallet/shielded-spend-ffi
QuantumExplorer 76ad3b5
fix(platform-wallet): gate shielded tree appends by tree size, not wa…
QuantumExplorer 407e0da
feat(swift-example-app): aggregate shielded balance + notes-synced on…
QuantumExplorer e83524e
fix(platform-wallet): address shielded review feedback (Rust)
QuantumExplorer 7917a9f
fix(swift-sdk): address shielded review feedback (Swift)
QuantumExplorer 82cb6e5
fix(platform-wallet): harden shield flow — reuse rs-sdk nonce fetch +…
QuantumExplorer 64096d9
fix(swift-example-app): correct self-shield recipient hint; doc best-…
QuantumExplorer 0098206
fix(platform-wallet): surface structured balance error from shield pr…
QuantumExplorer 6f70314
fix(platform-wallet): shield Type 15/18 wait for proven execution (#3…
QuantumExplorer 8c80874
docs(platform-wallet): clarify sync watermark is exclusive next-index…
QuantumExplorer e768cdc
fix(platform-wallet): add shielded sync quiesce barrier for Clear/sto…
QuantumExplorer 8acd813
fix(platform-wallet): dispatch shielded completion event before clear…
QuantumExplorer 47c3f52
refactor(platform-wallet): move shielded Clear quiesce+clear into cle…
QuantumExplorer 3660842
fix(shielded): drop stale post-Clear completion event in host; correc…
QuantumExplorer b97ff6d
fix(swift-sdk): suppress trailing shielded completion event after sto…
QuantumExplorer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,325 @@ | ||
| //! FFI bindings for the shielded spend pipeline (transitions | ||
| //! 15/16/17/19 — shield, transfer, unshield, withdraw). | ||
| //! | ||
| //! Transitions 16/17/19 sign with the bound shielded wallet's | ||
| //! Orchard `SpendAuthorizingKey`, which lives on the | ||
| //! `OrchardKeySet` cached after [`platform_wallet_manager_bind_shielded`]. | ||
| //! No host-side `Signer<PlatformAddress>` is required — the host | ||
| //! only supplies the recipient + amount (+ core fee rate for | ||
| //! withdrawal) and the resulting Halo 2 proof + state transition | ||
| //! is built and broadcast on the Rust side. | ||
| //! | ||
| //! Transition 15 (`shield` — Platform→Shielded) additionally | ||
| //! takes a host-supplied `Signer<PlatformAddress>` because the | ||
| //! input addresses' ECDSA signatures live in the host keychain. | ||
| //! Per-input nonces are fetched from Platform inside | ||
| //! [`ShieldedWallet::shield`] before building. | ||
| //! | ||
| //! Type 18 (`shield_from_asset_lock` — Core L1→Shielded) lives on | ||
| //! [`ShieldedWallet`] but isn't wired here yet — it needs the | ||
| //! asset-lock proof + private key threaded through. | ||
| //! | ||
| //! Feature-gated behind `shielded`. The accompanying | ||
| //! [`platform_wallet_shielded_warm_up_prover`] entry-point is | ||
| //! also defined here so hosts can pre-build the Halo 2 proving | ||
| //! key on a background thread at app startup. | ||
| //! | ||
| //! [`ShieldedWallet`]: platform_wallet::wallet::shielded::ShieldedWallet | ||
| //! [`ShieldedWallet::shield`]: platform_wallet::wallet::shielded::ShieldedWallet::shield | ||
|
|
||
| use std::ffi::CStr; | ||
| use std::os::raw::c_char; | ||
|
|
||
| use platform_wallet::wallet::shielded::CachedOrchardProver; | ||
| use rs_sdk_ffi::{SignerHandle, VTableSigner}; | ||
|
|
||
| use crate::check_ptr; | ||
| use crate::error::*; | ||
| use crate::handle::*; | ||
| use crate::runtime::{block_on_worker, runtime}; | ||
|
|
||
| /// Kick off the Halo 2 proving-key build on a background tokio | ||
| /// worker if it hasn't been built yet. Returns immediately — | ||
| /// hosts can call this at app startup without blocking the UI | ||
| /// thread. Subsequent calls are cheap no-ops once the key is | ||
| /// cached. The first shielded send still pays the ~30 s build | ||
| /// cost only if it fires before the warm-up worker finishes; | ||
| /// `platform_wallet_shielded_prover_is_ready` reports whether | ||
| /// that's the case. | ||
| /// | ||
| /// Independent of any manager — the cache is a process-global | ||
| /// `OnceLock`. | ||
| #[no_mangle] | ||
| pub unsafe extern "C" fn platform_wallet_shielded_warm_up_prover() { | ||
| runtime().spawn_blocking(|| CachedOrchardProver::new().warm_up()); | ||
| } | ||
|
|
||
| /// Whether the Halo 2 proving key has already been built. | ||
| /// | ||
| /// Useful as a UI indicator ("preparing prover…") before the | ||
| /// first shielded send. `false` doesn't mean shielded sends will | ||
| /// fail — it just means the next one will pay the ~30s build | ||
| /// cost up front. | ||
| #[no_mangle] | ||
| pub unsafe extern "C" fn platform_wallet_shielded_prover_is_ready() -> bool { | ||
| CachedOrchardProver::new().is_ready() | ||
| } | ||
|
|
||
| /// Send a shielded → shielded transfer. | ||
| /// | ||
| /// Spends notes from `wallet_id`'s shielded balance and creates a | ||
| /// new note for `recipient_raw_43`. `amount` is in credits | ||
| /// (1 DASH = 1e11 credits). Errors if the wallet has no bound | ||
| /// shielded sub-wallet, no spendable notes, or insufficient | ||
| /// shielded balance to cover `amount + estimated_fee`. | ||
| /// | ||
| /// # Safety | ||
| /// - `wallet_id_bytes` must point to 32 readable bytes. | ||
| /// - `recipient_raw_43` must point to 43 readable bytes (the | ||
| /// recipient's raw Orchard payment address — same shape | ||
| /// `platform_wallet_manager_shielded_default_address` returns). | ||
| #[no_mangle] | ||
| pub unsafe extern "C" fn platform_wallet_manager_shielded_transfer( | ||
| handle: Handle, | ||
| wallet_id_bytes: *const u8, | ||
| recipient_raw_43: *const u8, | ||
| amount: u64, | ||
| ) -> PlatformWalletFFIResult { | ||
| check_ptr!(wallet_id_bytes); | ||
| check_ptr!(recipient_raw_43); | ||
|
|
||
| let mut wallet_id = [0u8; 32]; | ||
| std::ptr::copy_nonoverlapping(wallet_id_bytes, wallet_id.as_mut_ptr(), 32); | ||
| let mut recipient = [0u8; 43]; | ||
| std::ptr::copy_nonoverlapping(recipient_raw_43, recipient.as_mut_ptr(), 43); | ||
|
|
||
| let wallet = match resolve_wallet(handle, &wallet_id) { | ||
| Ok(w) => w, | ||
| Err(result) => return result, | ||
| }; | ||
|
|
||
| // Run the proof on a worker thread (8 MB stack). Halo 2 circuit | ||
| // synthesis recurses past the ~512 KB iOS dispatch-thread stack | ||
| // and crashes with EXC_BAD_ACCESS at the first | ||
| // `synthesize(... measure(pass))` call when polled on the | ||
| // calling thread. | ||
| let result = block_on_worker(async move { | ||
| let prover = CachedOrchardProver::new(); | ||
| wallet | ||
| .shielded_transfer_to(&recipient, amount, &prover) | ||
| .await | ||
| }); | ||
| if let Err(e) = result { | ||
| return PlatformWalletFFIResult::err( | ||
| PlatformWalletFFIResultCode::ErrorWalletOperation, | ||
| format!("shielded transfer failed: {e}"), | ||
| ); | ||
| } | ||
| PlatformWalletFFIResult::ok() | ||
| } | ||
|
|
||
| /// Unshield: spend shielded notes and send `amount` credits to a | ||
| /// platform address. | ||
| /// | ||
| /// `to_platform_addr_cstr` is the recipient as a NUL-terminated | ||
| /// UTF-8 bech32m string (e.g. `"dash1..."` on mainnet, | ||
| /// `"tdash1..."` on testnet). The Rust side parses it via | ||
| /// `PlatformAddress::from_bech32m_string` so hosts don't have to | ||
| /// hand-roll the bincode storage variant tag (`0x00`/`0x01`), | ||
| /// which differs from the bech32m payload's type byte | ||
| /// (`0xb0`/`0x80`). | ||
| /// | ||
| /// # Safety | ||
| /// - `wallet_id_bytes` must point to 32 readable bytes. | ||
| /// - `to_platform_addr_cstr` must be a valid NUL-terminated UTF-8 | ||
| /// C string for the duration of the call. | ||
| #[no_mangle] | ||
| pub unsafe extern "C" fn platform_wallet_manager_shielded_unshield( | ||
| handle: Handle, | ||
| wallet_id_bytes: *const u8, | ||
| to_platform_addr_cstr: *const c_char, | ||
| amount: u64, | ||
| ) -> PlatformWalletFFIResult { | ||
| check_ptr!(wallet_id_bytes); | ||
| check_ptr!(to_platform_addr_cstr); | ||
|
|
||
| let mut wallet_id = [0u8; 32]; | ||
| std::ptr::copy_nonoverlapping(wallet_id_bytes, wallet_id.as_mut_ptr(), 32); | ||
| let to_addr_str = match CStr::from_ptr(to_platform_addr_cstr).to_str() { | ||
| Ok(s) => s.to_string(), | ||
| Err(e) => { | ||
| return PlatformWalletFFIResult::err( | ||
| PlatformWalletFFIResultCode::ErrorUtf8Conversion, | ||
| format!("to_platform_addr is not valid UTF-8: {e}"), | ||
| ); | ||
| } | ||
| }; | ||
|
|
||
| let wallet = match resolve_wallet(handle, &wallet_id) { | ||
| Ok(w) => w, | ||
| Err(result) => return result, | ||
| }; | ||
|
|
||
| let result = block_on_worker(async move { | ||
| let prover = CachedOrchardProver::new(); | ||
| wallet | ||
| .shielded_unshield_to(&to_addr_str, amount, &prover) | ||
| .await | ||
| }); | ||
| if let Err(e) = result { | ||
| return PlatformWalletFFIResult::err( | ||
| PlatformWalletFFIResultCode::ErrorWalletOperation, | ||
| format!("shielded unshield failed: {e}"), | ||
| ); | ||
| } | ||
| PlatformWalletFFIResult::ok() | ||
| } | ||
|
|
||
| /// Withdraw: spend shielded notes and send `amount` credits to a | ||
| /// Core L1 address. `to_core_address_cstr` is the address as a | ||
| /// Base58Check NUL-terminated UTF-8 string (e.g. | ||
| /// `"yL...."` on testnet); the Rust side parses it and verifies | ||
| /// the network matches the wallet's. `core_fee_per_byte` is the | ||
| /// L1 fee rate in duffs/byte (`1` is the dashmate default). | ||
| /// | ||
| /// # Safety | ||
| /// - `wallet_id_bytes` must point to 32 readable bytes. | ||
| /// - `to_core_address_cstr` must be a valid NUL-terminated UTF-8 | ||
| /// C string for the duration of the call. | ||
| #[no_mangle] | ||
| pub unsafe extern "C" fn platform_wallet_manager_shielded_withdraw( | ||
| handle: Handle, | ||
| wallet_id_bytes: *const u8, | ||
| to_core_address_cstr: *const c_char, | ||
| amount: u64, | ||
| core_fee_per_byte: u32, | ||
| ) -> PlatformWalletFFIResult { | ||
| check_ptr!(wallet_id_bytes); | ||
| check_ptr!(to_core_address_cstr); | ||
|
|
||
| let mut wallet_id = [0u8; 32]; | ||
| std::ptr::copy_nonoverlapping(wallet_id_bytes, wallet_id.as_mut_ptr(), 32); | ||
| let to_core = match CStr::from_ptr(to_core_address_cstr).to_str() { | ||
| Ok(s) => s.to_string(), | ||
| Err(e) => { | ||
| return PlatformWalletFFIResult::err( | ||
| PlatformWalletFFIResultCode::ErrorUtf8Conversion, | ||
| format!("to_core_address is not valid UTF-8: {e}"), | ||
| ); | ||
| } | ||
| }; | ||
|
|
||
| let wallet = match resolve_wallet(handle, &wallet_id) { | ||
| Ok(w) => w, | ||
| Err(result) => return result, | ||
| }; | ||
|
|
||
| let result = block_on_worker(async move { | ||
| let prover = CachedOrchardProver::new(); | ||
| wallet | ||
| .shielded_withdraw_to(&to_core, amount, core_fee_per_byte, &prover) | ||
| .await | ||
| }); | ||
| if let Err(e) = result { | ||
| return PlatformWalletFFIResult::err( | ||
| PlatformWalletFFIResultCode::ErrorWalletOperation, | ||
| format!("shielded withdraw failed: {e}"), | ||
| ); | ||
| } | ||
| PlatformWalletFFIResult::ok() | ||
| } | ||
|
|
||
| /// Shield: spend credits from a Platform Payment account into | ||
| /// the bound shielded sub-wallet's pool. `account_index` selects | ||
| /// which Platform Payment account to draw from; the wallet | ||
| /// auto-selects input addresses in ascending derivation order | ||
| /// until the cumulative balance covers `amount + fee buffer`. | ||
| /// | ||
| /// `signer_address_handle` is a `*mut SignerHandle` produced by | ||
| /// `dash_sdk_signer_create_with_ctx` (typically Swift's | ||
| /// `KeychainSigner.handle`) — same shape | ||
| /// `platform_address_wallet_transfer` expects. The caller retains | ||
| /// ownership; this function does not destroy the handle. | ||
| /// | ||
| /// # Safety | ||
| /// - `wallet_id_bytes` must point to 32 readable bytes. | ||
| /// - `signer_address_handle` must be a valid, non-destroyed | ||
| /// `*mut SignerHandle` that outlives this call and points at a | ||
| /// `VTableSigner` with the callback variant (the native variant | ||
| /// doesn't satisfy `Signer<PlatformAddress>`). | ||
| #[no_mangle] | ||
| pub unsafe extern "C" fn platform_wallet_manager_shielded_shield( | ||
| handle: Handle, | ||
| wallet_id_bytes: *const u8, | ||
| account_index: u32, | ||
| amount: u64, | ||
| signer_address_handle: *mut SignerHandle, | ||
| ) -> PlatformWalletFFIResult { | ||
| check_ptr!(wallet_id_bytes); | ||
| check_ptr!(signer_address_handle); | ||
|
QuantumExplorer marked this conversation as resolved.
|
||
|
|
||
| let mut wallet_id = [0u8; 32]; | ||
| std::ptr::copy_nonoverlapping(wallet_id_bytes, wallet_id.as_mut_ptr(), 32); | ||
|
|
||
| let wallet = match resolve_wallet(handle, &wallet_id) { | ||
| Ok(w) => w, | ||
| Err(result) => return result, | ||
| }; | ||
|
|
||
| // SAFETY: the caller retains ownership of the signer handle | ||
| // and guarantees it outlives this call. We block until the | ||
| // worker future completes, so the `'static` lifetime we paint | ||
| // on the borrow does not actually outlive the host's handle. | ||
| // `VTableSigner` is `Send + Sync` per its `unsafe impl` in | ||
| // rs-sdk-ffi, so `&'static VTableSigner` is automatically | ||
| // `Send + 'static` — exactly what `block_on_worker` needs. | ||
| let address_signer: &'static VTableSigner = | ||
| std::mem::transmute::<&VTableSigner, &'static VTableSigner>( | ||
| &*(signer_address_handle as *const VTableSigner), | ||
| ); | ||
|
QuantumExplorer marked this conversation as resolved.
Outdated
QuantumExplorer marked this conversation as resolved.
Outdated
|
||
|
|
||
| // Run the proof on a worker thread (8 MB stack). Halo 2 circuit | ||
| // synthesis recurses past the ~512 KB iOS dispatch-thread stack | ||
| // and crashes with EXC_BAD_ACCESS at the first | ||
| // `synthesize(... measure(pass))` call when polled on the | ||
| // calling thread. | ||
| let result = block_on_worker(async move { | ||
| let prover = CachedOrchardProver::new(); | ||
| wallet | ||
| .shielded_shield_from_account(account_index, amount, address_signer, &prover) | ||
| .await | ||
| }); | ||
|
QuantumExplorer marked this conversation as resolved.
Outdated
|
||
| if let Err(e) = result { | ||
| return PlatformWalletFFIResult::err( | ||
| PlatformWalletFFIResultCode::ErrorWalletOperation, | ||
| format!("shielded shield failed: {e}"), | ||
| ); | ||
| } | ||
| PlatformWalletFFIResult::ok() | ||
| } | ||
|
|
||
| /// Resolve the wallet `Arc` for the given manager handle, or | ||
| /// produce a `PlatformWalletFFIResult` describing why we couldn't. | ||
| fn resolve_wallet( | ||
| handle: Handle, | ||
| wallet_id: &[u8; 32], | ||
| ) -> Result<std::sync::Arc<platform_wallet::PlatformWallet>, PlatformWalletFFIResult> { | ||
| let option = PLATFORM_WALLET_MANAGER_STORAGE.with_item(handle, |manager| { | ||
| runtime().block_on(manager.get_wallet(wallet_id)) | ||
| }); | ||
| let inner_option = match option { | ||
| Some(v) => v, | ||
| None => { | ||
| return Err(PlatformWalletFFIResult::err( | ||
| PlatformWalletFFIResultCode::ErrorInvalidHandle, | ||
| format!("invalid manager handle: {handle}"), | ||
| )); | ||
| } | ||
| }; | ||
| inner_option.ok_or_else(|| { | ||
| PlatformWalletFFIResult::err( | ||
| PlatformWalletFFIResultCode::ErrorWalletOperation, | ||
| format!("wallet not found: {}", hex::encode(wallet_id)), | ||
| ) | ||
| }) | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.