wallet: persist the mnemonic entropy in wallet.dat
Adds the record pair for the entropy, mirroring "hdseed"/"chdseed": a plaintext form, an encrypted form that erases its plaintext counterpart the way WriteCryptedKey does, and an erase. Both new types are registered in IsKeyType so -salvagewallet preserves them. Without that, salvage would silently drop the phrase while keeping the wallet otherwise intact. The records are defined but nothing writes them yet. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -871,6 +871,10 @@ static bool IsKeyType(string strType)
|
|||||||
{
|
{
|
||||||
return (strType == "key" || strType == "wkey" ||
|
return (strType == "key" || strType == "wkey" ||
|
||||||
strType == "hdseed" || strType == "chdseed" ||
|
strType == "hdseed" || strType == "chdseed" ||
|
||||||
|
// The mnemonic entropy must survive a keys-only salvage: without it
|
||||||
|
// a recovered wallet keeps its seed (and stays fully spendable) but
|
||||||
|
// silently loses the ability to reprint its seed phrase.
|
||||||
|
strType == "mnementropy" || strType == "cmnementropy" ||
|
||||||
strType == "zkey" || strType == "czkey" ||
|
strType == "zkey" || strType == "czkey" ||
|
||||||
strType == "sapzkey" || strType == "csapzkey" ||
|
strType == "sapzkey" || strType == "csapzkey" ||
|
||||||
strType == "vkey" ||
|
strType == "vkey" ||
|
||||||
@@ -1345,6 +1349,24 @@ bool CWalletDB::EraseHDSeed(const uint256& seedFp)
|
|||||||
return Erase(std::make_pair(std::string("hdseed"), seedFp));
|
return Erase(std::make_pair(std::string("hdseed"), seedFp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CWalletDB::WriteMnemonicEntropy(const uint256& entropyFp, const RawHDSeed& entropy)
|
||||||
|
{
|
||||||
|
nWalletDBUpdated++;
|
||||||
|
return Write(std::make_pair(std::string("mnementropy"), entropyFp), entropy);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWalletDB::WriteCryptedMnemonicEntropy(const uint256& entropyFp, const std::vector<unsigned char>& vchCryptedSecret)
|
||||||
|
{
|
||||||
|
nWalletDBUpdated++;
|
||||||
|
return Write(std::make_pair(std::string("cmnementropy"), entropyFp), vchCryptedSecret);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWalletDB::EraseMnemonicEntropy(const uint256& entropyFp)
|
||||||
|
{
|
||||||
|
nWalletDBUpdated++;
|
||||||
|
return Erase(std::make_pair(std::string("mnementropy"), entropyFp));
|
||||||
|
}
|
||||||
|
|
||||||
bool CWalletDB::WriteHDChain(const CHDChain& chain)
|
bool CWalletDB::WriteHDChain(const CHDChain& chain)
|
||||||
{
|
{
|
||||||
nWalletDBUpdated++;
|
nWalletDBUpdated++;
|
||||||
|
|||||||
@@ -227,6 +227,12 @@ public:
|
|||||||
//! CWallet::EncryptWallet) copies whatever records still exist into the new
|
//! CWallet::EncryptWallet) copies whatever records still exist into the new
|
||||||
//! file, so a leftover "hdseed" leaves the unencrypted seed on disk forever.
|
//! file, so a leftover "hdseed" leaves the unencrypted seed on disk forever.
|
||||||
bool EraseHDSeed(const uint256& seedFp);
|
bool EraseHDSeed(const uint256& seedFp);
|
||||||
|
//! BIP39 entropy for a phrase-recoverable wallet. Display-only: derivation
|
||||||
|
//! never reads it. Record names are deliberately distinct prefixes from
|
||||||
|
//! "hdseed"/"chdseed" so they cannot collide.
|
||||||
|
bool WriteMnemonicEntropy(const uint256& entropyFp, const RawHDSeed& entropy);
|
||||||
|
bool WriteCryptedMnemonicEntropy(const uint256& entropyFp, const std::vector<unsigned char>& vchCryptedSecret);
|
||||||
|
bool EraseMnemonicEntropy(const uint256& entropyFp);
|
||||||
//! write the hdchain model (external chain child index counter)
|
//! write the hdchain model (external chain child index counter)
|
||||||
bool WriteHDChain(const CHDChain& chain);
|
bool WriteHDChain(const CHDChain& chain);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user