Skip to content

Conversation

@aureleoules
Copy link
Contributor

@aureleoules aureleoules commented Dec 1, 2022

Fixes #26463.

This PR prevents a user from unloading a wallet if it is currently rescanning.

To test:

./src/bitcoin-cli -testnet -named createwallet wallet_name=wo disable_private_keys=true
./src/bitcoin-cli -testnet -rpcwallet=wo importdescriptors '[{
	  "desc": "addr(mmcuW74MyJUZuLnWXGQLoNXPrS9RbFz6gD)#tpnrahgc",
      "timestamp": 0,
      "active": false,
      "internal": false,
      "next": 0
}]'
./src/bitcoin-cli -testnet unloadwallet wo
error code: -4
error message:
Wallet is currently rescanning. Abort existing rescan or wait.

@DrahtBot
Copy link
Contributor

DrahtBot commented Dec 1, 2022

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

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK w0xlt, kouloumos, promag, achow101
Concept ACK luke-jr

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Copy link
Contributor

@stickies-v stickies-v left a comment

Choose a reason for hiding this comment

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

Current behaviour seems to be that unloadwallet waits until the scan is finished. Changing that by throwing could affect downstream users that are expecting unloadwallet to just wait. I think the behaviour in this PR is better if it were implemented like that from the start. I'm not sure if it's worth changing though? ~0 on this for now.

Copy link
Contributor

@ishaanam ishaanam left a comment

Choose a reason for hiding this comment

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

Current behaviour seems to be that unloadwallet waits until the scan is finished.

This is what I have observed as well. Even so, I think that it would be better if instead of waiting for the rescan to finish (which could take hours), CWallet::AbortRescan is called from unloadwallet. This seems better because unloadwallet should ideally be able to unload the wallet relatively quickly regardless of the processes that the wallet is running. A warning could be given when a rescan has been aborted by unloadwallet so that a user is not surprised.

@aureleoules
Copy link
Contributor Author

Changing that by throwing could affect downstream users that are expecting unloadwallet to just wait.

Do you know any software that would use this behavior? I understand this could affect users but this seems a bit hacky.

A warning could be given when a rescan has been aborted by unloadwallet so that a user is not surprised.

I don't really have an opinion on this. But an argument for keeping the warning in 8198c76a3008094fefbbae1b11e5d5673a993158 is that an user may not realize that the wallet is still rescanning and wouldn't want to abort it when trying to unload.
As a compromise we could add a 'force' argument to unloadwallet to abort the rescan if there is one.

@w0xlt
Copy link
Contributor

w0xlt commented Dec 3, 2022

As a compromise we could add a 'force' argument to unloadwallet to abort the rescan if there is one.

I think this is a good approach.

@luke-jr
Copy link
Member

luke-jr commented Dec 7, 2022

Agree with a force option (named only / options Object).

But also, we probably shouldn't return from unloadwallet until the wallet is actually unloaded fully, independently of whether that's due to a rescan or otherwise.

I guess this PR is strictly better than the current behaviour, though, so Concept ACK.

@aureleoules aureleoules force-pushed the 2022-11-unloadwallet-with-rescan branch from 8198c76 to bee026e Compare December 7, 2022 14:08
@aureleoules
Copy link
Contributor Author

aureleoules commented Dec 7, 2022

I added the named force option that will abort the rescan in progress.
https://github.com/bitcoin/bitcoin/compare/8198c76a3008094fefbbae1b11e5d5673a993158..2567ffc5f1850af7b97c3faf166c187dff65cd4c

@aureleoules aureleoules force-pushed the 2022-11-unloadwallet-with-rescan branch from bee026e to 2567ffc Compare December 7, 2022 14:11
Copy link
Contributor

@promag promag left a comment

Choose a reason for hiding this comment

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

Tiny concept NACK.

I think unloadwallet should just fail if a scan is in progress. We already have that behavior/warning elsewhere: Wallet is currently rescanning. Abort existing rescan or wait. I understand it can be seen as a breaking change, but makes more sense than what happened in #26463.


Regardless of the above, the current code is still not ideal, for instance, a scan can be initiated after IsScanning check if importdescriptors is called concurrently. I think you should use WalletRescanReserver because it allows checking if a rescan is in progress and at the same time prevent concurrent scans.

A test case would be nice.

@ziggie1984
Copy link

Thanks for fixing this issue. I like the approach more where we just fail the unloadwallet call but the force flag is also a good way.

a scan can be initiated after IsScanning check if importdescriptors is called concurrently.

Definitly important to prevent bitcoind from crashing. I was able to bring bitcoind down when unloading the wallet (blocking in the background) deleting the walletdir and then importing the descriptors with the same wallet name again (an then there was a dependence that one sync finished before the other). So would be important if we would not allow loading a wallet which is currently in rescan (at least not with the same name).

@aureleoules aureleoules force-pushed the 2022-11-unloadwallet-with-rescan branch from 2567ffc to 3f31949 Compare December 8, 2022 15:11
@aureleoules
Copy link
Contributor Author

I have decided to remove to force option and only leave a warning in case there is a rescan. To me it's simpler and faster to type abortrescan than options={"force": true} and the warning is consistent with other RPCs.

I think you should use WalletRescanReserver because it allows checking if a rescan is in progress and at the same time prevent concurrent scans.

Done, thanks.

Copy link
Contributor

@promag promag 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, unloadwallet fails if a rescan is in progress. Needs:

  • release notes
  • test, not sure how
  • follow-up in the GUI

@aureleoules aureleoules force-pushed the 2022-11-unloadwallet-with-rescan branch from 3f31949 to 8aa324e Compare December 8, 2022 15:41
@aureleoules aureleoules force-pushed the 2022-11-unloadwallet-with-rescan branch from 8aa324e to 109cbb8 Compare December 8, 2022 15:45
@aureleoules
Copy link
Contributor Author

Thanks, @promag. I added release notes.

I think the test should be a follow-up as there are many other instances where this warning is not tested.

@promag
Copy link
Contributor

promag commented Dec 8, 2022

I think the test should be a follow-up as there are many other instances where this warning is not tested.

The general rule of thumb is that tests are added when there are changes.

@aureleoules
Copy link
Contributor Author

The general rule of thumb is that tests are added when there are changes.

I agree but the RPC error Wallet is currently rescanning. Abort existing rescan or wait has not been tested in other RPCs either and if a test were to be added, the other RPCs should be tested too and that may be out of scope.

grep -nrIi "Wallet is currently rescanning. Abort existing rescan or wait" ./src
src/wallet/rpc/backup.cpp:159:            throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");
src/wallet/rpc/backup.cpp:254:        throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");
src/wallet/rpc/backup.cpp:447:        throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");
src/wallet/rpc/backup.cpp:516:        throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");
src/wallet/rpc/backup.cpp:1351:        throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");
src/wallet/rpc/backup.cpp:1658:        throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");
src/wallet/rpc/transactions.cpp:872:        throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");
src/wallet/rpc/wallet.cpp:444:            throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");
grep -nrIi "Wallet is currently rescanning. Abort existing rescan or wait" ./test
<empty>

I'll look into adding a test though.

@promag
Copy link
Contributor

promag commented Dec 8, 2022

My suggestion is to test the just introduced error, the other are indeed out of scope.

@ziggie1984
Copy link

ziggie1984 commented Dec 8, 2022

Is it conceptionally possible to abort the rescan, if the wallet_dir is deleted (manually with rm -f wallet_dir)? My tests showed me that bitcoind will happily rescan further ? Or is it somehow a user-misbehaving we should not take into account ?

@promag
Copy link
Contributor

promag commented Dec 8, 2022

@ziggie1984 user-misbehaving

@luke-jr
Copy link
Member

luke-jr commented Dec 9, 2022

Yeah, I would think deleting data files out from under the software should be expected to crash ;)

@aureleoules
Copy link
Contributor Author

I added a test in #26700 @promag.

Copy link
Contributor

@w0xlt w0xlt left a comment

Choose a reason for hiding this comment

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

ACK 109cbb8

