Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(db): Fix a sprout/history tree read panic in Zebra 1.4.0, which only happens before the 25.3.0 state upgrade completes #7972

Merged
merged 8 commits into from
Nov 22, 2023
Next Next commit
Avoid a race condition in the 25.3.0 state upgrade
  • Loading branch information
teor2345 authored Nov 21, 2023
commit 2116ab7ce680af6da9ed72ede0887823414778a2
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ pub fn run(
// Writing the trees back to the database automatically updates their format.
let mut batch = DiskWriteBatch::new();

// Delete the previous `Height` tip key format, which is now a duplicate.
// It's ok to do a full delete, because the trees are restored before the batch is written.
batch.delete_range_sprout_tree(upgrade_db, &Height(0), &MAX_ON_DISK_HEIGHT);
batch.delete_range_history_tree(upgrade_db, &Height(0), &MAX_ON_DISK_HEIGHT);

// Update the sprout tip key format in the database.
batch.update_sprout_tree(upgrade_db, &sprout_tip_tree);
batch.update_history_tree(upgrade_db, &history_tip_tree);
Expand All @@ -46,6 +41,24 @@ pub fn run(
.write_batch(batch)
.expect("updating tree key formats should always succeed");

// These deletes can be slow due to tombstones for previously deleted keys,
teor2345 marked this conversation as resolved.
Show resolved Hide resolved
// so we do it in a separate batch to avoid data races with syncing (#7961).
let mut batch = DiskWriteBatch::new();

// Delete the previous `Height` tip key format, which is now a duplicate.
// This doesn't delete the new `()` key format, because it serializes to an empty array.
batch.delete_range_sprout_tree(upgrade_db, &Height(0), &MAX_ON_DISK_HEIGHT);
batch.delete_range_history_tree(upgrade_db, &Height(0), &MAX_ON_DISK_HEIGHT);

// Return before we write if the upgrade is cancelled.
if !matches!(cancel_receiver.try_recv(), Err(mpsc::TryRecvError::Empty)) {
return Err(CancelFormatChange);
}

upgrade_db
.write_batch(batch)
.expect("cleaning up old tree key formats should always succeed");

Ok(())
}

Expand Down
Loading