8000 wallet: avoid rescans under assumed-valid blocks by jamesob · Pull Request #23997 · bitcoin/bitcoin · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

wallet: avoid rescans under assumed-valid blocks #23997

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

Merged
merged 1 commit into from
Jul 18, 2022

Conversation

jamesob
Copy link
Contributor
@jamesob jamesob commented Jan 7, 2022

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
Copy link
Member
luke-jr commented Jan 7, 2022

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
Copy link
Member
Sjors commented Jan 7, 2022

@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
Copy link
Contributor Author
jamesob commented Jan 7, 2022

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
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
Copy link
Contributor
DrahtBot commented Jan 14, 2022

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
Copy link
Contributor Author
jamesob commented Jan 15, 2022

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
Copy link
Member
Sjors commented Jan 16, 2022

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(?).

@jamesob
Copy link
Contributor Author
jamesob commented Jan 18, 2022

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
Copy link
Contributor Author
jamesob commented Feb 11, 2022

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.

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
Member

ACK 817326a

@jamesob
Copy link
Contributor Author
jamesob commented Jun 6, 2022

Ready for merge?

Copy link
Member
@maflcko maflcko left a comment

Choose a reason for hiding this comment

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

left a question

_(
"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
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
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.

Copy link
Member
@maflcko maflcko Jun 7, 2022

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
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
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
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.

Copy link
Member
@jonatack jonatack left a comment

Choose a reason for hiding this comment

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

Concept ACK

// If a block is pruned after this check, we will load the wallet,
// 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
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
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.

Copy link
Contributor
@ryanofsky ryanofsky Jun 14, 2022

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}"

Copy link
Contributor
@ryanofsky ryanofsky left a comment

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

// If a block is pruned after this check, we will load the wallet,
// 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
Contributor
@ryanofsky ryanofsky Jun 14, 2022

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
Copy link
Member
achow101 commented Jun 14, 2022

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
Copy link
Contributor
ryanofsky commented Jun 15, 2022

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
Copy link
Contributor Author
jamesob commented Jul 18, 2022

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
Copy link
Member
maflcko commented Jul 19, 2022

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

@jamesob
Copy link
Contributor Author
jamesob commented Jul 19, 2022

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
Copy link
Member
maflcko commented Aug 2, 2022

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
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
Copy link
Contributor Author
jamesob commented Oct 7, 2022

@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 24, 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
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Oct 24, 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
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
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
0