diff options
author | Andrew Chow <github@achow101.com> | 2023-09-19 13:01:36 -0400 |
---|---|---|
committer | Andrew Chow <github@achow101.com> | 2023-09-19 13:10:57 -0400 |
commit | abe4fedab735c145881e85dc2b02cf819a241635 (patch) | |
tree | 70bdfcc81953a2dad24a1e07c2976e75102e6c13 /src/wallet/scriptpubkeyman.cpp | |
parent | 53313c49d6dc12dacd7e3ce6594d4cad268cec12 (diff) | |
parent | 8e7e3e614955e60d3bf9e9a481ef8916bf9e22d9 (diff) | |
download | bitcoin-abe4fedab735c145881e85dc2b02cf819a241635.tar.xz |
Merge bitcoin/bitcoin#28125: wallet: bugfix, disallow migration of invalid scripts
8e7e3e614955e60d3bf9e9a481ef8916bf9e22d9 test: wallet, verify migration doesn't crash for an invalid script (furszy)
1de8a2372ab39386e689b27d15c4d029be239319 wallet: disallow migration of invalid or not-watched scripts (furszy)
Pull request description:
Fixing #28057.
The legacy wallet allows to import any raw script (#28126), without
checking if it was valid or not. Appending it to the watch-only set.
This causes a crash in the migration process because we are only
expecting to find valid scripts inside the legacy spkm.
These stored scripts internally map to `ISMINE_NO` (same as if they
weren't stored at all..).
So we need to check for these special case, and take into account that
the legacy spkm could be storing invalid not watched scripts.
Which, in code words, means `IsMineInner()` returning
`IsMineResult::INVALID` for them.
Note:
To verify this, can run the test commit on top of master.
`wallet_migration.py` will crash without the bugfix commit.
ACKs for top commit:
achow101:
ACK 8e7e3e614955e60d3bf9e9a481ef8916bf9e22d9
Tree-SHA512: c2070e8ba78037a8f573b05bf6caa672803188f05429adf5b93f9fc1493faedadecdf018dee9ead27c656710558c849c5da8ca5f6f3bc9c23b3c4275d2fb50c7
Diffstat (limited to 'src/wallet/scriptpubkeyman.cpp')
-rw-r--r-- | src/wallet/scriptpubkeyman.cpp | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp index 1f510d1c58..20f735da12 100644 --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -1716,8 +1716,23 @@ std::unordered_set<CScript, SaltedSipHasher> LegacyScriptPubKeyMan::GetScriptPub } // All watchonly scripts are raw - spks.insert(setWatchOnly.begin(), setWatchOnly.end()); + for (const CScript& script : setWatchOnly) { + // As the legacy wallet allowed to import any script, we need to verify the validity here. + // LegacyScriptPubKeyMan::IsMine() return 'ISMINE_NO' for invalid or not watched scripts (IsMineResult::INVALID or IsMineResult::NO). + // e.g. a "sh(sh(pkh()))" which legacy wallets allowed to import!. + if (IsMine(script) != ISMINE_NO) spks.insert(script); + } + + return spks; +} +std::unordered_set<CScript, SaltedSipHasher> LegacyScriptPubKeyMan::GetNotMineScriptPubKeys() const +{ + LOCK(cs_KeyStore); + std::unordered_set<CScript, SaltedSipHasher> spks; + for (const CScript& script : setWatchOnly) { + if (IsMine(script) == ISMINE_NO) spks.insert(script); + } return spks; } |