upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp131
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)