-
Notifications
You must be signed in to change notification settings - Fork 54
fix(platform-wallet): spv error propagation #3810
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
base: v3.1-dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -97,9 +97,9 @@ impl SpvRuntime { | |||||||||||||||||
| tx: &Transaction, | ||||||||||||||||||
| ) -> Result<(), PlatformWalletError> { | ||||||||||||||||||
| let client_guard = self.client.read().await; | ||||||||||||||||||
| let client = client_guard | ||||||||||||||||||
| .as_ref() | ||||||||||||||||||
| .ok_or(PlatformWalletError::SpvNotRunning)?; | ||||||||||||||||||
| let client = client_guard.as_ref().ok_or(PlatformWalletError::SpvError( | ||||||||||||||||||
| "SPV Client not started".to_string(), | ||||||||||||||||||
| ))?; | ||||||||||||||||||
|
|
||||||||||||||||||
| client | ||||||||||||||||||
| .broadcast_transaction(tx) | ||||||||||||||||||
|
|
@@ -117,9 +117,9 @@ impl SpvRuntime { | |||||||||||||||||
| height: u32, | ||||||||||||||||||
| ) -> Result<[u8; 48], PlatformWalletError> { | ||||||||||||||||||
| let client_guard = self.client.read().await; | ||||||||||||||||||
| let client = client_guard | ||||||||||||||||||
| .as_ref() | ||||||||||||||||||
| .ok_or(PlatformWalletError::SpvNotRunning)?; | ||||||||||||||||||
| let client = client_guard.as_ref().ok_or(PlatformWalletError::SpvError( | ||||||||||||||||||
| "SPV Client not started".to_string(), | ||||||||||||||||||
| ))?; | ||||||||||||||||||
|
|
||||||||||||||||||
| let llmq_type = LLMQType::from(quorum_type as u8); | ||||||||||||||||||
| let qh = QuorumHash::from_byte_array(quorum_hash).reverse(); | ||||||||||||||||||
|
|
@@ -132,16 +132,16 @@ impl SpvRuntime { | |||||||||||||||||
| Ok(*quorum.quorum_entry.quorum_public_key.as_ref()) | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| /// Run the SPV sync loop until calling [`stop`]. This blocks the current thread. | ||||||||||||||||||
| pub async fn run(&self, config: ClientConfig) -> Result<(), PlatformWalletError> { | ||||||||||||||||||
| tracing::info!("SpvRuntime::run() starting client..."); | ||||||||||||||||||
| self.start(config).await?; | ||||||||||||||||||
| tracing::info!("SpvRuntime::run() client started, entering sync loop"); | ||||||||||||||||||
|
|
||||||||||||||||||
| /// Drive the sync loop of an already-[`start`]ed client until [`stop`] | ||||||||||||||||||
| /// is called. | ||||||||||||||||||
| /// [`spawn_run_loop`](Self::spawn_run_loop). | ||||||||||||||||||
| async fn run(&self) -> Result<(), PlatformWalletError> { | ||||||||||||||||||
|
Comment on lines
+135
to
+138
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💬 Nitpick: Malformed rustdoc on The doc comment ends with a standalone
Suggested change
source: ['claude'] |
||||||||||||||||||
| let client_guard = self.client.read().await; | ||||||||||||||||||
| let client = client_guard | ||||||||||||||||||
| .as_ref() | ||||||||||||||||||
| .ok_or(PlatformWalletError::SpvNotRunning)? | ||||||||||||||||||
| .ok_or(PlatformWalletError::SpvError( | ||||||||||||||||||
| "SPV Client not started".to_string(), | ||||||||||||||||||
| ))? | ||||||||||||||||||
| .clone(); | ||||||||||||||||||
| drop(client_guard); | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
@@ -189,10 +189,11 @@ impl SpvRuntime { | |||||||||||||||||
| stop_result | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| /// Spawn `run()` on the current tokio runtime and return immediately. | ||||||||||||||||||
| /// Spawn the sync loop of an already-[`start`]ed client on the current | ||||||||||||||||||
| /// tokio runtime and return immediately. | ||||||||||||||||||
| /// | ||||||||||||||||||
| /// Call [`stop`] to stop it | ||||||||||||||||||
| pub fn spawn_in_background(self: &Arc<Self>, config: ClientConfig) { | ||||||||||||||||||
| pub fn spawn_run_loop(self: &Arc<Self>) { | ||||||||||||||||||
| { | ||||||||||||||||||
| let existing = self.task.lock().expect("spv task mutex poisoned"); | ||||||||||||||||||
| if existing.is_some() { | ||||||||||||||||||
|
|
@@ -206,8 +207,8 @@ impl SpvRuntime { | |||||||||||||||||
| let this = Arc::clone(self); | ||||||||||||||||||
|
|
||||||||||||||||||
| let handle = tokio::spawn(async move { | ||||||||||||||||||
| if let Err(e) = this.run(config).await { | ||||||||||||||||||
| tracing::warn!("SpvRuntime background run exited with error: {}", e); | ||||||||||||||||||
| if let Err(e) = this.run().await { | ||||||||||||||||||
| tracing::warn!("SpvRuntime background run loop exited with error: {}", e); | ||||||||||||||||||
| } | ||||||||||||||||||
| }); | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
@@ -252,9 +253,10 @@ impl SpvRuntime { | |||||||||||||||||
| /// The SPV client must be running to perform this operation. | ||||||||||||||||||
| pub async fn clear_storage(&self) -> Result<(), PlatformWalletError> { | ||||||||||||||||||
| let client_guard = self.client.read().await; | ||||||||||||||||||
| let client = client_guard | ||||||||||||||||||
| .as_ref() | ||||||||||||||||||
| .ok_or(PlatformWalletError::SpvNotRunning)?; | ||||||||||||||||||
| let client = client_guard.as_ref().ok_or(PlatformWalletError::SpvError( | ||||||||||||||||||
| "SPV Client not started".to_string(), | ||||||||||||||||||
| ))?; | ||||||||||||||||||
|
|
||||||||||||||||||
| client | ||||||||||||||||||
| .clear_storage() | ||||||||||||||||||
| .await | ||||||||||||||||||
|
|
@@ -266,9 +268,10 @@ impl SpvRuntime { | |||||||||||||||||
| /// The network cannot be changed on a running client. | ||||||||||||||||||
| pub async fn update_config(&self, config: ClientConfig) -> Result<(), PlatformWalletError> { | ||||||||||||||||||
| let client_guard = self.client.read().await; | ||||||||||||||||||
| let client = client_guard | ||||||||||||||||||
| .as_ref() | ||||||||||||||||||
| .ok_or(PlatformWalletError::SpvNotRunning)?; | ||||||||||||||||||
| let client = client_guard.as_ref().ok_or(PlatformWalletError::SpvError( | ||||||||||||||||||
| "SPV Client not started".to_string(), | ||||||||||||||||||
| ))?; | ||||||||||||||||||
|
|
||||||||||||||||||
| client | ||||||||||||||||||
| .update_config(config) | ||||||||||||||||||
| .await | ||||||||||||||||||
|
|
||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 Suggestion: Poll
spv().start(config)on the worker runtime, not the FFI caller threadruntime().block_on(manager.spv().start(config))polls the new (substantial) startup future —PeerNetworkManager::new,DiskStorageManager::new,DashSpvClient::new— directly on the foreign caller's thread.packages/rs-platform-wallet-ffi/src/runtime.rsexplicitly documents that iOS dispatch/concurrency threads have ~512 KB stacks and that async FFI work should useblock_on_worker, which parks the caller on a oneshot and runs the future on the 8 MB-stack worker. The rest of this crate consistently follows that pattern. Previously this work happened insidetokio::spawnon the runtime; the PR's new ordering reintroduces the exact stack-sensitive pattern the runtime module was built to avoid. Switch toblock_on_workerusing theArc<SpvRuntime>so the future isSend + 'static.source: ['codex']