Background: The ParseHDKeypath method (src/util/bip32.cpp) is used only in a limited way: it is used when loading legacy wallets. Note that similar functionality is implemented independently in src/script/descriptor.cpp (ParseKeyPath, ParseKeyPathNum).
Deficiencies: The method has a unit test, but it checks only the bool result, and not the parsed keypath. This can be demonstrated by breaking the implementation by adding a keypath.clear(); statement just before the final return true;. With this obviously broken implementation the tests pass.
Solution proposed: Extend the tests with checks (without modifying the behavior), and also rename the method.
Notes:
- Behavior is not changed. This is a legacy method expected to be removed in the future. Production code is touched only by the rename.
- Here there is no attempt to merge
ParseHDKeypathwithParseKeyPath.
Potential future steps: The duplicated implementation -- ParseHDKeypath and ParseKeyPath -- could be merged, to reduce code duplication. Combining the two implementations could result in slightly better code; the former implementation looks better, while the latter has better unit test coverage.
Changes:
Extend the unit tests with checks for the returned parsed keypath. Add the expected parsed numerical keypath as test data. Note: breaking the production code as described above now results in test failure.
In the unit test also perform round-trip conversion: convert to string, then parse again, and convert to string again. In the last two steps the results should match the input before the round-trip (note: this is not true for the first roundtrip). Additionally, add negative tests for the unsupported 'h' hardened delimiter.
In the fuzzer also exercise the
apostrophe=falseversion ofFormatHDKeypath.Rename the method
ParseHDKeypathtoParseHDKeypathLegacy, to make it clearer that it is used only in the legacy wallet use case, and reduce the chance of confusion with similar parsing functionality indescriptor.cpp.