diff options
| author | Bitflash <btf01@proton.me> | 2026-08-01 12:56:16 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-01 12:56:16 -0300 |
| commit | 7131c30c33c980f0ba1d37dfc6a3fbe8c319813e (patch) | |
| tree | 668de28f9aec4f8f350146f1d824b487752cf747 /src/main.h | |
| parent | b426948b966405b65f3ea6c1994164b462980694 (diff) | |
wallet: generate keys ahead of use so a backup outlives the next block (#85)
The wallet made a key per address and per block mined, so a backup only ever
contained the keys that existed the moment it was taken -- mine one block and
the coin lands on a key the backup has never heard of. The README warned about
it, which is an admission rather than a fix.
Keys are now generated a hundred at a time and handed out one at a time, each
written to wallet.dat before it can be pointed at. A backup covers the next
hundred addresses. Deterministic derivation (#47) stays open; this buys back the
distance between a backup and the next mistake.
Diffstat (limited to 'src/main.h')
| -rw-r--r-- | src/main.h | 26 |
1 files changed, 26 insertions, 0 deletions
| @@ -124,6 +124,32 @@ FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszM | |||
| 124 | FILE* AppendBlockFile(unsigned int& nFileRet); | 124 | FILE* AppendBlockFile(unsigned int& nFileRet); |
| 125 | bool AddKey(const CKey& key); | 125 | bool AddKey(const CKey& key); |
| 126 | vector<unsigned char> GenerateNewKey(); | 126 | vector<unsigned char> GenerateNewKey(); |
| 127 | |||
| 128 | // --- Key pool ------------------------------------------------------------- | ||
| 129 | // | ||
| 130 | // A backup of this wallet only ever contained the keys that existed the moment | ||
| 131 | // it was taken. Mine a block or take a new address afterwards and the coin | ||
| 132 | // lands on a key the backup has never heard of -- it is on the chain, and the | ||
| 133 | // file you carefully put away cannot spend it. The LEIA-ME shipped with a | ||
| 134 | // warning about this, which is an admission, not a fix. | ||
| 135 | // | ||
| 136 | // Keys are now generated a hundred at a time and handed out one by one, so a | ||
| 137 | // backup covers the next hundred addresses this node will use. It is the same | ||
| 138 | // answer Bitcoin arrived at, and it is not deterministic derivation (#47) -- | ||
| 139 | // it just buys back the distance between a backup and the next mistake. | ||
| 140 | static const int KEYPOOL_SIZE = 100; | ||
| 141 | extern CCriticalSection cs_keyPool; | ||
| 142 | extern map<int64, vector<unsigned char> > mapKeyPool; | ||
| 143 | |||
| 144 | // Fill the pool back up to KEYPOOL_SIZE. Every key it creates is written to | ||
| 145 | // wallet.dat before it is offered to anybody. | ||
| 146 | void TopUpKeyPool(); | ||
| 147 | |||
| 148 | // Hand out the oldest unused key. Falls back to generating one on the spot if | ||
| 149 | // the pool cannot be filled, which is exactly what this code did before the | ||
| 150 | // pool existed -- a wallet that cannot pre-generate should still be able to | ||
| 151 | // mine. | ||
| 152 | vector<unsigned char> GetKeyFromPool(); | ||
| 127 | bool AddToWallet(const CWalletTx& wtxIn); | 153 | bool AddToWallet(const CWalletTx& wtxIn); |
| 128 | void ReacceptWalletTransactions(); | 154 | void ReacceptWalletTransactions(); |
| 129 | // Returns how many wallet transactions the chain corrected. | 155 | // Returns how many wallet transactions the chain corrected. |