From 07ba3481e2624d85eaf5ff5808bd2d0280bcbb22 Mon Sep 17 00:00:00 2001 From: Bitflash Date: Sat, 1 Aug 2026 14:29:28 -0300 Subject: mine: do not trust a stored generate flag with no mining mode beside it (#87) fGenerateBitcoins and nMineMode only mean anything together, and a wallet.dat can hold one without the other: Bitcoin 0.1.0 already wrote fGenerateBitcoins when mining was toggled, years before this fork had a mode. #84 restored that lone flag, which puts the node in the one state the miner cannot act on -- generate on, mode relay -- so every miner thread starts and returns at the relay guard. The machine looks like it is mining and hashes nothing. That happened to a 32-core node on its first 1.2.11 start: "Mining with 31 thread(s)" followed by 31 lines of "BitcoinMiner thread N returned true". The flag is now believed only when the mode it belongs to was stored with it, and the pair is made coherent either way. --- src/db.cpp | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'src/db.cpp') diff --git a/src/db.cpp b/src/db.cpp index 3af87fb..7763af8 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -551,6 +551,9 @@ bool CReviewDB::WriteReviews(uint256 hash, const vector& vReviews) bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) { + // Whether wallet.dat actually carried a mining mode, as opposed to just the + // ancient fGenerateBitcoins flag. See the reconciliation further down. + bool fHaveStoredMineMode = false; vchDefaultKeyRet.clear(); // Satoshi's "todo: shouldn't we catch exceptions" sat here since 2009, and @@ -669,7 +672,7 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) // participant cannot work without. if (!fMineModeFromCommandLine) { - if (strKey == "nMineMode") ssValue >> nMineMode; + if (strKey == "nMineMode") { ssValue >> nMineMode; fHaveStoredMineMode = true; } if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins; if (strKey == "strParticipantPool") ssValue >> strParticipantPool; } @@ -692,6 +695,32 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) return false; } + // fGenerateBitcoins and nMineMode only mean anything together, and a + // wallet.dat can easily hold one without the other: Bitcoin 0.1.0 already + // wrote fGenerateBitcoins when mining was toggled, years before this fork + // had a mode at all. Restoring that lone flag put a node into the one state + // the miner cannot act on -- generate on, mode relay -- so every miner + // thread started and returned at the relay guard, and the machine sat there + // looking like it was mining while hashing nothing. That happened to a + // 32-core node on the first 1.2.11 start. + // + // So the flag is only believed when the mode it belongs to was stored with + // it, and the pair is made coherent either way. + if (!fMineModeFromCommandLine) + { + if (!fHaveStoredMineMode) + { + if (fGenerateBitcoins) + printf("LoadWallet: ignoring a stored fGenerateBitcoins with no mining mode " + "beside it -- it predates this setting and cannot be read on its own\n"); + fGenerateBitcoins = 0; + } + else + { + fGenerateBitcoins = (nMineMode != MINE_RELAY) ? 1 : 0; + } + } + printf("nTransactionFee = %lld\n", nTransactionFee); printf("addrIncoming = %s\n", addrIncoming.ToString().c_str()); printf("nMineMode = %d, strParticipantPool = %s, fGenerateBitcoins = %d (%s)\n", -- cgit v1.2.3