Skip to content

wallet: avoid rescans under assumed-valid blocks#23997

Merged
achow101 merged 1 commit into
bitcoin:masterfrom
jamesob:2022-01-snapshot-rescans
Jul 18, 2022
Merged

wallet: avoid rescans under assumed-valid blocks#23997
achow101 merged 1 commit into
bitcoin:masterfrom
jamesob:2022-01-snapshot-rescans

Conversation

@jamesob

@jamesob jamesob commented Jan 7, 2022

Copy link
Copy Markdown
Contributor

This is part of the assumeutxo project (parent PR: #15606)


Refuse to load a wallet if it requires a rescan lower than the height of assumed-valid blocks.

Of course in live code right now, BLOCK_ASSUMED_VALID block index entries don't exist since they're a unique flag introduced by the use of UTXO snapshots, so this is prophylactic code exercised only by unittests.

@fanquake fanquake added the Wallet label Jan 7, 2022
@luke-jr

luke-jr commented Jan 7, 2022

Copy link
Copy Markdown
Member

Why would this make sense? If any blocks are assumed valid, not only them, but also every block afterward is also dubious.

The correct behaviour would seem to be to work normally, and refuse to show anything as confirmed until all blocks it depends on have been verified valid.

@Sjors

Sjors commented Jan 7, 2022

Copy link
Copy Markdown
Member

@luke-jr IIUC this PR deals with a situation where a rescan is physically impossible, whereas you're referring to whether it's safe.

We could add a warning when a user tries to load any wallet before the background sync is finished. We also need some way to warn the user for this when they create a new wallet. Showing everything as unconfirmed would be one approach, but maybe it's better to show the transactions as confirmed, but still have a general warning about the background sync. Unconfirmed transactions might give users the wrong idea about e.g. the ability to fee bump or abandon them.

@jamesob CI is not happy

@jamesob jamesob force-pushed the 2022-01-snapshot-rescans branch from 621a2de to eef3e58 Compare January 7, 2022 15:29
@jamesob

jamesob commented Jan 7, 2022

Copy link
Copy Markdown
Contributor Author

Why would this make sense?

As @Sjors notes, the rescan is physically impossible if a block index entry is marked BLOCK_ASSUMED_VALID because it lacks the block data on disk, similar to pruning.

@achow101

Copy link
Copy Markdown
Member

Since this check is basically the same check that pruning does, why don't we just make the pruning check always happen and adjust the error message to be more generic? It would really just be removing the if (chain.havePruned()) condition, and there would be no need to add getLowestBlockDataHeight.

@DrahtBot

DrahtBot commented Jan 14, 2022

Copy link
Copy Markdown
Contributor

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #25494 (indexes: Stop using node internal types by ryanofsky)
  • #24230 (indexes: Stop using node internal types and locking cs_main, improve sync logic by ryanofsky)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@jamesob jamesob force-pushed the 2022-01-snapshot-rescans branch from eef3e58 to 99881c2 Compare January 15, 2022 02:55
@jamesob

jamesob commented Jan 15, 2022

Copy link
Copy Markdown
Contributor Author

Since this check is basically the same check that pruning does, why don't we just make the pruning check always happen and adjust the error message to be more generic? It would really just be removing the if (chain.havePruned()) condition, and there would be no need to add getLowestBlockDataHeight.

Good suggestion. I've made this change (though still distinguish the two cases in the error message) and have improved the test.

@jamesob jamesob force-pushed the 2022-01-snapshot-rescans branch from 99881c2 to 4c25084 Compare January 15, 2022 03:11
@DrahtBot DrahtBot mentioned this pull request Jan 15, 2022
18 tasks
@jamesob jamesob force-pushed the 2022-01-snapshot-rescans branch from 4c25084 to 7d51ad9 Compare January 15, 2022 16:45
@Sjors

Sjors commented Jan 16, 2022

Copy link
Copy Markdown
Member

2ab917a26266ed2ce0265f3e81c7e9184eabfac4 deserves it's own PR. It's also what's causing the tests to fail, and nodes to crash when you shut them down after creating a new wallet(?).

@jamesob

jamesob commented Jan 18, 2022

Copy link
Copy Markdown
Contributor Author

2ab917a deserves it's own PR. It's also what's causing the tests to fail, and nodes to crash when you shut them down after creating a new wallet(?).

Yep... I'm going to avoid attempting that fix here and instead scale the tests back.

@jamesob

jamesob commented Feb 11, 2022

Copy link
Copy Markdown
Contributor Author

I've removed the test from this change since, as far as I can tell, it's impossible to unittest this behavior without leaking the wallet database. This happens because CWallet::Create eats the database unique_ptr into a shared_ptr and then doesn't return the shared_ptr upon failure.

Comment thread src/wallet/wallet.cpp Outdated
Refuse to load a wallet if it requires a rescan lower than the height of
an unvalidated snapshot we're running -- in more general terms, if we
don't have data for the blocks.
@jamesob jamesob force-pushed the 2022-01-snapshot-rescans branch from 9bf1245 to 817326a Compare February 16, 2022 01:50
@achow101

Copy link
Copy Markdown
Member

ACK 817326a

@jamesob

jamesob commented Jun 6, 2022

Copy link
Copy Markdown
Contributor Author

Ready for merge?

@maflcko maflcko left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

left a question

Comment thread src/node/interfaces.cpp
Comment thread src/wallet/wallet.cpp
_(
"Assumed-valid: last wallet synchronisation goes beyond "
"available block data. You need to wait for the background "
"validation chain to download more blocks.") :

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This doesn't seem actionable for the user? The user would have to disable the wallet, then restart without wallet, then wait for the background chainstate to catch up, then start again? And with pruning enabled they'd just trade this error with the other one, no?

I guess the only way this could happen is if the users loads a wallet from another datadir/backup? In that case it doesn't seem too bad to just do a full rescan along with the background download?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This error won't stop the node though, right? Won't the background validation process just continue after the loadwallet call has failed via this error? Maybe @achow101 @ryanofsky can clarify.

@maflcko maflcko Jun 7, 2022

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I haven't tested this, but this seems like a fatal error. Or rather, if it wasn't a fatal error, it should be one, based on the wording:

error = _("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)");

(I guess it would be nice if someone added a test for the prune case).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

At least in these cases, the error is not fatal AFAICT:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Fair enough. (I'd still prefer if the wallet locator was automatically reset further back instead of asking the user to "wait manually".)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This would be fatal if the wallet was loaded on start. But via loadwallet or through the GUI, it will just return an error.

@jonatack jonatack left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Concept ACK

Comment thread src/node/interfaces.cpp
Comment thread src/wallet/wallet.cpp
Comment thread src/wallet/wallet.cpp
// but fail the rescan with a generic error.
error = _("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)");

error = chain.hasAssumedValidChain() ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Shouldn't the prune error overwrite the au error?

If prune is enabled, downloading au data won't help, as it will be pruned.

Suggested change
error = chain.hasAssumedValidChain() ?
error = chain.havePruned() ? "prune err" : "au err";

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah, this is a good point.

@ryanofsky ryanofsky Jun 14, 2022

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Agree with all of Marco's points here and think this should be updated

  • If havePrune and hasAssumedValidChain are both true, better to show havePrune error message
  • Assumed-valid error message is vague and not very actionable. Would suggest "Error loading wallet. Wallet requires blocks to be downloaded, and software does not currently support loading wallets while blocks are being downloaded out of order though assumeutxo snapshots. Wallet should be able to load successfully after node sync reaches height {block_height}"

@ryanofsky ryanofsky left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code review ACK 817326a. This seems like the simplest change we can make to avoid wallet problems when an assumeutxo snapshot is loaded.

There are other improvements that could be made to the wallet after this to make it work better with assumeutxo snapshot loading. Wallet could rescan from the background chain and scan background blocks as they are downloaded. With the attachChain method in #24230, this would not require any wallet-specific assumeutxo code. Wallet could just passively receive block connected notifications it needs in order

Comment thread src/wallet/wallet.cpp
// but fail the rescan with a generic error.
error = _("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)");

error = chain.hasAssumedValidChain() ?

@ryanofsky ryanofsky Jun 14, 2022

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Agree with all of Marco's points here and think this should be updated

  • If havePrune and hasAssumedValidChain are both true, better to show havePrune error message
  • Assumed-valid error message is vague and not very actionable. Would suggest "Error loading wallet. Wallet requires blocks to be downloaded, and software does not currently support loading wallets while blocks are being downloaded out of order though assumeutxo snapshots. Wallet should be able to load successfully after node sync reaches height {block_height}"

@achow101

achow101 commented Jun 14, 2022

Copy link
Copy Markdown
Member

Thinking on this again, I'm actually not sure that there even needs to be an error. With assume utxo, we are background downloading and verifying the blocks. If the locator is ahead of those blocks, then we will get those blocks eventually and they will be scanned. Conversely, pruning means that those blocks are deleted and we won't be retrieving them automatically.

A big difference between assume utxo and pruning is that with assume utxo we will know the utxos for the wallet, whereas with just pruning we don't. So refusing to load wallets when only pruned makes sense, as funds may be missing, but with assume utxo, I don't think that holds. We can retrieve the utxos from the snapshot and blocks following. If it's good enough for validation, it should be good enough for the wallet. Of course we need to change the wallet to track utxos rather than full transactions, but that's a different problem.

@ryanofsky

ryanofsky commented Jun 15, 2022

Copy link
Copy Markdown
Contributor

Thinking on this again, I'm actually not sure that there even needs to be an error. With assume utxo, we are background downloading and verifying the blocks.

I think because of a assumeutxo implementation detail the wallet won't actually be notified about these blocks and won't scan them.

But even if the wallet were notified about background blocks I assume it still need to be an error if any blocks are missing at startup because wallet expects to scan blocks in order. So even if background blocks were processed and added incoming transactions to the wallet, later blocks would still need to be rescanned so wallet could see if those transactions were spent (EDIT: this isn't really the right reason, but I think there are cases where wallet needs to scan blocks in order).

An alternative to this PR would make the wallet receive background block notifications and rescan more smartly, but just showing an error like this PR does is the simplest possible behavior that is not buggy

@jamesob

jamesob commented Jul 18, 2022

Copy link
Copy Markdown
Contributor Author

I agree with @ryanofsky's assessment - this seems like the simplest change to avoid broken wallet behavior. I think anything beyond that is going to be a much more substantial change.

Is there anything else holding this PR up from further review/merge?

@achow101 achow101 merged commit 8d4a058 into bitcoin:master Jul 18, 2022
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Jul 18, 2022
817326a wallet: avoid rescans if under the snapshot (James O'Beirne)

Pull request description:

  This is part of the [assumeutxo project](https://github.com/bitcoin/bitcoin/projects/11) (parent PR: bitcoin#15606)

  ---

  Refuse to load a wallet if it requires a rescan lower than the height of assumed-valid blocks.

  Of course in live code right now, `BLOCK_ASSUMED_VALID` block index entries don't exist since they're a unique flag introduced by the use of UTXO snapshots, so this is prophylactic code exercised only by unittests.

ACKs for top commit:
  achow101:
    ACK 817326a
  ryanofsky:
    Code review ACK 817326a. This seems like the simplest change we can make to avoid wallet problems when an assumeutxo snapshot is loaded.

Tree-SHA512: cfa44b2eb33d1818d30df45210d0dde1e9b78cc9b7c88cb985054dc28427bba9e0905debe4196065d1d3a5ce7bca7e605e629d5ce5f0225b25395746e6d3d596
@maflcko

maflcko commented Jul 19, 2022

Copy link
Copy Markdown
Member

I think you forgot to toggle the boolean check? Currently it seems the wrong way around, as commented in #23997 (comment)

@jamesob

jamesob commented Jul 19, 2022

Copy link
Copy Markdown
Contributor Author

I think you forgot to toggle the boolean check? Currently it seems the wrong way around, as commented in #23997 (comment)

Argh, my mistake. I'll file a follow-up.

@maflcko

maflcko commented Aug 2, 2022

Copy link
Copy Markdown
Member

Argh, my mistake. I'll file a follow-up.

Let us know if you don't, so that someone else can pick this up.

@ryanofsky

Copy link
Copy Markdown
Contributor

re: #23997 (comment)

Argh, my mistake. I'll file a follow-up.

@jamesob, did you get around to this? It seems like this is still applicable to current code

@jamesob

jamesob commented Oct 7, 2022

Copy link
Copy Markdown
Contributor Author

@ryanofsky @MarcoFalke I'm sorry about that guys, PR is finally up: #26282

fanquake added a commit to bitcoin-core/gui that referenced this pull request Oct 10, 2022
… over assumedvalid

1c36baf wallet: have prune error take precedence over assumedvalid (James O'Beirne)

Pull request description:

  Fixes bitcoin/bitcoin#23997 (comment).

  From Russ Yanofsky:

  > Agree with all of Marco's points here and think this should be updated
  >
  > If havePrune and hasAssumedValidChain are both true, better to show havePrune error message.  Assumed-valid error message is vague and not very actionable.  Would suggest "Error loading wallet. Wallet requires blocks to be downloaded, and software does not currently support loading wallets while blocks are being downloaded out of order though assumeutxo snapshots. Wallet should be able to load successfully after node sync reaches height {block_height}"

ACKs for top commit:
  MarcoFalke:
    ACK 1c36baf
  aureleoules:
    ACK 1c36baf

Tree-SHA512: bfb0024bb962525cbbd392ade3c0331a8b0525e7f2f2ab52b2dbb9b6dd6311070d85ecb762a7689db84a30991971865698ab6fec187206e6a92133790c5a91dc
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Oct 10, 2022
…sumedvalid

1c36baf wallet: have prune error take precedence over assumedvalid (James O'Beirne)

Pull request description:

  Fixes bitcoin#23997 (comment).

  From Russ Yanofsky:

  > Agree with all of Marco's points here and think this should be updated
  >
  > If havePrune and hasAssumedValidChain are both true, better to show havePrune error message.  Assumed-valid error message is vague and not very actionable.  Would suggest "Error loading wallet. Wallet requires blocks to be downloaded, and software does not currently support loading wallets while blocks are being downloaded out of order though assumeutxo snapshots. Wallet should be able to load successfully after node sync reaches height {block_height}"

ACKs for top commit:
  MarcoFalke:
    ACK 1c36baf
  aureleoules:
    ACK 1c36baf

Tree-SHA512: bfb0024bb962525cbbd392ade3c0331a8b0525e7f2f2ab52b2dbb9b6dd6311070d85ecb762a7689db84a30991971865698ab6fec187206e6a92133790c5a91dc
@bitcoin bitcoin locked and limited conversation to collaborators Aug 7, 2024
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Oct 25, 2024
…sumedvalid

1c36baf wallet: have prune error take precedence over assumedvalid (James O'Beirne)

Pull request description:

  Fixes bitcoin#23997 (comment).

  From Russ Yanofsky:

  > Agree with all of Marco's points here and think this should be updated
  >
  > If havePrune and hasAssumedValidChain are both true, better to show havePrune error message.  Assumed-valid error message is vague and not very actionable.  Would suggest "Error loading wallet. Wallet requires blocks to be downloaded, and software does not currently support loading wallets while blocks are being downloaded out of order though assumeutxo snapshots. Wallet should be able to load successfully after node sync reaches height {block_height}"

ACKs for top commit:
  MarcoFalke:
    ACK 1c36baf
  aureleoules:
    ACK 1c36baf

Tree-SHA512: bfb0024bb962525cbbd392ade3c0331a8b0525e7f2f2ab52b2dbb9b6dd6311070d85ecb762a7689db84a30991971865698ab6fec187206e6a92133790c5a91dc
Kino1994 pushed a commit to Kino1994/bitcoin-full-history that referenced this pull request Jun 28, 2026
… over assumedvalid

712a4d5 wallet: have prune error take precedence over assumedvalid (James O'Beirne)

Pull request description:

  Fixes bitcoin/bitcoin#23997 (comment).

  From Russ Yanofsky:

  > Agree with all of Marco's points here and think this should be updated
  >
  > If havePrune and hasAssumedValidChain are both true, better to show havePrune error message.  Assumed-valid error message is vague and not very actionable.  Would suggest "Error loading wallet. Wallet requires blocks to be downloaded, and software does not currently support loading wallets while blocks are being downloaded out of order though assumeutxo snapshots. Wallet should be able to load successfully after node sync reaches height {block_height}"

ACKs for top commit:
  MarcoFalke:
    ACK 712a4d5
  aureleoules:
    ACK 712a4d5

Tree-SHA512: bfb0024bb962525cbbd392ade3c0331a8b0525e7f2f2ab52b2dbb9b6dd6311070d85ecb762a7689db84a30991971865698ab6fec187206e6a92133790c5a91dc
BigcoinBGC pushed a commit to BigcoinBGC/bigcoin that referenced this pull request Jun 30, 2026
… over assumedvalid

9e91d9f wallet: have prune error take precedence over assumedvalid (James O'Beirne)

Pull request description:

  Fixes bitcoin/bitcoin#23997 (comment).

  From Russ Yanofsky:

  > Agree with all of Marco's points here and think this should be updated
  >
  > If havePrune and hasAssumedValidChain are both true, better to show havePrune error message.  Assumed-valid error message is vague and not very actionable.  Would suggest "Error loading wallet. Wallet requires blocks to be downloaded, and software does not currently support loading wallets while blocks are being downloaded out of order though assumeutxo snapshots. Wallet should be able to load successfully after node sync reaches height {block_height}"

ACKs for top commit:
  MarcoFalke:
    ACK 9e91d9f
  aureleoules:
    ACK 9e91d9f

Tree-SHA512: bfb0024bb962525cbbd392ade3c0331a8b0525e7f2f2ab52b2dbb9b6dd6311070d85ecb762a7689db84a30991971865698ab6fec187206e6a92133790c5a91dc
ab4cus pushed a commit to ab4cus/e4Coin-core that referenced this pull request Jul 8, 2026
… over assumedvalid

1c36bafc5f7db268546dcc86c793071a7e9d35e0 wallet: have prune error take precedence over assumedvalid (James O'Beirne)

Pull request description:

  Fixes bitcoin/bitcoin#23997 (comment).

  From Russ Yanofsky:

  > Agree with all of Marco's points here and think this should be updated
  >
  > If havePrune and hasAssumedValidChain are both true, better to show havePrune error message.  Assumed-valid error message is vague and not very actionable.  Would suggest "Error loading wallet. Wallet requires blocks to be downloaded, and software does not currently support loading wallets while blocks are being downloaded out of order though assumeutxo snapshots. Wallet should be able to load successfully after node sync reaches height {block_height}"

ACKs for top commit:
  MarcoFalke:
    ACK 1c36bafc5f7db268546dcc86c793071a7e9d35e0
  aureleoules:
    ACK 1c36bafc5f7db268546dcc86c793071a7e9d35e0

Tree-SHA512: bfb0024bb962525cbbd392ade3c0331a8b0525e7f2f2ab52b2dbb9b6dd6311070d85ecb762a7689db84a30991971865698ab6fec187206e6a92133790c5a91dc
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

9 participants