diff --git a/src/components/api_service/mod.rs b/src/components/api_service/mod.rs index 5f916af..d14e857 100644 --- a/src/components/api_service/mod.rs +++ b/src/components/api_service/mod.rs @@ -90,7 +90,28 @@ impl SpvRpcImpl { } } - fn load_spv_instance(&self) -> Option { + fn load_spv_instance( + &self, + stg_tip_height: u32, + target_confirmed_height: u32, + ) -> Result> { + if let Some(spv_instance) = self.load_cache_spv_instance() { + let spv_client_cell = + spv_instance.find_best_spv_client_not_greater_than_height(stg_tip_height)?; + + let spv_header_root = &spv_client_cell.client.headers_mmr_root; + let spv_best_height = spv_header_root.max_height; + if spv_best_height < target_confirmed_height { + Ok(None) + } else { + Ok(Some(spv_instance)) + } + } else { + Ok(None) + } + } + + fn load_cache_spv_instance(&self) -> Option { if let Some(cached) = self .cached_spv_instance .read() @@ -244,9 +265,11 @@ impl SpvRpc for SpvRpcImpl { log::debug!(">>> try the cached SPV instance at first"); - let (mut spv_instance, from_cache) = if let Some(spv_instance) = self.load_spv_instance() { + let spv_instance = if let Ok(Some(spv_instance)) = + self.load_spv_instance(stg_tip_height, target_height + confirmations) + { log::debug!(">>> the cached SPV instance is {spv_instance}"); - (spv_instance, true) + spv_instance } else { log::debug!(">>> fetch SPV instance from remote since cached is not satisfied"); let spv_instance = tokio::task::block_in_place(|| -> RpcResult { @@ -266,10 +289,10 @@ impl SpvRpc for SpvRpcImpl { })?; log::debug!(">>> the fetched SPV instance is {spv_instance}"); self.update_spv_instance(spv_instance.clone()); - (spv_instance, false) + spv_instance }; - let mut spv_client_cell = spv_instance + let spv_client_cell = spv_instance .find_best_spv_client_not_greater_than_height(stg_tip_height) .map_err(|err| { let message = format!( @@ -285,43 +308,6 @@ impl SpvRpc for SpvRpcImpl { log::debug!(">>> the best SPV client is {}", spv_client_cell.client); - let spv_header_root = &spv_client_cell.client.headers_mmr_root; - let spv_best_height = spv_header_root.max_height; - if spv_best_height < target_height + confirmations && from_cache { - // Fetch SPV instance from network again - spv_instance = tokio::task::block_in_place(|| -> RpcResult { - spv.ckb_cli.find_spv_cells(spv_type_script).map_err(|err| { - let message = format!( - "failed to get SPV cell base on height {stg_tip_height} from chain" - ); - log::error!("{message} since {err}"); - RpcError { - code: RpcErrorCode::InternalError, - message, - data: None, - } - }) - })?; - log::debug!(">>> the fetched SPV instance is {spv_instance}"); - self.update_spv_instance(spv_instance.clone()); - - spv_client_cell = spv_instance - .find_best_spv_client_not_greater_than_height(stg_tip_height) - .map_err(|err| { - let message = format!( - "failed to get SPV cell base on height {stg_tip_height} from fetched data" - ); - log::error!("{message} since {err}"); - RpcError { - code: RpcErrorCode::InternalError, - message, - data: None, - } - })?; - - log::debug!(">>> the best SPV client is {}", spv_client_cell.client); - } - let spv_header_root = &spv_client_cell.client.headers_mmr_root; let spv_best_height = spv_header_root.max_height; if spv_best_height < target_height + confirmations {