Skip to content

Commit 2464c8f

Browse files
Merge pull request #9 from yangby-cryptape/feature/dummy-can-rollback
feat: dummy service can rollback to an old client
2 parents 29a8710 + 5863d2c commit 2464c8f

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

prover/src/dummy_service.rs

+26-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use ckb_bitcoin_spv_verifier::{
88
utilities::{bitcoin::calculate_next_target, mmr},
99
};
1010

11-
use crate::result::Result;
11+
use crate::result::{Error, Result};
1212

1313
/// A dummy service for testing the SPV client cells's bootstrap and update.
1414
pub struct DummyService {
@@ -20,7 +20,11 @@ pub struct DummyService {
2020
impl DummyService {
2121
pub fn bootstrap(height: u32, header: core::Header) -> Result<Self> {
2222
if height % DIFFCHANGE_INTERVAL != 0 {
23-
panic!("bad height");
23+
let msg = format!(
24+
"bad bootstrap height, expected multiples of \
25+
{DIFFCHANGE_INTERVAL} but got {height}"
26+
);
27+
return Err(Error::other(msg));
2428
}
2529
let mut headers = HashMap::new();
2630
let store = mmr::lib::util::MemStore::default();
@@ -117,6 +121,26 @@ impl DummyService {
117121
.build())
118122
}
119123

124+
// The `prev_client` is not checked, since this is just a dummy service for testing purpose only.
125+
pub fn rollback_to(&mut self, prev_client: core::SpvClient) -> Result<()> {
126+
let prev_height = prev_client.headers_mmr_root.max_height;
127+
if prev_height < self.client.headers_mmr_root.min_height
128+
|| self.client.headers_mmr_root.max_height < prev_height
129+
{
130+
let msg = format!(
131+
"the previous header (height: {prev_height}) is not found (current: [{}, {}])",
132+
self.client.headers_mmr_root.min_height, self.client.headers_mmr_root.max_height
133+
);
134+
return Err(Error::other(msg));
135+
}
136+
let curr_height = self.client.headers_mmr_root.max_height;
137+
for h in (prev_height + 1)..=curr_height {
138+
self.headers.remove(&h);
139+
}
140+
self.client = prev_client;
141+
Ok(())
142+
}
143+
120144
pub fn tip_client(&self) -> core::SpvClient {
121145
self.client.clone()
122146
}

prover/src/result.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub enum Error {
1616
pub type Result<T> = ::std::result::Result<T, Error>;
1717

1818
impl Error {
19-
pub(crate) fn other<S: ToString>(arg: S) -> Self {
19+
pub fn other<S: ToString>(arg: S) -> Self {
2020
Self::Other(arg.to_string())
2121
}
2222
}

prover/src/tests/service.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,17 @@ fn test_spv_client(
6666
}
6767

6868
log::trace!("process {} headers at one time", headers.len());
69-
let update = service.update(mem::take(&mut headers)).unwrap();
69+
let update = if headers_group_size % 5 == 0 {
70+
let tmp_headers = mem::take(&mut headers);
71+
let _update = service.update(tmp_headers.clone()).unwrap();
72+
log::trace!("rollback to previous client (for test): {old_client}");
73+
service.rollback_to(old_client.unpack()).unwrap();
74+
log::trace!("process {} headers again", headers.len());
75+
service.update(tmp_headers)
76+
} else {
77+
service.update(mem::take(&mut headers))
78+
}
79+
.unwrap();
7080
if verify_tx_range.0 <= height + 1 && height <= verify_tx_range.1 {
7181
headers_group_size = 1;
7282
} else {

0 commit comments

Comments
 (0)