Skip to content

Conversation

achow101
Copy link
Member

@achow101 achow101 commented Nov 28, 2022

#26606 introduced BerkeleyRODatabase which is an independent parser for BDB files. This PR uses this in legacy wallet migration so that migration will continue to work once the legacy wallet and BDB are removed. LegacyDataSPKM is introduced to have the minimum data and functions necessary for a legacy wallet to be loaded for migration.

@DrahtBot
Copy link
Contributor

DrahtBot commented Nov 28, 2022

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

Code Coverage

For detailed information about the code coverage, see the test coverage report.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK cbergqvist, theStack, furszy

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:

  • #29124 (wallet: Automatically repair corrupted metadata with doubled derivation path by achow101)
  • #28574 (wallet: optimize migration process, batch db transactions by furszy)
  • #28333 (wallet: Construct ScriptPubKeyMans with all data rather than loaded progressively 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 indep-desc-migrate2 branch 2 times, most recently from 9d6ce8a to 03fdbaf Compare November 29, 2022 00:44
@Sjors
Copy link
Member

Sjors commented Nov 29, 2022

I think it would be easier to review if you made a separate PR for BerkeleyRODatabase and have it work as a regular, albeit read-only, wallet database backend.

I'm pleasantly surprised at how small the implementation is.

@luke-jr
Copy link
Member

luke-jr commented Nov 29, 2022

I don't see how reimplementing BDB is better than just continuing to use BDB.

@achow101 achow101 force-pushed the indep-desc-migrate2 branch from bb4ea93 to a8060af Compare November 29, 2022 21:22
@achow101
Copy link
Member Author

I don't see how reimplementing BDB is better than just continuing to use BDB.

The reimplementation is quite compact because it is for only reading BDB files, only the features that we use, and none of the actual DB system stuff. BDB itself contains a ton of code, a lot of which we don't use. Maintaining it as a dependency will eventually be more burdensome - we already need to patch it in order to compile in the depends system. This reimplementation does not carry those issues - it implements a format that isn't going to change, and it only depends on things that are already being used elsewhere in the codebase.

@achow101
Copy link
Member Author

I think it would be easier to review if you made a separate PR for BerkeleyRODatabase and have it work as a regular, albeit read-only, wallet database backend.

I've opeend #26606 for just BerkeleyRODatabase and its use in wallettool's dump.

@achow101
Copy link
Member Author

achow101 commented Jun 24, 2024

I believe this PR could get merged quite fast if you leave 8950371 for a follow-up and make IsMine compatible with LegacyDataSPKM in this PR.

Moved to #30328

The IsMine removal is also nice but I wouldn't miss a deadline for it.

I think it needs to be in the next release as it is a critical part of migration. I would prefer to have it in a release that people can use before deleting the legacy wallet.

Updated

  • in c653f4f: typo in commit subject (s/MigrateToLegacy/MigrateToDescriptor/)

Fixed

No, we should not be migrating a wallet if we cannot decrypt the keys. BerkeleyRODatabase always returns true for all write operations so it doesn't matter. Also, I don't think it is useful to invert that and have to have specific bypasses for BerkeleyRODatabase in all functions that attempts to write to it.

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.

Strange CI https://github.com/bitcoin/bitcoin/actions/runs/9649050504/job/26611651920?pr=26596 error.. it doesn't seem to be related. The "salvage" command opens the wallet in DatabaseFormat::BERKELEY format.

When we reopen the wallet to do the migration, instead of opening using
BDB, open it using the BerkeleyRO implementation.
@achow101 achow101 force-pushed the indep-desc-migrate2 branch from e94b4e6 to 9700c21 Compare June 26, 2024 20:39
@furszy
Copy link
Member

furszy commented Jun 27, 2024

Now that the IsMine changes were moved to another PR, could reorder the commits just so 0cce574 is introduced before c3373a3. This will let us keep the IsMine assertions inside MigrateToDescriptor for now.

Other than that, code review ACK 9700c21.

@DrahtBot DrahtBot requested review from theStack and cbergqvist June 27, 2024 20:42
Copy link
Contributor

@cbergqvist cbergqvist left a comment

Choose a reason for hiding this comment

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

git range-diff master a8f8a2d 9700c217

Agree with @furszy on reordering the commits to make it possible to retain the 3 asserts in MigrateToDescriptor().

