Skip to content

Commit 54457c2

Browse files
committed
fix: make the rollback atomic to the kind of database
1 parent 103ecf6 commit 54457c2

File tree

3 files changed

+44
-35
lines changed

3 files changed

+44
-35
lines changed

crates/fuel-core/src/combined_database.rs

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -318,38 +318,26 @@ impl CombinedDatabase {
318318
/// we leave it to the caller to decide how to bring them up to date.
319319
/// We don't rollback the on-chain database as it is the source of truth.
320320
/// The target height of the rollback is the latest height of the on-chain database.
321-
pub fn sync_aux_db_heights<S>(&self, shutdown_listener: &mut S) -> anyhow::Result<()>
322-
where
323-
S: ShutdownListener,
324-
{
325-
while !shutdown_listener.is_cancelled() {
326-
let on_chain_height = match self.on_chain().latest_height_from_metadata()? {
327-
Some(height) => height,
328-
None => break, // Exit loop if on-chain height is None
329-
};
330-
331-
let off_chain_height = self.off_chain().latest_height_from_metadata()?;
332-
let gas_price_height = self.gas_price().latest_height_from_metadata()?;
321+
pub fn sync_aux_db_heights(&self) -> anyhow::Result<()> {
322+
let on_chain_height = match self.on_chain().latest_height_from_metadata()? {
323+
Some(height) => height,
324+
None => return Ok(()), // Exit loop if on-chain height is None
325+
};
333326

334-
// Handle off-chain rollback if necessary
335-
if let Some(off_height) = off_chain_height {
336-
if off_height > on_chain_height {
337-
self.off_chain().rollback_last_block()?;
338-
}
339-
}
327+
let off_chain_height = self.off_chain().latest_height_from_metadata()?;
328+
let gas_price_height = self.gas_price().latest_height_from_metadata()?;
340329

341-
// Handle gas price rollback if necessary
342-
if let Some(gas_height) = gas_price_height {
343-
if gas_height > on_chain_height {
344-
self.gas_price().rollback_last_block()?;
345-
}
330+
// Handle off-chain rollback if necessary
331+
if let Some(off_height) = off_chain_height {
332+
if off_height > on_chain_height {
333+
self.off_chain().rollback_to(on_chain_height)?;
346334
}
335+
}
347336

348-
// If both off-chain and gas price heights are synced, break
349-
if off_chain_height.map_or(true, |h| h <= on_chain_height)
350-
&& gas_price_height.map_or(true, |h| h <= on_chain_height)
351-
{
352-
break;
337+
// Handle gas price rollback if necessary
338+
if let Some(gas_height) = gas_price_height {
339+
if gas_height > on_chain_height {
340+
self.gas_price().rollback_to(on_chain_height)?;
353341
}
354342
}
355343

crates/fuel-core/src/database.rs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -272,19 +272,40 @@ where
272272
impl<Description> Database<Description>
273273
where
274274
Description: DatabaseDescription,
275+
Description::Height: PartialOrd,
275276
{
276277
pub fn rollback_last_block(&self) -> StorageResult<()> {
278+
self.perform_rollback(None)
279+
}
280+
281+
pub fn rollback_to(&self, to_height: Description::Height) -> StorageResult<()> {
282+
self.perform_rollback(Some(to_height))
283+
}
284+
285+
fn perform_rollback(
286+
&self,
287+
to_height: Option<Description::Height>,
288+
) -> StorageResult<()> {
277289
let mut lock = self.inner_storage().stage.height.lock();
278-
let height = *lock;
290+
let current_height = *lock;
291+
292+
let current_height = current_height.ok_or_else(|| {
293+
anyhow::anyhow!("Database doesn't have a height to rollback")
294+
})?;
279295

280-
let Some(height) = height else {
296+
let to_height = to_height.unwrap_or(current_height);
297+
298+
if to_height > current_height {
281299
return Err(
282-
anyhow::anyhow!("Database doesn't have a height to rollback").into(),
300+
anyhow::anyhow!("Can't rollback to the height {:?} because it's greater than the current height {:?}",
301+
to_height, current_height).into(),
283302
);
284-
};
285-
self.inner_storage().data.rollback_block_to(&height)?;
286-
let new_height = height.rollback_height();
303+
}
304+
305+
self.inner_storage().data.rollback_block_to(&to_height)?;
306+
let new_height = to_height.rollback_height();
287307
*lock = new_height;
308+
288309
tracing::info!(
289310
"Rollback of the {} to the height {:?} was successful",
290311
Description::name(),

crates/fuel-core/src/service.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ impl FuelService {
134134

135135
// initialize sub services
136136
tracing::info!("Initializing sub services");
137-
database.sync_aux_db_heights(shutdown_listener)?;
137+
database.sync_aux_db_heights()?;
138138
let (services, shared) = sub_services::init_sub_services(&config, database)?;
139139

140140
let sub_services = Arc::new(services);

0 commit comments

Comments
 (0)