Skip to content

gui: Rescan a restore from its creation date - #139

Open
BenWestgate wants to merge 5 commits into
gui-before-you-startfrom
restore-creation-date
Open

BenWestgate wants to merge 5 commits into
gui-before-you-startfrom
restore-creation-date

Conversation

@BenWestgate

@BenWestgate BenWestgate commented Oct 7, 2026 •

Copy link
Copy Markdown
Owner

Requested by Ben · project thread

Before: restore always imports with timestamp 0, so Bitcoin Core rescans from 2009. On a pruned node, as on Bails, those blocks are gone. Core imports the keys anyway, then fails the rescan, and codex32 reports "did not import every private descriptor" with the wallet already filled but missing its history. Also, wallets created by the GUI were not loaded at Core's next start. If the node kept syncing and pruned past the wallet's last sync, the wallet would no longer open ("You need to -reindex"). A Bails tester (PolymathBT) hit the second case on Tails with a wallet made during initial sync.

After: the restore page asks for the approximate creation date from the wallet record (YYYY-MM-DD, blank searches all history) and rescans from a day before it. Before any wallet is touched, and again right before the import, the library checks the node's prune height. If the rescan needs pruned blocks, it refuses on the same page and names the date the node still covers, so the user can enter a later date. New wallets are created with load_on_startup=true, so Core keeps them in step with the chain.

Stacked on #113 (its GUI budget is needed here). GitHub retargets this to bails-v1-pin once #113 merges.

How

  • _bitcoin_core.parse_creation_date: blank → 0. An ISO date that is already in the future at UTC+14 is refused. Otherwise the result is midnight UTC minus one day, which covers any time zone the record was written in.
  • BitcoinCore.check_history(timestamp): on a pruned node, read the time of the block at pruneheight (getblockstats … ["time"]) and refuse a timestamp less than a day after it. Core picks its start by the highest block time so far, and block times are not monotonic. Unclear output (a non-boolean pruned, a missing or negative pruneheight, a block time that is not a positive int) fails closed. initialize calls it as the last step before importdescriptors, so the CLI is covered too. The GUI's wallet_setup.verify calls it on the fingerprint page and again just before creating a restore wallet.
  • _fingerprint_page (restore only) gains the date row and keeps any BitcoinCoreError from that check on the page, as it already did for a fingerprint mismatch.
  • wallet_setup.create adds load_on_startup=true and refuses the wallet unless Core returns an object whose warnings is a list without "could not be updated". Invariant 9, docs/security/model.md and docs/developer/gui.md name the new argument.
  • Size budget (authorized by Ben on 2026-10-07 in the project thread): the library is at 5,019 logical lines, so its budget goes from 5,000 to 5,025 in tests/test_cli.py, AGENTS.md, docs/developer/api.md and gui.md. The GUI stays under its 2,050, at 2,049.

The "I have no wallet record" path still restores from 0. On a pruned node it now gets the clear refusal from initialize before import, instead of the half-filled wallet.

Validation

  • Full suite on Python 3.12, GTK 4.14 and libadwaita 1.5 under Xvfb passes, including the bip32 modules. CI is green on all 12 jobs.
  • New tests/test_gui_restore_date.py checks that the date reaches verify and _wallets, that a pruned-history refusal stays on the page, that a malformed date never reaches Core, and that a new wallet's record check asks for no date. New tests in tests/test_bitcoin_core.py cover date parsing (including tomorrow), the one-day margin, the check running right before import, and malformed pruning output. GUI tests cover the createwallet flag, the failed-setting warning, malformed results, and a wallet name that contains the warning text.
  • Ruff, format and mypy are clean.
  • Not run against a real pruned Core. Worth one restore on Tails with a recent date and one blank.

Written by Claude at Ben's request; needs review by a responsible human per docs/developer/AI_POLICY.md.

🤖 Generated with Claude Code

