From 35c994e541d49848136ebc887bd71d5f4e88207c Mon Sep 17 00:00:00 2001 From: EthanYuan Date: Mon, 20 May 2024 13:31:33 +0800 Subject: [PATCH 1/3] fix typo. --- src/components/api_service/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/api_service/mod.rs b/src/components/api_service/mod.rs index efaad52..e0355fa 100644 --- a/src/components/api_service/mod.rs +++ b/src/components/api_service/mod.rs @@ -314,7 +314,7 @@ impl SpvRpc for SpvRpcImpl { log::warn!("[onchain] header#{spv_best_height}; mmr-root {spv_header_root}"); let stg_header_root = packed_stg_header_root.unpack(); log::warn!("[storage] header#{spv_best_height}; mmr-root {stg_header_root}"); - let desc = "the SPV instance on chain is not unknown, reorg is required"; + let desc = "the SPV instance on chain is unknown, reorg is required"; return Err(ApiErrorCode::OnchainReorgRequired.with_desc(desc)); } From 0b90ec9b41f6514f45fe5eaccb043b7df4e54d00 Mon Sep 17 00:00:00 2001 From: EthanYuan Date: Mon, 20 May 2024 18:58:48 +0800 Subject: [PATCH 2/3] if cache did't hit, re-fetch spv instance from network. --- src/components/api_service/mod.rs | 68 ++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 15 deletions(-) diff --git a/src/components/api_service/mod.rs b/src/components/api_service/mod.rs index e0355fa..5f916af 100644 --- a/src/components/api_service/mod.rs +++ b/src/components/api_service/mod.rs @@ -244,30 +244,32 @@ impl SpvRpc for SpvRpcImpl { log::debug!(">>> try the cached SPV instance at first"); - let spv_instance = if let Some(spv_instance) = self.load_spv_instance() { + let (mut spv_instance, from_cache) = if let Some(spv_instance) = self.load_spv_instance() { log::debug!(">>> the cached SPV instance is {spv_instance}"); - spv_instance + (spv_instance, true) } else { log::debug!(">>> fetch SPV instance from remote since cached is not satisfied"); let 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, - } - }) + spv.ckb_cli + .find_spv_cells(spv_type_script.clone()) + .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_instance + (spv_instance, false) }; - let spv_client_cell = spv_instance + let mut spv_client_cell = spv_instance .find_best_spv_client_not_greater_than_height(stg_tip_height) .map_err(|err| { let message = format!( @@ -284,7 +286,43 @@ 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 { let desc = format!( From aa27734d569ca0ba3d29ccab4644f03d30d19f2c Mon Sep 17 00:00:00 2001 From: EthanYuan Date: Tue, 21 May 2024 19:06:05 +0800 Subject: [PATCH 3/3] refactoring: check the loaded cache in --- src/components/api_service/mod.rs | 95 +++++++++++++------------------ 1 file changed, 41 insertions(+), 54 deletions(-) diff --git a/src/components/api_service/mod.rs b/src/components/api_service/mod.rs index 5f916af..77680ea 100644 --- a/src/components/api_service/mod.rs +++ b/src/components/api_service/mod.rs @@ -90,7 +90,30 @@ impl SpvRpcImpl { } } - fn load_spv_instance(&self) -> Option { + fn load_spv_instance( + &self, + stg_tip_height: u32, + target_confirmed_height: u32, + ) -> Result> { + let spv_instance = match self.load_cache_spv_instance() { + Some(instance) => instance, + None => return Ok(None), + }; + + 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 { + return Ok(None); + } + + Ok(Some(spv_instance)) + } + + fn load_cache_spv_instance(&self) -> Option { if let Some(cached) = self .cached_spv_instance .read() @@ -244,32 +267,32 @@ 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 { - spv.ckb_cli - .find_spv_cells(spv_type_script.clone()) - .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, - } - }) + 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_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!( @@ -286,43 +309,7 @@ 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 { let desc = format!(