Wallet Database
Wallets are stored on disk as databases, either using Berkeley Database (BDB) or sqlite format.
The version of BDB we used for the wallet is unmaintained, so new wallets should prefer sqlite format |
The wallet is stored on disk as a Key Value store.
These are some of the records which help us regenerate a descriptor wallet (populating a DescriptorScriptPubKeyMan
(DSPKM)) from the database:
// walletdb.cpp
const std::string WALLETDESCRIPTOR{"walletdescriptor"};
const std::string WALLETDESCRIPTORCACHE{"walletdescriptorcache"};
const std::string WALLETDESCRIPTORLHCACHE{"walletdescriptorlhcache"};
const std::string WALLETDESCRIPTORCKEY{"walletdescriptorckey"};
const std::string WALLETDESCRIPTORKEY{"walletdescriptorkey"};
For Legacy wallets (populating a LegacyScriptPubKeyMan
(LSPKM)) we use the records with *.KEY
& SCRIPT
.
Wallet metadata may include a tipLocator
— the most recent tip — and a wallet version
which is used in database upgrades.
To load the wallet we read the database by iterating the records and loading them to CWallet
, using ReadKeyValue()
to deserialize.
Record | Load point |
---|---|
| (Bitcoin) transactions end up in |
| Keys for legacy wallets are loaded into |
| Descriptor wallet information generally goes into |
| Addresses go into |
You can see where all the other DB records are deserialized to by examining the ReadKeyValue()
function.
The various *ScriptPubkeyMan
objects are all owned by the CWallet
instance eventually, however LegacyScriptPubKeyMan
is both created and owned by CWallet
, whereas DescriptorScriptPubKeyMan
is created externally to CWallet
and only after loading exists in the CWallet
context.
Note that TxSpends
is not tracked in the wallet database (and loaded at startup), but instead is rebuilt from scratch because it’s fast to do so and we must reload every transaction anyway, so it’s not much more work to regenerate TxSpends
at the same time.