wallet: Implement independent BDB parser#26606
Conversation
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code CoverageFor detailed information about the code coverage, see the test coverage report. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsReviewers, this pull request conflicts with the following ones:
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. |
e18fdbf to
f135c19
Compare
src/streams.h
Outdated
There was a problem hiding this comment.
1d093bbf97b8d4ec5413ca560ac79e56f23d7f1d: Note for other reviewers: yes
src/streams.h
Outdated
There was a problem hiding this comment.
1d093bbf97b8d4ec5413ca560ac79e56f23d7f1d: maybe log the exact error code.
There was a problem hiding this comment.
It's kind of annoying to do that, so I'll leave it as is. The other functions do the same.
src/wallet/migrate.h
Outdated
There was a problem hiding this comment.
1224f45a92972199799d1ea33700eee567dc66fe: maybe call this file bdb_ro_wallet_db.h?
There was a problem hiding this comment.
The intent is to have all of the migration stuff in these files, so I will leave it as is.
|
Concept ACK. Have you looked into a fuzz target for this parser? |
I haven't. If someone would like to write one, I'd be happy to add it. |
2d61534 to
f2dc015
Compare
|
Adding a fuzz target that compares this to the real thing seems useful. Given that this PR changes It seems a bit daunting to compare the low level DBD parsing code in this PR to the real thing. Having a fuzzer also reduces the need to be very thorough in that. I'm not sure how much confidence I have in the existing test coverage for dumpwallet. |
944a020 to
f108c6b
Compare
sedited
left a comment
There was a problem hiding this comment.
Re-ACK c0e0a0affea3e3cee9a8910de4bae55a9bdd24cf
BerkeleyRODatabase is intended for use after BDB is removed, so it needs to be able to read all of the records from a BDB file. Thus an independent deserializer for BDB data files is implemented in it. This deserializer is targeted towards the data files that Bitcoin Core creates so it does not fully support all of BDB's features (e.g. other database types, encryption, etc.).
Implements MakeBerkeleyRODatabase and adds DatabaseFormat::BERKELEY_RO so that MakeDatabase can use BerkeleyRO as the backend database.
…lets In order to ease the transition to not having BDB, make the dump tool use DatabaseFormmat::BERKELEY_RO when -withinternalbdb is set.
Byteswapped databases make it easier to test opening and deserializing other endian databases.
|
reACK d51fbab |
There was a problem hiding this comment.
ACK d51fbab
Convinced myself that this parser works reliably partly by looking at the original code, partly by extending the test framework's BDB parser to match this PR's logic (see #30125), which helped a lot in understanding the structure. Also tested with a few random signet legacy wallets that I still had around, though those were all quite small.
Btw, I couldn't manage to find or create a BDB wallet where the DELETE flag is set in a record header (would be nice to exercise that in a test, though it's hard to verify that it's really set without inspecting manually, or e.g. adding debug messages on deserialization), but the code to handle that is simple enough and looks correct.
| error.original == "Page number mismatch" || | ||
| error.original == "Bad btree level" || | ||
| error.original == "Bad page size" || | ||
| error.original == "File size is not a multiple of page size" || |
There was a problem hiding this comment.
nit: isn't thrown in the parser (commented out), hence can be removed here
| error.original == "File size is not a multiple of page size" || |
| error.original == "Unexpected number of entries in outer database root page" || | ||
| error.original == "Subdatabase has an unexpected name" || | ||
| error.original == "Subdatabase page number has unexpected length" || | ||
| error.original == "Unexpected inner database page type" || |
There was a problem hiding this comment.
nit: isn't thrown anywhere, can be removed
| error.original == "Unexpected inner database page type" || |
| def add_options(self, parser): | ||
| self.add_wallet_options(parser) | ||
| parser.add_argument("--bdbro", action="store_true", help="Use the BerkeleyRO internal parser when dumping a Berkeley DB wallet file") | ||
| parser.add_argument("--swap-bdb-endian", action="store_true",help="When making Legacy BDB wallets, always make then byte swapped internally") |
There was a problem hiding this comment.
typo nit
| parser.add_argument("--swap-bdb-endian", action="store_true",help="When making Legacy BDB wallets, always make then byte swapped internally") | |
| parser.add_argument("--swap-bdb-endian", action="store_true",help="When making Legacy BDB wallets, always make them byte swapped internally") |
|
I wonder if it makes sense to collect the fuzz inputs to qa-assets, from testers that still have them. However, the fuzz CI does not compile with BDB, so that'll probably need to be adjusted first. |
|
Ported to the CMake-based build system in hebasto#220. |
This looks like an inconsistency in BDB itself as the failure is on BDB loading the database file. Additionally, since this test case passes on linux, I'm not entirely sure what to do about it. This will also be resolved once BDB is removed. |
Split from #26596
This PR adds
BerkeleyRODatabasewhich is an independent implementation of a BDB file parser. It provides read only access to a BDB file, and can therefore be used as a read only database backend for wallets. This will be used for dumping legacy wallet records and migrating legacy wallets without the need for BDB itself.Wallettool's
dumpcommand is changed to useBerkeleyRODatabaseinstead ofBerkeleyDatabase(andCWalletitself) to demonstrate that this parser works and to test it against the existing wallettool functional tests.