The process of saving wallet data into disk is currently unspecified. The key-values used in the current implementation are undocumented, and their structure and functionality are unknown without a deep analysis of the involved source code. This document details the schema and the mechanics of the wallet database. This is an informational document, no changes will be done to the source code.
The main purpose of this is the persistence of public and private keys the user created and the ability to recover the wallet state after a node restart. This file also allows the migration of user information from one node to another by moving the database to the corresponding new data directory, assuming both zcashd instances are running the same or similar version. A re-index may be necessary after this operation.
The current database is a key-value store where keys and values can have multiple data types in binary format. The first data found in a database key is always the property name, the rest of the key is generally used to identify a record, for example::
Here ``zkey`` is the property name located at the first position of the database key; the public key is also part of the database key, and it is located in the second position; the private key is saved in the database value column at the first position.
According to Zcash v3.0.0-rc1 the following key-values can be found: the property names in **bold** mean only one instance of this type can exist in the entire database, while the others, suffixed by '\*' can have multiple instances. Keys and Values columns of the table contain the types that the stored data is representing. Included also there are the variable names hoping it will add some clarity to what the stored data is representing.
*``DEFAULT_KEYPOOL_SIZE`` (100 by default) keys will be added to the pool, creating 100 records with ``pool`` as property name (first value of database key).
*``version``, ``minversion``, ``witnesscachesize`` and ``bestblock`` properties are added. These are settings and state information: the ``bestblock`` property is a good example of the database being populated that is happening without any user interaction, but it will just update as the best block of the current chain changes.
At any time after the database is created, new properties can be added as the wallet users perform actions. For example, if the user creates a new Sapling address with the RPC command ``z_getnewaddress`` then new records with properties `sapzkey` and `sapzkeymeta` will be added to the database.
In zcashd, database changes do not happen immediately but they are flushed in its own thread by ``ThreadFlushWalletDB()`` function periodically to avoid overhead. The internal counter ``nWalletDBUpdated`` is increased each time a new write operation to the database is done, this is compared with the last flush in order to commit new stuff.
When the node goes down for whatever reason the information in the wallet database SHOULD persist in the disk; the next time the node starts, the software will detect the database file, read from there and add the values into memory structures that will guarantee wallet functionality.
The wallet database will not save all the transactions that are happening in the blockchain however it will save all transactions where wallet keys are involved. This is needed for example to get balances. Therefore the wallet must have all the transactions related to a key to compute the final value of coin available in the derived address.
Transactions are saved in the database ``tx`` key as they arrive, this means transactions have a sequence. The set of all transactions from the begging to a specified timestamp is the wallet state at that instant. Wallet state is important among other things to get current balance for a wallet or address.
In the blockchain, transactions can be invalidated by rollbacks; wallet code will handle this by updating the transactions in the memory database. New state needs to be reflected in the disk database, this is done in zcashd by the flag ``fAnyUnordered`` where if true at start time, will launch a rescan over all transactions again.
Encryption will not be discussed in this document in detail as it is expected for the algorithm to change in the future according to the Wallet format ZIP issue: [#ZIP400Issue]_.
For a deeper understanding of the current encryption mechanism please refer to [#CrypterCode]_
References
==========
..[#RFC2119]`Key words for use in RFCs to Indicate Requirement Levels <https://www.rfc-editor.org/rfc/rfc2119.html>`_