@DrahtBot DrahtBot requested a review from cbergqvist June 27, 2024 22:27
achow101 and others added 5 commits July 1, 2024 14:24
In order to load the necessary data for migrating a legacy wallet
without the full LegacyScriptPubKeyMan, move the data storage and
loading components to LegacyDataSPKM. LegacyScriptPubKeyMan now
subclasses that.
IsMine is necessary for migration. It should be inlined with migration
when the legacy wallet is removed.
In SetupLegacyScriptPubKeyMan, a base LegacyDataSPKM will be created if
the database has the format "bdb_ro" (i.e. the wallet was opened only
for migration purposes).

All of the loading functions are now called with a LegacyDataSPKM object
instead of LegacyScriptPubKeyMan.
The migration process reloads the wallet after all failures.
This commit tests the behavior by trying to obtain a new address
after a decryption failure during migration.
@achow101 achow101 force-pushed the indep-desc-migrate2 branch from 9700c21 to 8ce3739 Compare July 1, 2024 18:25
@achow101
Copy link
Member Author

achow101 commented Jul 1, 2024

Reordered the commits and preserved the IsMine asserts.

Copy link
Contributor

@cbergqvist cbergqvist left a comment

Choose a reason for hiding this comment

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

ACK 8ce3739

git range-diff 9700c217~5..9700c217 8ce3739~5..8ce3739 - not the easiest read, also used GH compare.

Passed make check & test/functional/test_runner.py including p2p_handshake.py which failed on CI.

Only one non-critical reservation: #26596 (comment)

Copy link
Contributor

@theStack theStack left a comment

Choose a reason for hiding this comment

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

Code-review ACK 8ce3739

Comment on lines +3614 to +3622
LegacyDataSPKM* CWallet::GetLegacyDataSPKM() const
{
if (IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
return nullptr;
}
auto it = m_internal_spk_managers.find(OutputType::LEGACY);
if (it == m_internal_spk_managers.end()) return nullptr;
return dynamic_cast<LegacyDataSPKM*>(it->second);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: was about to suggest to deduplicate shared code between this method and ::GetLegacyScriptPubKeyMan above, but since the latter is removed soon anyway (in PR #28710, commit 5652a9c#diff-1f2db0e4d5c12d109c7f0962333c245b49b696cb39ff432da048e9d6c08944d8), it's probably not worth it.

Copy link
Member

@furszy furszy Jul 3, 2024

Choose a reason for hiding this comment

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

If you re-touch it again. Could:

LegacyDataSPKM* CWallet::GetLegacyDataSPKM() const
{
    if (IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) { return nullptr; }
    return dynamic_cast<LegacyDataSPKM*>(GetScriptPubKeyMan(OutputType::LEGACY, /*internal=*/true));
}

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.

Code review ACK 8ce3739

Comment on lines +3614 to +3622
LegacyDataSPKM* CWallet::GetLegacyDataSPKM() const
{
if (IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
return nullptr;
}
auto it = m_internal_spk_managers.find(OutputType::LEGACY);
if (it == m_internal_spk_managers.end()) return nullptr;
return dynamic_cast<LegacyDataSPKM*>(it->second);
}
Copy link
Member

@furszy furszy Jul 3, 2024

Choose a reason for hiding this comment

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

If you re-touch it again. Could:

LegacyDataSPKM* CWallet::GetLegacyDataSPKM() const
{
    if (IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) { return nullptr; }
    return dynamic_cast<LegacyDataSPKM*>(GetScriptPubKeyMan(OutputType::LEGACY, /*internal=*/true));
}

Comment on lines 793 to +798
void LegacyScriptPubKeyMan::LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata& meta)
{
LOCK(cs_KeyStore);
LegacyDataSPKM::LoadKeyMetadata(keyID, meta);
UpdateTimeFirstKey(meta.nCreateTime);
mapKeyMetadata[keyID] = meta;
}
Copy link
Member

@furszy furszy Jul 3, 2024

Choose a reason for hiding this comment

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

In 7461d0c:

At this point, just a non-blocking nit but you are locking cs_KeyStore twice. One here, and another one inside LegacyDataSPKM::LoadKeyMetadata.

Same for LoadScriptMetadata.

Comment on lines +813 to +816
bool LegacyDataSPKM::AddKeyPubKeyInner(const CKey& key, const CPubKey& pubkey)
{
LOCK(cs_KeyStore);
return FillableSigningProvider::AddKeyPubKey(key, pubkey);
Copy link
Member

Choose a reason for hiding this comment

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

In 7461d0c:

FillableSigningProvider::AddKeyPubKey already locks cs_Keystore internally.

@glozow glozow merged commit d9aa7b2 into bitcoin:master Jul 11, 2024
@bitcoin bitcoin locked and limited conversation to collaborators Jul 11, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants