Skip to content

fix(consensus-db): tolerate a missing data table during migration - #392

Closed
Dusk1e wants to merge 1 commit into
circlefin:mainfrom
Dusk1e:fix/consensus-db-migration-missing-table
Closed

Dusk1e wants to merge 1 commit into
circlefin:mainfrom
Dusk1e:fix/consensus-db-migration-missing-table

Conversation

@Dusk1e

@Dusk1e Dusk1e commented Sep 12, 2026

Copy link
Copy Markdown

migrate_certificates and migrate_decided_blocks open their table inside a read transaction:

let mut next_height = if let Some((min_height, _)) = self
    .db
    .begin_read()?
    .open_table(CERTIFICATES_TABLE)?
    .first()?

open_table on a read transaction returns TableDoesNotExist when the table isn't there. The other two table migrations, migrate_undecided_blocks and migrate_pending_parts, open theirs inside a write transaction, which creates it, so those already treat a missing table as an empty one. The first two abort the whole migration instead.

A datadir can reach the migration before the tables exist. Db::new migrates, and only afterwards does Store::open call create_tables. needs_migration records "file exists, no schema version" as v0 and asks for a migration, and redb::Database::create makes the file before that version is ever written — so a first start interrupted between the two leaves a database that every later start rejects with:

Table(TableDoesNotExist("certificates"))

db migrate fails the same way, --dry-run included, since preview_migrate runs the same functions.

The change treats a missing table as empty in both, which is what the other two already do. The added test fails on main with TableDoesNotExist("certificates") and passes with the change; the rest of the crate's suite (107 tests) still passes.

migrate_certificates and migrate_decided_blocks open their table inside a read
transaction, which fails with TableDoesNotExist when the table is not there.
migrate_undecided_blocks and migrate_pending_parts open theirs inside a write
transaction, which creates it, so those two already treat a missing table as an
empty one.

A datadir can reach the migration before the tables exist. Db::new migrates, and
only afterwards does Store::open call create_tables; needs_migration records
"file exists, no schema version" as v0 and asks for a migration, and redb makes
the file before that version is written. A first start interrupted in between
leaves a database that every later start rejects, and `db migrate` rejects it
the same way, dry run included.

Treat a missing table as empty in both, matching the other two.
@ZhiyuCircle

Copy link
Copy Markdown
Contributor

Hi @Dusk1e,

Thank you for your interest in contributing to Arc Node, and apologies for the delay in getting back to this PR.

We're closing out the pull request backlog that predates our current contribution policy. This PR is being closed because it does not reference a GitHub issue. All PRs must reference an existing issue using the format Closes: #XXX, and the author must be assigned to that issue before the PR is opened.

This is not a judgement on the change itself. If you'd still like to land it:

  1. Open an issue describing the problem, or find the existing one
  2. Comment on the issue requesting assignment, and wait for maintainer approval
  3. Open a fresh PR once you have been assigned

Please see CONTRIBUTING.md for details. Thanks again for taking the time to contribute.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants