8000 Introduce `MockableDatabase` for wallet unit tests by achow101 · Pull Request #26715 · bitcoin/bitcoin · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Introduce MockableDatabase for wallet unit tests #26715

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 8 commits into from
May 15, 2023

Conversation

achow101
Copy link
Member
@achow101 achow101 commented Dec 16, 2022

For the wallet's unit tests, we currently use either DummyDatabase or memory-only versions of either BDB or SQLite. The tests that use DummyDatabase just need a WalletDatabase so that the CWallet can be constructed, while the tests using the memory-only databases just need a backing data store. There is also a FailDatabase that is similar to DummyDatabase except it fails be default or can have a configured return value. Having all of these different database types can make it difficult to write tests, particularly tests that work when either BDB or SQLite is disabled.

This PR unifies all of these different unit test database classes into a single MockableDatabase. Like DummyDatabase, most functions do nothing and just return true. Like FailDatabase, the return value of some functions can be configured on the fly to test various failure cases. Like the memory-only databases, records can actually be written to the MockableDatabase and be retrieved later, but all of this is still held in memory. Using MockableDatabase completely removes the need for having BDB or SQLite backed wallets in the unit tests for the tests that are not actually testing specific database behaviors.

Because MockableDatabases can be created by each unit test, we can also control what records are stored in the database. Records can be added and removed externally from the typical database modification functions. This will give us greater ability to test failure conditions, particularly those involving corrupted records.

Possible alternative to #26644

@DrahtBot
Copy link
Contributor
DrahtBot commented Dec 16, 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 furszy, TheCharlatan

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

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #bitcoin-core/gui/723 (Add warnings for non-active addresses in receive tab and address book by pinheadmz)
  • #27556 (wallet: fix deadlock in bdb read write operation by furszy)
  • #27286 (wallet: Keep track of the wallet's own transaction outputs in memory by achow101)
  • #26627 (wallet: Migrate non-HD keys with single combo containing a list of keys by achow101)
  • #26008 (wallet: cache IsMine scriptPubKeys to improve performance of descriptor wallets by achow101)
  • #25722 (refactor: Use util::Result class for wallet loading by ryanofsky)
  • #25297 (wallet: group independent db writes on single batched db transaction by furszy)
  • #24914 (wallet: Load database records in a particular order by achow101)

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.

@achow101 achow101 force-pushed the test-wallet-corrupt branch 2 times, most recently from 4e1a86d to 7bab6f2 Compare January 7, 2023 02:49
@achow101 achow101 force-pushed the test-wallet-corrupt branch from 7bab6f2 to 720a114 Compare January 23, 2023 19:44
@achow101 achow101 marked this pull request as ready for review January 23, 2023 19:44
@achow101 achow101 force-pushed the test-wallet-corrupt branch from 720a114 to 9487f7b Compare January 25, 2023 23:52
@achow101 achow101 force-pushed the test-wallet-corrupt branch from 9487f7b to d881f59 Compare January 26, 2023 16:02
@achow101 achow101 force-pushed the test-wallet-corrupt branch from d881f59 to 82538df Compare January 26, 2023 19:41
@achow101 achow101 force-pushed the test-wallet-corrupt branch 2 times, most recently from 3942517 to 759ce90 Compare February 17, 2023 20:38
Copy link
Contributor
@TheCharlatan TheCharlatan left a comment

Choose a reason for hiding this comment

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

Approach ACK

Just some minor comments; I like this change. I did not check yet if there are other tests that might be simpler with the new mockable class.

achow101 added 6 commits May 3, 2023 10:45
It's only used by salvage, so make it local to that only.
This will be needed for the following scripted-diff to work.
Since we have a mockable wallet database, we don't really need to be
using BDB or SQLite's in-memory database capabilities. It doesn't really
help us to be using those as we aren't doing anything that requires one
type of db over the other, and will just prefer SQLite if it's
available.

MockableDatabase is suitable for these uses, so use
CreateMockableWalletDatabase to use that.

-BEGIN VERIFY SCRIPT-
sed -i "s/CreateMockWalletDatabase(options)/CreateMockableWalletDatabase()/" $(git grep -l "CreateMockWalletDatabase(options)" -- ":(exclude)src/wallet/walletdb.*")
sed -i "s/CreateMockWalletDatabase/CreateMockableWalletDatabase/" $(git grep -l "CreateMockWalletDatabase" -- ":(exclude)src/wallet/walletdb.*")
-END VERIFY SCRIPT-
In the wallet ckey loading test, we modify various ckey records to test
corruption handling. As the database is now a mockable database, we can
modify the records that the database will be initialized with. This
avoids having to use the verbose database reading and writing functions.
@achow101 achow101 force-pushed the test-wallet-corrupt branch from abb2a83 to 45e3815 Compare May 3, 2023 14:45
Copy link
Member
@furszy furszy left a comment

Choose a reason for hiding this comment

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

ACK 33e2b82

@DrahtBot DrahtBot requested a review from TheCharlatan May 3, 2023 19:53
Copy link
Contributor
@TheCharlatan TheCharlatan left a comment

Choose a reason for hiding this comment

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

ACK 33e2b82

@fanquake fanquake merged commit d02df7d into bitcoin:master May 15, 2023
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request May 15, 2023
fanquake added a commit that referenced this pull request May 16, 2023
0282b21 walletdb: Remove unused CreateMockWalletDatabase (Andrew Chow)

Pull request description:

  This has been superseded by the MockableDatabase. Remove to avoid confusion as to which type of mock database to use for testing.

  I thought this was included in #26715, maybe it got lost in a rebase.

ACKs for top commit:
  furszy:
    utACK 0282b21
  brunoerg:
    crACK 0282b21

Tree-SHA512: 18445c4d8a4e2609ef7471c6d75297f43694b79e768f6c993a5addb1dc0e88bd12bac263c9d8e903d828ddf6bf50434f9e2f72048f4fc528e98fed8ee65123ca
@kouloumos
Copy link
Contributor

While reviewing #27666, I observed that this PR changed the performance of the WalletLoadingLegacy benchmark:

PR branch (33e2b82)

ns/op op/s err% ins/op cyc/op IPC bra/op miss% total benchmark
63,589,392.00 15.73 0.1% 265,707,729.00 125,674,284.00 2.114 32,837,198.00 1.0% 0.32 WalletLoadingLegacy

master at the time (5394522)

ns/op op/s err% ins/op cyc/op IPC bra/op miss% total benchmark
272,970,312.00 3.66 0.1% 617,971,997.00 417,477,301.00 1.480 103,288,956.00 0.4% 1.39 `WalletLoadingLegacy``

This is probably not an issue, but it seems worth noting that a change of the underlying mock implementation had such an impact on the performance of legacy wallet loading. I am thinking that this might be the case of a not so effective benchmark, but I'll need to investigate further as I haven't look into the actual changes of this PR yet.

@achow101
Copy link
Member Author

This is probably not an issue, but it seems worth noting that a change of the underlying mock implementation had such an impact on the performance of legacy wallet loading.

It changed the underlying db used for this benchmark from the BDB in-memory database to the MockableDatabase. However I think the goal of this benchmark is to measure LoadWallet specifically and not necessarily the database engine, so I don't think it particularly matters.

sidhujag pushed a commit to syscoin/syscoin that referenced this pull request May 17, 2023
0282b21 walletdb: Remove unused CreateMockWalletDatabase (Andrew Chow)

Pull request description:

  This has been superseded by the MockableDatabase. Remove to avoid confusion as to which type of mock database to use for testing.

  I thought this was included in bitcoin#26715, maybe it got lost in a rebase.

ACKs for top commit:
  furszy:
    utACK 0282b21
  brunoerg:
    crACK 0282b21

Tree-SHA512: 18445c4d8a4e2609ef7471c6d75297f43694b79e768f6c993a5addb1dc0e88bd12bac263c9d8e903d828ddf6bf50434f9e2f72048f4fc528e98fed8ee65123ca
achow101 added a commit that referenced this pull request May 18, 2023
69d4390 test: add coverage for wallet read write db deadlock (furszy)
12daf6f walletdb: scope bdb::EraseRecords under a single db txn (furszy)
043fcb0 wallet: bugfix, GetNewCursor() misses to provide batch ptr to BerkeleyCursor (furszy)

Pull request description:

  Decoupled from #26644 so it can closed in favor of #26715.

  Basically, with bdb, we can't make a write operation while we are traversing the db with the same db handler. These two operations are performed in different txn contexts and cause a deadlock.

  Added coverage by using `EraseRecords()` which is the simplest function that executes this process.

  To replicate it, need bdb support and drop the first commit. The test will run forever.

ACKs for top commit:
  achow101:
    ACK 69d4390
  hebasto:
    re-ACK 69d4390

Tree-SHA512: b3773be78925f674e962f4a5c54b398a9d0cfe697148c01c3ec0d68281cc5c1444b38165960d219ef3cf1a57c8ce6427f44a876275958d49bbc0808486e19d7d
fanquake added a commit to bitcoin-core/gui that referenced this pull request May 19, 2023
b8ed951 msvc: Provide `ObjectFileName` explicitly (Hennadii Stepanov)

Pull request description:

  This PR is a follow-up to bitcoin/bitcoin#26715.

  Fixes intermittent MSVC link [errors](https://cirrus-ci.com/task/6646912535756800).

ACKs for top commit:
  sipsorcery:
    ACK b8ed951.

Tree-SHA512: 4319ecf61b578ce66d240998d089b9bb0a42f89dcfcb1a73f648cd3915f566c773721dcff1feba27d393a743d121334ccb890b1a519173e35a156d6135821ef4
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request May 19, 2023
69d4390 test: add coverage for wallet read write db deadlock (furszy)
12daf6f walletdb: scope bdb::EraseRecords under a single db txn (furszy)
043fcb0 wallet: bugfix, GetNewCursor() misses to provide batch ptr to BerkeleyCursor (furszy)

Pull request description:

  Decoupled from bitcoin#26644 so it can closed in favor of bitcoin#26715.

  Basically, with bdb, we can't make a write operation while we are traversing the db with the same db handler. These two operations are performed in different txn contexts and cause a deadlock.

  Added coverage by using `EraseRecords()` which is the simplest function that executes this process.

  To replicate it, need bdb support and drop the first commit. The test will run forever.

ACKs for top commit:
  achow101:
    ACK 69d4390
  hebasto:
    re-ACK 69d4390

Tree-SHA512: b3773be78925f674e962f4a5c54b398a9d0cfe697148c01c3ec0d68281cc5c1444b38165960d219ef3cf1a57c8ce6427f44a876275958d49bbc0808486e19d7d
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request May 19, 2023
b8ed951 msvc: Provide `ObjectFileName` explicitly (Hennadii Stepanov)

Pull request description:

  This PR is a follow-up to bitcoin#26715.

  Fixes intermittent MSVC link [errors](https://cirrus-ci.com/task/6646912535756800).

ACKs for top commit:
  sipsorcery:
    ACK b8ed951.

Tree-SHA512: 4319ecf61b578ce66d240998d089b9bb0a42f89dcfcb1a73f648cd3915f566c773721dcff1feba27d393a743d121334ccb890b1a519173e35a156d6135821ef4
@bitcoin bitcoin locked and limited conversation to collaborators May 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants
0