#25722 refactor: Use util::Result class for wallet loading
| Reviewability | Reviews | Agreement | Size | |||||||
|---|---|---|---|---|---|---|---|---|---|---|
| #25722 refactor: Use util::Result class for wallet loading | Review #25665 first | 0 | Strong | 1,156 + 280 tests | ||||||
|
|
|
| |||||||
Reviewability: ReadyStalePaused Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs. Size: lines added or modified outside tests, then in tests; greener = smaller. | ||||||||||
Goal
Refactors wallet loading, creation, restoration, verification, and migration across the wallet subsystem to uniformly return util::Result and util::ResultPtr. It eliminates mutable out-parameters for database status enums, bilingual error strings, and warning vectors. As part of this standardization, DatabaseStatus is renamed to DatabaseError with its unused success state removed.
Problem: Wallet initialization and loading functions across the stack handle errors inconsistently, passing multiple mutable out-parameters for status codes, error strings, and lists of warnings. This creates cumbersome function signatures and boilerplate error-propagation code across wallet internals, RPC handlers, and GUI controllers.
Evidence of importance:
- Author description: 'Wallet loading functions up and down the stack have lots of error and warning parameters, and return error information in different ways. This PR makes them uniformly return util::Result, without changing behavior.'
Scope: This PR is stacked on #25665 and #26022, including commits that enhance util::Result to support error payload types, warning messages, and pointer dereferencing sugar. It also includes a scripted-diff commit replacing DatabaseStatus with DatabaseError.
Risk of a mistake: medium (wallet, wallet_storage, rpc_api). A mistake in error translation or result checking could cause wallet database loading to fail unexpectedly or return incorrect error codes via RPC.
Changed since the previous assessment: Rebased onto master to incorporate recent wallet architectural changes (such as the splitting of CWallet::Create), and updated base commits with a CI configuration workaround for GCC maybe-uninitialized compiler warnings.
Reviewability
Ready · Review #25665 first
Stacked on #25665; the base PR's changes are included in this diff.
Waiting on (from the thread read):
- author: draft PR waiting on base PRs (#25665, #26022) to merge 2024-11-04
Agreement
Strong
substantive support, no open objection (martinus)
Thread notes: Added waiting_on tracking; author logged periodic rebase and conflict resolutions while PR remains in draft.
Objections, suggestions, and questions:
| Reviewer | Type | Harm, request, or question | Status | Must be | Author replied | Quote |
|---|---|---|---|---|---|---|
| martinus (contributor) | suggestion, maintenance | use a bool template argument instead of passing a lambda to simplify recursive Construct calls | fixed · fix pushed · author adopted the suggestion renaming the template argument to Failure and pushed the change | answered | yes | 2023-04-16: 'It took me a while to figure out what's going on here with the recursive `Construct` calls and the lambda that's passed along. How about instead of passing a lambda along use a `bool` template argumen' Status from: 2023-05-02: ryanofsky: 'Thanks, that's much better! Took suggestion jsut renaming argument to "Failure"' |
| martinus (contributor) | suggestion, interface | explicitly mark move-assignment operator as deleted for clearer compiler error messages | fixed · fix pushed · author marked the operator deleted and added a comment | answered | yes | 2023-04-16: 'Mayby explicitly mark the move-assignment as delete' Status from: 2023-05-02: ryanofsky: 'Thanks, that changes error message from `error: object of type 'util::Result<int>' cannot be assigned because its copy a' |
| martinus (contributor) | suggestion, maintenance | remove unnecessary check if (!src.m_info->errors.empty()) | answered · author explained the check avoids allocating ErrorInfo in the common error-free case | answered | yes | 2023-04-16: 'nit: I don't think the `if (!src.m_info->errors.empty())` check is necessary.' Status from: 2023-05-02: ryanofsky: 'It's not strictly necessary, but it avoids allocating an ErrorInfo object in the common case where there are no errors o' |
| martinus (contributor) | objection, correctness | compile error in spend.cpp ChooseSelectionResult after rebase | fixed · fix pushed · fixed in rebase | changed | no | 2023-04-22: 'After rebasing I get a compile error in `spend.cpp` `ChooseSelectionResult`, adding a bunch of `std::move` helps' Status from: 2023-07-21: ryanofsky: 'making most of the suggested changes' |
| martinus (contributor) | objection, interface | allowing Result<bool> is error-prone because Result converts to bool for success or failure | answered · author agreed that types like bool and optional<T> are ambiguous and should be disallowed, while clarifying pointers and ints should remain allowed | answered | yes | 2023-04-22: 'maybe consider forbidding type `bool` for `T`. I recently had similar code in another project, and its utterly confusing; because Result can convert to bool but that only tells if it *has* a bool or n' Status from: 2023-07-20: ryanofsky: 'I agree with all of this and want to do more work to address it.' |
| martinus (contributor) | suggestion, correctness | add static_assert checks to ensure sizeof(util::Result) matches expected size | fixed · fix pushed · author added static_asserts in result_tests.cpp | answered | yes | 2023-04-22: 'I'd add a check somewhere to ensure that the size of the Result is as claimed in the commit message' Status from: 2023-05-02: ryanofsky: 'Thanks, added to result_tests.cpp' |
| martinus (contributor) | suggestion, safety | mark move constructors noexcept along with methods they use | answered · author explained conditions required for noexcept and deferred optimization for later | answered | yes | 2023-04-22: 'move constructors should usually be `noexcept`, but then all methods it uses also have to be `noexcept`.' Status from: 2023-05-02: ryanofsky: 'Right now I'm just trying to do the simplest thing that's correct, and I think probably in most cases where the result c' |
| sedited (member) | question, interface | how are Result<std::optional<T>> and other types implementing operator bool() handled | answered · author answered agreeing that Result<optional<T>> is ambiguous and should be disallowed | answered | yes | 2023-06-19: 'I guess the same goes for something like `Result<std::optional<int>, int>`, or really any type implementing `operator bool()`? How did you handle these cases in your code?' Status from: 2023-07-20: ryanofsky: 'I think by default types convertible to bool should be disallowed with `Result`. I think `Result<bool>` or `Result<optio' |
Support:
- martinus (contributor) (2023-04-22) [read]: This makes util::Result quite a bit more powerful, and it's still simple to use.
Participants:
- martinus (contributor, objection, 13 statements 2023-04-16 to 2023-04-22): reviewed code, reported a rebase compile error, warned against Result<bool>, and suggested template and test improvements
- sedited (member, question, 1 statements 2023-06-19 to 2023-06-19): asked how types convertible to bool and Result<optional<T>> are handled
- maflcko (member, neutral, 1 statements 2023-08-01 to 2023-08-01): suggested keeping PR in draft while CI is red and based on other PRs
Dependencies
Files
361 lines under test/bench/ci.
- src/wallet/wallet.cpp +278/-259
- src/util/result.h +415/-62
- src/test/result_tests.cpp +239/-11
- src/wallet/dump.cpp +49/-54
- src/node/chainstate.cpp +56/-39
- src/wallet/sqlite.cpp +37/-33
- src/wallet/interfaces.cpp +32/-32
- src/wallet/wallettool.cpp +27/-28
- src/util/messages.h +52/-0
- src/wallet/load.cpp +22/-25
- src/init.cpp +24/-21
- src/qt/walletcontroller.cpp +29/-16
- src/wallet/rpc/wallet.cpp +20/-19
- src/wallet/walletdb.cpp +12/-27
- src/util/messages.cpp +32/-0
- src/node/chainstate.h +6/-22
- src/wallet/wallet.h +12/-13
- src/wallet/rpc/util.cpp +11/-11
- src/wallet/test/util.cpp +7/-15
- src/bench/wallet_create.cpp +5/-10
- src/bench/wallet_loading.cpp +7/-7
- src/kernel/bitcoinkernel.cpp +7/-7
- src/wallet/test/walletload_tests.cpp +4/-9
- src/wallet/rpc/backup.cpp +5/-7
- src/wallet/test/db_tests.cpp +3/-9
- src/wallet/export.cpp +6/-5
- src/wallet/migrate.cpp +3/-7
- src/wallet/test/fuzz/wallet_bdb_parser.cpp +3/-6
- src/wallet/test/wallet_tests.cpp +3/-6
- src/test/util/setup_common.cpp +4/-4
- src/interfaces/wallet.h +3/-3
- src/wallet/db.h +3/-3
- src/wallet/dump.h +3/-2
- src/wallet/rpc/util.h +3/-2
- src/wallet/sqlite.h +3/-2
- ci/test/00_setup_env_win64.sh +2/-1
- src/wallet/migrate.h +2/-1
- ci/test/00_setup_env_native_previous_releases.sh +1/-1
- src/addrdb.cpp +1/-1
- src/addrdb.h +1/-1
- src/qt/test/addressbooktests.cpp +1/-1
- src/qt/test/wallettests.cpp +1/-1
- src/kernel/CMakeLists.txt +1/-0
- src/util/CMakeLists.txt +1/-0
Card
The short text the ranking pass compares across PRs.
This pull request refactors wallet loading, creation, restoration, and migration functions across the wallet subsystem to uniformly return util::Result and util::ResultPtr. It removes disparate out-parameters for database status codes, bilingual error strings, and warning vectors, standardizing error reporting without changing behavior. The PR is an internal refactoring with no reported bug fixes or user-visible functional changes. It depends on base PRs #25665 and #26022 for extensions to the util::Result template.
Data
thread read through 2024-11-04 (31 statements), head d3ee1e6368
labels: Refactoring · draft
Categories
Utilities (logging, arguments, libraries)
P3 · cleanup (ranking pass: Moved down: a behaviour-preserving refactor of wallet error plumbing, reviewable only after #25665 and #26022.)
The PR expands util::Result capabilities to handle structured error types and warnings. While valuable for consistent error reporting across the codebase, this is an internal utility enhancement without urgent timing.
Membership: Extensively enhances src/util/result.h (+415/-62) and adds src/util/messages.* to support error payload types, warning messages, and pointer sugar.
Factors: security/stability 0, bug 0, performance 0, user value 0, leverage 1
Wallet
P3 · cleanup (ranking pass: Moved down: behavior-preserving error-plumbing refactor, ranked with the other internal cleanups.)
Standardizes wallet loading error handling and removes error out-parameters across the wallet stack 'without changing behavior'. It provides a cleaner internal architecture across wallet loading and migration routines, but has no direct user-facing or fund-safety impact.
Membership: Refactors wallet initialization, loading, creation, restoration, and migration throughout src/wallet/ to uniformly return util::Result.
Factors: security/stability 0, bug 0, performance 0, user value 0, leverage 1