https://claude.ai/code/session_01T4RnVngvFFCw3U93bJWLTp

Restore always imported with timestamp 0, so Bitcoin Core rescanned
from 2009. A pruned node, as on Bails, no longer has those blocks:
Core imports the keys, then fails the rescan, leaving a filled wallet
without its history. A tester hit this on Tails.

The restore page now asks for the approximate creation date the
wallet record already carries and rescans from a day before it.
Before any wallet is touched, the library checks the node's prune
height and refuses a rescan it cannot do, naming the date it can.

New wallets are created with load_on_startup, so Core loads them at
every start and a pruned node never prunes past their last sync,
which is the "resync the whole blockchain" error the same tester
saw on a wallet made during initial sync.

The library is now 5,013 logical lines, so its budget goes from
5,000 to 5,025 in the test, AGENTS.md and the developer docs.

Refs BenWestgate/Bails#314
@BenWestgate
BenWestgate marked this pull request as ready for review October 7, 2026 21:05

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9e40c160c7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/codex32_gui/wallet_setup.py
Comment thread src/codex32/_bitcoin_core.py Outdated
Comment thread src/codex32/_bitcoin_core.py Outdated
Comment thread src/codex32/_bitcoin_core.py Outdated
Comment thread src/codex32_gui/wallet_setup.py
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-07T21:46:35.711540Z 75f5aed New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Codex review of the first commit found five holes.

The prune check ran before wallet selection, so a node pruning
during the unlock wait could outrun it; it now runs as the last
step before importdescriptors. Unclear pruning metadata no longer
reads as an unpruned node: pruned must be a boolean and, when
true, pruneheight an integer, or the import is refused.

Subtracting the safety day before the future check let tomorrow's
date through as today's midnight; the check now runs first, with
a UTC+14 margin so the earliest time zone can still enter its own
date.

Core only warns when it cannot save load_on_startup, so create
reads the result and refuses a wallet Core will not load again.
Invariant 9 and the wallet creation row now name that argument.

Refs BenWestgate/Bails#314

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b93cbe2993

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/codex32/_bitcoin_core.py Outdated
Comment thread src/codex32_gui/wallet_setup.py Outdated
Comment thread src/codex32_gui/wallet_setup.py Outdated
Comment thread src/codex32/_bitcoin_core.py Outdated
Comment thread docs/developer/api.md
Second Codex round on the restore date change.

pruned=1 compared equal to True and slipped past the boolean check,
so it now needs a real bool. Core picks the rescan start by the
highest block time seen so far, not the raw time at pruneheight,
and block times are not monotonic, so the margin past the pruned
blocks grows from four hours to a day; entered dates are only
day-accurate anyway.

A wallet named "could not be updated" read as a failed
load_on_startup, so only Core's warnings are searched. verify now
needs the rescan start, so a restore into a new wallet rechecks the
pruned history right before createwallet instead of skipping it.

Refs BenWestgate/Bails#314

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ae90e38e33

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/codex32/_bitcoin_core.py Outdated
Comment thread src/codex32_gui/wallet_setup.py
Third Codex round. getblockstats returning time=true counted as the
integer 1, so any real date passed the prune check without knowing
which blocks the node keeps. A block time is now trusted only as a
positive integer that is not a bool; anything else refuses the
import.

docs/developer/gui.md still listed the old createwallet shape, so
it now names load_on_startup=true and the refusal when Core cannot
save it.

Refs BenWestgate/Bails#314

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 75f5aedf8d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/codex32/_bitcoin_core.py
Comment thread src/codex32_gui/wallet_setup.py Outdated
Fourth Codex round. A negative pruneheight passed as an unpruned
node, and a createwallet result that was not an object, or whose
warnings were not a list, was accepted without knowing whether
Core saved load_on_startup. Both now refuse.

Refs BenWestgate/Bails#314
@chatgpt-codex-connector

This comment has been minimized.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants