diff options
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 131 |
1 files changed, 121 insertions, 10 deletions
diff --git a/src/main.cpp b/src/main.cpp index a51b5ae..681673c 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <atomic> | 14 | #include <atomic> |
| 15 | #include <mutex> | 15 | #include <mutex> |
| 16 | #include <thread> | 16 | #include <thread> |
| 17 | #include <system_error> | ||
| 17 | #include "bip32.h" | 18 | #include "bip32.h" |
| 18 | #include "btfaddr.h" | 19 | #include "btfaddr.h" |
| 19 | #include "btftunnel.h" | 20 | #include "btftunnel.h" |
| @@ -1843,7 +1844,7 @@ void CWalletTx::RelayWalletTransaction(CTxDB& txdb) | |||
| 1843 | uint256 hash = GetHash(); | 1844 | uint256 hash = GetHash(); |
| 1844 | if (!txdb.ContainsTx(hash)) | 1845 | if (!txdb.ContainsTx(hash)) |
| 1845 | { | 1846 | { |
| 1846 | if (LogAcceptsCategory("net")) printf("Relaying wtx %s\n", hash.ToString().substr(0,6).c_str()); | 1847 | if (LogAcceptsCategory("relay")) printf("Relaying wtx %s\n", hash.ToString().substr(0,6).c_str()); |
| 1847 | RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this); | 1848 | RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this); |
| 1848 | } | 1849 | } |
| 1849 | } | 1850 | } |
| @@ -2809,7 +2810,18 @@ bool LoadBlockIndex(bool fAllowNew) | |||
| 2809 | // CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) | 2810 | // CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) |
| 2810 | // vMerkleTree: 4a5e1e | 2811 | // vMerkleTree: 4a5e1e |
| 2811 | 2812 | ||
| 2812 | // Bitflash genesis block -- own header (fair launch, 2026 stable relaunch) | 2813 | // Bitflash genesis block -- own header (fair launch) |
| 2814 | // | ||
| 2815 | // Do not change pszTimestamp, the scriptPubKey, nTime or nNonce. They | ||
| 2816 | // are the inputs to the genesis hash, and the genesis hash is | ||
| 2817 | // consensus. Changing one on its own trips the assert below, which is | ||
| 2818 | // loud and reverts cleanly; changing one and regenerating | ||
| 2819 | // GENESIS_NONCE and hashGenesisBlock to match -- which is exactly what | ||
| 2820 | // the re-mining branch below prints out and invites -- gives a node | ||
| 2821 | // that starts without complaint, builds its own chain from height 0, | ||
| 2822 | // and rejects every real peer as being on a different chain. That one | ||
| 2823 | // fails silently, and the damage scales with how many people run the | ||
| 2824 | // "fixed" build. | ||
| 2813 | char* pszTimestamp = "Bitflash 24/Jul/2026 Fair launch: one CPU one vote, no premine"; | 2825 | char* pszTimestamp = "Bitflash 24/Jul/2026 Fair launch: one CPU one vote, no premine"; |
| 2814 | CTransaction txNew; | 2826 | CTransaction txNew; |
| 2815 | txNew.vin.resize(1); | 2827 | txNew.vin.resize(1); |
| @@ -2822,7 +2834,14 @@ bool LoadBlockIndex(bool fAllowNew) | |||
| 2822 | block.hashPrevBlock = 0; | 2834 | block.hashPrevBlock = 0; |
| 2823 | block.hashMerkleRoot = block.BuildMerkleTree(); | 2835 | block.hashMerkleRoot = block.BuildMerkleTree(); |
| 2824 | block.nVersion = 1; | 2836 | block.nVersion = 1; |
| 2825 | block.nTime = 1753315200; // 2026-07-24 00:00:00 UTC (stable relaunch) | 2837 | // 1753315200 is 2025-07-24T00:00:00Z. The headline in pszTimestamp |
| 2838 | // above reads 2026 and does not match it. This is a known discrepancy | ||
| 2839 | // and not a typo in the constant: the value is only consensus-critical | ||
| 2840 | // as an input to the genesis hash, the block hashes to | ||
| 2841 | // hashGenesisBlock with it, and every node on the network agrees. The | ||
| 2842 | // mismatch is in the launched chain and cannot be corrected -- see the | ||
| 2843 | // warning above before deciding otherwise. | ||
| 2844 | block.nTime = 1753315200; | ||
| 2826 | block.nBits = 0x1f0fffff; // = bnProofOfWorkLimit (Bitflash RandomX floor) | 2845 | block.nBits = 0x1f0fffff; // = bnProofOfWorkLimit (Bitflash RandomX floor) |
| 2827 | block.nNonce = GENESIS_NONCE; | 2846 | block.nNonce = GENESIS_NONCE; |
| 2828 | 2847 | ||
| @@ -2849,6 +2868,11 @@ bool LoadBlockIndex(bool fAllowNew) | |||
| 2849 | printf("powhash = %s\n", block.GetPoWHash().ToString().c_str()); | 2868 | printf("powhash = %s\n", block.GetPoWHash().ToString().c_str()); |
| 2850 | printf("hash = %s\n", block.GetHash().ToString().c_str()); | 2869 | printf("hash = %s\n", block.GetHash().ToString().c_str()); |
| 2851 | printf("merkle = %s\n", block.hashMerkleRoot.ToString().c_str()); | 2870 | printf("merkle = %s\n", block.hashMerkleRoot.ToString().c_str()); |
| 2871 | printf("----------------------------------------\n"); | ||
| 2872 | printf("These constants bring up a NEW chain. Do not paste them\n"); | ||
| 2873 | printf("into a build for this network to make an edited nTime or\n"); | ||
| 2874 | printf("pszTimestamp fit -- a node whose genesis differs starts\n"); | ||
| 2875 | printf("cleanly on a chain of its own and rejects every real peer.\n"); | ||
| 2852 | printf("========================================\n"); | 2876 | printf("========================================\n"); |
| 2853 | } | 2877 | } |
| 2854 | 2878 | ||
| @@ -3394,7 +3418,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) | |||
| 3394 | vRecv >> *pblock; | 3418 | vRecv >> *pblock; |
| 3395 | 3419 | ||
| 3396 | //// debug print | 3420 | //// debug print |
| 3397 | if (LogAcceptsCategory("net")) { printf("received block:\n"); pblock->print(); } | 3421 | if (LogAcceptsCategory("relay")) { printf("received block:\n"); pblock->print(); } |
| 3398 | 3422 | ||
| 3399 | CInv inv(MSG_BLOCK, pblock->GetHash()); | 3423 | CInv inv(MSG_BLOCK, pblock->GetHash()); |
| 3400 | pfrom->AddInventoryKnown(inv); | 3424 | pfrom->AddInventoryKnown(inv); |
| @@ -4183,9 +4207,32 @@ connected: | |||
| 4183 | std::vector<ParticipantShareHit> shareHits; | 4207 | std::vector<ParticipantShareHit> shareHits; |
| 4184 | std::mutex shareHitsMtx; | 4208 | std::mutex shareHitsMtx; |
| 4185 | std::vector<std::thread> hashThreads; | 4209 | std::vector<std::thread> hashThreads; |
| 4186 | for (int i = 0; i < nWorkers; i++) | 4210 | try |
| 4187 | hashThreads.emplace_back(ParticipantHashWorker, &jobShared, i, nWorkers, | 4211 | { |
| 4188 | &shareHits, &shareHitsMtx); | 4212 | for (int i = 0; i < nWorkers; i++) |
| 4213 | hashThreads.emplace_back(ParticipantHashWorker, &jobShared, i, nWorkers, | ||
| 4214 | &shareHits, &shareHitsMtx); | ||
| 4215 | } | ||
| 4216 | catch (const std::system_error& e) | ||
| 4217 | { | ||
| 4218 | // A refused pthread_create used to reach std::terminate here and | ||
| 4219 | // kill the worker mid-session -- observed twice on an otherwise | ||
| 4220 | // healthy participant. Stop the workers that did start the same way | ||
| 4221 | // the disconnect path below does, drop this pool connection, and let | ||
| 4222 | // the caller's reconnect loop try again once the pressure clears. | ||
| 4223 | LogPrint("worker", "[worker] cannot spawn hash threads (%s)" | ||
| 4224 | " -- dropping pool connection\n", e.what()); | ||
| 4225 | SetParticipantMiningStatus("hash thread spawn failed"); | ||
| 4226 | { | ||
| 4227 | std::lock_guard<std::mutex> lk(jobShared.mtx); | ||
| 4228 | jobShared.stop = true; | ||
| 4229 | jobShared.haveJob = false; | ||
| 4230 | } | ||
| 4231 | for (std::thread& t : hashThreads) | ||
| 4232 | t.join(); | ||
| 4233 | closesocket(s); | ||
| 4234 | return false; | ||
| 4235 | } | ||
| 4189 | LogPrint("worker", "[worker] spawned %d hash threads on shared RandomX dataset\n", | 4236 | LogPrint("worker", "[worker] spawned %d hash threads on shared RandomX dataset\n", |
| 4190 | nWorkers); | 4237 | nWorkers); |
| 4191 | const uint64 sessionStartHashes = gParticipantHashes.load(); | 4238 | const uint64 sessionStartHashes = gParticipantHashes.load(); |
| @@ -4196,6 +4243,14 @@ connected: | |||
| 4196 | std::string jobId; | 4243 | std::string jobId; |
| 4197 | unsigned char header[80] = {}; | 4244 | unsigned char header[80] = {}; |
| 4198 | uint256 target; | 4245 | uint256 target; |
| 4246 | // Cached answer to "which block is this job built on", for the | ||
| 4247 | // mining.notify handler below -- see the comment there. Session-local, so | ||
| 4248 | // a reconnect re-resolves rather than trusting an answer obtained before | ||
| 4249 | // a possible change of pool. | ||
| 4250 | uint256 hashPrevResolved; // prevhash the cached answer describes | ||
| 4251 | bool fPrevResolved = false; // whether that answer exists yet | ||
| 4252 | int nPrevHeight = -1; // its height, or -1 == unknown to us | ||
| 4253 | int nBestHeightResolved = -1; // nBestHeight when we last resolved | ||
| 4199 | double currentDifficulty = 1.0; // updated by mining.set_difficulty from pool | 4254 | double currentDifficulty = 1.0; // updated by mining.set_difficulty from pool |
| 4200 | bool haveJob = false; | 4255 | bool haveJob = false; |
| 4201 | bool gotSubscribeAck = false; | 4256 | bool gotSubscribeAck = false; |
| @@ -4324,8 +4379,64 @@ connected: | |||
| 4324 | jobShared.jobSeq++; | 4379 | jobShared.jobSeq++; |
| 4325 | jobShared.haveJob = true; | 4380 | jobShared.haveJob = true; |
| 4326 | } | 4381 | } |
| 4327 | LogPrint("worker", "[pool->worker] new job %s received\n", | 4382 | // Log the chain position the pool is |
| 4328 | jobId.c_str()); | 4383 | // building on, so a stale or private |
| 4384 | // fork is auditable from worker logs. | ||
| 4385 | // The prevhash comes from the header we | ||
| 4386 | // actually hash (== p[2] of the notify); | ||
| 4387 | // a brief cs_main lookup is safe here -- | ||
| 4388 | // this thread holds no other lock. | ||
| 4389 | // | ||
| 4390 | // Resolving it is the expensive half, and | ||
| 4391 | // this is the socket-reading thread: block | ||
| 4392 | // validation can hold cs_main for a long | ||
| 4393 | // time, and every moment spent waiting on | ||
| 4394 | // it here is a moment set_difficulty and | ||
| 4395 | // share responses are not being handled. | ||
| 4396 | // Most notifies in a round are a new job | ||
| 4397 | // on the SAME tip, so the answer is cached | ||
| 4398 | // and re-resolved only when it could come | ||
| 4399 | // out differently: a prevhash we have not | ||
| 4400 | // resolved, or one we could NOT resolve | ||
| 4401 | // last time while the chain has since | ||
| 4402 | // moved (unknown -> known). A block's | ||
| 4403 | // height is fixed once mapBlockIndex knows | ||
| 4404 | // it, so a cached "known" never goes | ||
| 4405 | // stale. nBestHeight is read unlocked on | ||
| 4406 | // purpose -- it only decides whether to | ||
| 4407 | // repeat a lookup, never what gets | ||
| 4408 | // printed, so a stale read costs at most | ||
| 4409 | // one deferred or one extra lookup. | ||
| 4410 | // The line still prints in full for every | ||
| 4411 | // job, cached or not. | ||
| 4412 | uint256 hashPrev; | ||
| 4413 | memcpy(&hashPrev, header + 4, 32); | ||
| 4414 | if (LogAcceptsCategory("worker")) | ||
| 4415 | { | ||
| 4416 | int nBestHeightNow = nBestHeight; | ||
| 4417 | if (!fPrevResolved | ||
| 4418 | || hashPrev != hashPrevResolved | ||
| 4419 | || (nPrevHeight < 0 && nBestHeightNow != nBestHeightResolved)) | ||
| 4420 | { | ||
| 4421 | nPrevHeight = -1; | ||
| 4422 | CRITICAL_BLOCK(cs_main) | ||
| 4423 | { | ||
| 4424 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrev); | ||
| 4425 | if (mi != mapBlockIndex.end()) | ||
| 4426 | nPrevHeight = (*mi).second->nHeight; | ||
| 4427 | } | ||
| 4428 | hashPrevResolved = hashPrev; | ||
| 4429 | nBestHeightResolved = nBestHeightNow; | ||
| 4430 | fPrevResolved = true; | ||
| 4431 | } | ||
| 4432 | if (nPrevHeight >= 0) | ||
| 4433 | LogPrint("worker", "[pool->worker] new job %s received, prevhash %s (known, job height %d)\n", | ||
| 4434 | jobId.c_str(), hashPrev.GetHex().c_str(), | ||
| 4435 | nPrevHeight + 1); | ||
| 4436 | else | ||
| 4437 | LogPrint("worker", "[pool->worker] new job %s received, prevhash %s (unknown to our chain)\n", | ||
| 4438 | jobId.c_str(), hashPrev.GetHex().c_str()); | ||
| 4439 | } | ||
| 4329 | SetParticipantMiningStatus("hashing job " + jobId); | 4440 | SetParticipantMiningStatus("hashing job " + jobId); |
| 4330 | } | 4441 | } |
| 4331 | } | 4442 | } |
| @@ -4839,7 +4950,7 @@ bool BitcoinMiner(int nThreadId) | |||
| 4839 | //// debug print | 4950 | //// debug print |
| 4840 | if (LogAcceptsCategory("net")) printf("BitcoinMiner:\n"); | 4951 | if (LogAcceptsCategory("net")) printf("BitcoinMiner:\n"); |
| 4841 | if (LogAcceptsCategory("net")) printf("RandomX proof-of-work found \n powhash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); | 4952 | if (LogAcceptsCategory("net")) printf("RandomX proof-of-work found \n powhash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); |
| 4842 | if (LogAcceptsCategory("net")) pblock->print(); | 4953 | if (LogAcceptsCategory("relay")) pblock->print(); |
| 4843 | 4954 | ||
| 4844 | SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); | 4955 | SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); |
| 4845 | CRITICAL_BLOCK(cs_main) | 4956 | CRITICAL_BLOCK(cs_main) |