Skip to content

Commit

Permalink
Merge pull request #41 from EthanYuan/fix-reorg-no-common-parent
Browse files Browse the repository at this point in the history
fix: add Reset operation when reorg fails
  • Loading branch information
EthanYuan authored Oct 16, 2024
2 parents 7f774ad + a107c09 commit 6e0831d
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 3 deletions.
30 changes: 30 additions & 0 deletions src/cli/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ use crate::{
utilities::{try_raise_fd_limit, value_parsers},
};

const SPV_RESET_TIP_OFFSET: u32 = 1200;

#[derive(Parser)]
pub struct Args {
#[clap(flatten)]
Expand Down Expand Up @@ -206,6 +208,34 @@ impl Args {
let (spv_client, spv_update) =
storage.generate_spv_client_and_spv_update(spv_tip_height, limit, flags)?;

let tx_hash =
self.reorg_spv_cells(&spv_service, input, spv_client, spv_update)?;

prev_tx_hash = Some(tx_hash);
}
SpvOperation::Reset(input) => {
let flags = input.info.get_flags()?;
if BitcoinChainType::Testnet != flags.into() {
let msg = "failed to reorg since no common parent between SPV instance and storage";
return Err(Error::other(msg));
}

log::info!(
"stale length: {:?}, clients count: {:?}",
input.stale.len(),
input.info.clients_count
);
log::info!("Try to reset SPV instance");

let spv_tip_height =
input.curr.client.headers_mmr_root.max_height - SPV_RESET_TIP_OFFSET;

let (spv_client, spv_update) = storage.generate_spv_client_and_spv_update(
spv_tip_height,
self.spv_headers_update_limit,
flags,
)?;

let tx_hash =
self.reorg_spv_cells(&spv_service, input, spv_client, spv_update)?;

Expand Down
17 changes: 14 additions & 3 deletions src/components/spv_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub struct SpvReorgInput {
pub enum SpvOperation {
Update(SpvUpdateInput),
Reorg(SpvReorgInput),
Reset(SpvReorgInput),
}

impl SpvService {
Expand Down Expand Up @@ -65,7 +66,12 @@ impl SpvService {
let stg_header_root_curr = packed_stg_header_root_curr.unpack();
log::warn!("[storage] header#{spv_height_curr}; mmr-root {stg_header_root_curr}");
let input = self.prepare_reorg_input(ins)?;
return Ok(SpvOperation::Reorg(input));
if input.info.clients_count as usize == input.stale.len() {
log::warn!("[onchain] all SPV clients are stale, resetting");
return Ok(SpvOperation::Reset(input));
} else {
return Ok(SpvOperation::Reorg(input));
}
}

let next_tip_client_id = ins.info.next_tip_client_id();
Expand Down Expand Up @@ -130,8 +136,13 @@ impl SpvService {
stale.push(cell.clone());
info.info.tip_client_id = info.prev_tip_client_id();
}
let msg = "failed to reorg since no common parent between SPV instance and storage";
Err(Error::other(msg))
log::warn!("failed to reorg since no common parent between SPV instance and storage");
let input = SpvReorgInput {
info: info.clone(),
curr: clients.get(&info.info.tip_client_id).unwrap().clone(),
stale,
};
Ok(input)
}

pub(crate) fn sync_storage(&self, batch_size: u32) -> Result<bool> {
Expand Down

0 comments on commit 6e0831d

Please sign in to comment.