Copy link
Contributor

@kouloumos kouloumos left a comment

Choose a reason for hiding this comment

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

ACK 109cbb8
The implementation is consistent with how the WalletRescanReserver is used in the rest of the related RPCs as pointed out in #26618 (review) .
(check the rest of the RPCs with git grep -n "Wallet is currently rescanning. Abort existing rescan or wait")

I would also prefer to see a test as part of this PR, but looking at the linked draft PR implementation it seems that the relative complexity to include a test (other test cases missing, refactor of an existing test file) justifies a follow-up.

Copy link
Contributor

@promag promag left a comment

Choose a reason for hiding this comment

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

ACK 109cbb8

@achow101
Copy link
Member

achow101 commented Jan 9, 2023

ACK 109cbb8

achow101 added a commit to bitcoin-core/gui that referenced this pull request Jan 9, 2023
…canning

109cbb8 doc: Add release notes for #26618 (Aurèle Oulès)
b13902d rpc: Prevent unloading a wallet when rescanning (Aurèle Oulès)

Pull request description:

  Fixes #26463.

  This PR prevents a user from unloading a wallet if it is currently rescanning.

  To test:

  ```bash
  ./src/bitcoin-cli -testnet -named createwallet wallet_name=wo disable_private_keys=true
  ./src/bitcoin-cli -testnet -rpcwallet=wo importdescriptors '[{
    "desc": "addr(mmcuW74MyJUZuLnWXGQLoNXPrS9RbFz6gD)#tpnrahgc",
        "timestamp": 0,
        "active": false,
        "internal": false,
        "next": 0
  }]'
  ./src/bitcoin-cli -testnet unloadwallet wo
  error code: -4
  error message:
  Wallet is currently rescanning. Abort existing rescan or wait.

ACKs for top commit:
  achow101:
    ACK 109cbb8
  w0xlt:
    ACK bitcoin/bitcoin@109cbb8
  kouloumos:
    ACK 109cbb8
  promag:
    ACK 109cbb8

Tree-SHA512: 15fdddf4cf9f3fa08f52069fe4a25a76e04a55bb2586b031bfb0393dce7f175dcdb52823e132a7dff6a894539beeb980a1aad2a792790be036be6977628149b2
@achow101
Copy link
Member

achow101 commented Jan 9, 2023

This was merged

@achow101 achow101 closed this Jan 9, 2023
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Jan 10, 2023
109cbb8 doc: Add release notes for bitcoin#26618 (Aurèle Oulès)
b13902d rpc: Prevent unloading a wallet when rescanning (Aurèle Oulès)

Pull request description:

  Fixes bitcoin#26463.

  This PR prevents a user from unloading a wallet if it is currently rescanning.

  To test:

  ```bash
  ./src/bitcoin-cli -testnet -named createwallet wallet_name=wo disable_private_keys=true
  ./src/bitcoin-cli -testnet -rpcwallet=wo importdescriptors '[{
    "desc": "addr(mmcuW74MyJUZuLnWXGQLoNXPrS9RbFz6gD)#tpnrahgc",
        "timestamp": 0,
        "active": false,
        "internal": false,
        "next": 0
  }]'
  ./src/bitcoin-cli -testnet unloadwallet wo
  error code: -4
  error message:
  Wallet is currently rescanning. Abort existing rescan or wait.

ACKs for top commit:
  achow101:
    ACK 109cbb8
  w0xlt:
    ACK bitcoin@109cbb8
  kouloumos:
    ACK 109cbb8
  promag:
    ACK 109cbb8

Tree-SHA512: 15fdddf4cf9f3fa08f52069fe4a25a76e04a55bb2586b031bfb0393dce7f175dcdb52823e132a7dff6a894539beeb980a1aad2a792790be036be6977628149b2
@aureleoules aureleoules deleted the 2022-11-unloadwallet-with-rescan branch January 12, 2023 11:51
@bitcoin bitcoin locked and limited conversation to collaborators Jan 12, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[wallet] when unloading a wallet which still rescans the wallet, the command should fail but bitcoind gets in a buggy state