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.cpp104
1 files changed, 96 insertions, 8 deletions
diff --git a/src/main.cpp b/src/main.cpp
index a68e3b0..dded83a 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"
@@ -1712,7 +1713,7 @@ void CWalletTx::RelayWalletTransaction(CTxDB& txdb)
1712 uint256 hash = GetHash(); 1713 uint256 hash = GetHash();
1713 if (!txdb.ContainsTx(hash)) 1714 if (!txdb.ContainsTx(hash))
1714 { 1715 {
1715 if (LogAcceptsCategory("net")) printf("Relaying wtx %s\n", hash.ToString().substr(0,6).c_str()); 1716 if (LogAcceptsCategory("relay")) printf("Relaying wtx %s\n", hash.ToString().substr(0,6).c_str());
1716 RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this); 1717 RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this);
1717 } 1718 }
1718 } 1719 }
@@ -3286,7 +3287,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
3286 vRecv >> *pblock; 3287 vRecv >> *pblock;
3287 3288
3288 //// debug print 3289 //// debug print
3289 if (LogAcceptsCategory("net")) { printf("received block:\n"); pblock->print(); } 3290 if (LogAcceptsCategory("relay")) { printf("received block:\n"); pblock->print(); }
3290 3291
3291 CInv inv(MSG_BLOCK, pblock->GetHash()); 3292 CInv inv(MSG_BLOCK, pblock->GetHash());
3292 pfrom->AddInventoryKnown(inv); 3293 pfrom->AddInventoryKnown(inv);
@@ -3922,9 +3923,32 @@ connected:
3922 std::vector<ParticipantShareHit> shareHits; 3923 std::vector<ParticipantShareHit> shareHits;
3923 std::mutex shareHitsMtx; 3924 std::mutex shareHitsMtx;
3924 std::vector<std::thread> hashThreads; 3925 std::vector<std::thread> hashThreads;
3925 for (int i = 0; i < nWorkers; i++) 3926 try
3926 hashThreads.emplace_back(ParticipantHashWorker, &jobShared, i, nWorkers, 3927 {
3927 &shareHits, &shareHitsMtx); 3928 for (int i = 0; i < nWorkers; i++)
3929 hashThreads.emplace_back(ParticipantHashWorker, &jobShared, i, nWorkers,
3930 &shareHits, &shareHitsMtx);
3931 }
3932 catch (const std::system_error& e)
3933 {
3934 // A refused pthread_create used to reach std::terminate here and
3935 // kill the worker mid-session -- observed twice on an otherwise
3936 // healthy participant. Stop the workers that did start the same way
3937 // the disconnect path below does, drop this pool connection, and let
3938 // the caller's reconnect loop try again once the pressure clears.
3939 LogPrint("worker", "[worker] cannot spawn hash threads (%s)"
3940 " -- dropping pool connection\n", e.what());
3941 SetParticipantMiningStatus("hash thread spawn failed");
3942 {
3943 std::lock_guard<std::mutex> lk(jobShared.mtx);
3944 jobShared.stop = true;
3945 jobShared.haveJob = false;
3946 }
3947 for (std::thread& t : hashThreads)
3948 t.join();
3949 closesocket(s);
3950 return false;
3951 }
3928 LogPrint("worker", "[worker] spawned %d hash threads on shared RandomX dataset\n", 3952 LogPrint("worker", "[worker] spawned %d hash threads on shared RandomX dataset\n",
3929 nWorkers); 3953 nWorkers);
3930 const uint64 sessionStartHashes = gParticipantHashes.load(); 3954 const uint64 sessionStartHashes = gParticipantHashes.load();
@@ -3935,6 +3959,14 @@ connected:
3935 std::string jobId; 3959 std::string jobId;
3936 unsigned char header[80] = {}; 3960 unsigned char header[80] = {};
3937 uint256 target; 3961 uint256 target;
3962 // Cached answer to "which block is this job built on", for the
3963 // mining.notify handler below -- see the comment there. Session-local, so
3964 // a reconnect re-resolves rather than trusting an answer obtained before
3965 // a possible change of pool.
3966 uint256 hashPrevResolved; // prevhash the cached answer describes
3967 bool fPrevResolved = false; // whether that answer exists yet
3968 int nPrevHeight = -1; // its height, or -1 == unknown to us
3969 int nBestHeightResolved = -1; // nBestHeight when we last resolved
3938 double currentDifficulty = 1.0; // updated by mining.set_difficulty from pool 3970 double currentDifficulty = 1.0; // updated by mining.set_difficulty from pool
3939 bool haveJob = false; 3971 bool haveJob = false;
3940 bool gotSubscribeAck = false; 3972 bool gotSubscribeAck = false;
@@ -4063,8 +4095,64 @@ connected:
4063 jobShared.jobSeq++; 4095 jobShared.jobSeq++;
4064 jobShared.haveJob = true; 4096 jobShared.haveJob = true;
4065 } 4097 }
4066 LogPrint("worker", "[pool->worker] new job %s received\n", 4098 // Log the chain position the pool is
4067 jobId.c_str()); 4099 // building on, so a stale or private
4100 // fork is auditable from worker logs.
4101 // The prevhash comes from the header we
4102 // actually hash (== p[2] of the notify);
4103 // a brief cs_main lookup is safe here --
4104 // this thread holds no other lock.
4105 //
4106 // Resolving it is the expensive half, and
4107 // this is the socket-reading thread: block
4108 // validation can hold cs_main for a long
4109 // time, and every moment spent waiting on
4110 // it here is a moment set_difficulty and
4111 // share responses are not being handled.
4112 // Most notifies in a round are a new job
4113 // on the SAME tip, so the answer is cached
4114 // and re-resolved only when it could come
4115 // out differently: a prevhash we have not
4116 // resolved, or one we could NOT resolve
4117 // last time while the chain has since
4118 // moved (unknown -> known). A block's
4119 // height is fixed once mapBlockIndex knows
4120 // it, so a cached "known" never goes
4121 // stale. nBestHeight is read unlocked on
4122 // purpose -- it only decides whether to
4123 // repeat a lookup, never what gets
4124 // printed, so a stale read costs at most
4125 // one deferred or one extra lookup.
4126 // The line still prints in full for every
4127 // job, cached or not.
4128 uint256 hashPrev;
4129 memcpy(&hashPrev, header + 4, 32);
4130 if (LogAcceptsCategory("worker"))
4131 {
4132 int nBestHeightNow = nBestHeight;
4133 if (!fPrevResolved
4134 || hashPrev != hashPrevResolved
4135 || (nPrevHeight < 0 && nBestHeightNow != nBestHeightResolved))
4136 {
4137 nPrevHeight = -1;
4138 CRITICAL_BLOCK(cs_main)
4139 {
4140 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrev);
4141 if (mi != mapBlockIndex.end())
4142 nPrevHeight = (*mi).second->nHeight;
4143 }
4144 hashPrevResolved = hashPrev;
4145 nBestHeightResolved = nBestHeightNow;
4146 fPrevResolved = true;
4147 }
4148 if (nPrevHeight >= 0)
4149 LogPrint("worker", "[pool->worker] new job %s received, prevhash %s (known, job height %d)\n",
4150 jobId.c_str(), hashPrev.GetHex().c_str(),
4151 nPrevHeight + 1);
4152 else
4153 LogPrint("worker", "[pool->worker] new job %s received, prevhash %s (unknown to our chain)\n",
4154 jobId.c_str(), hashPrev.GetHex().c_str());
4155 }
4068 SetParticipantMiningStatus("hashing job " + jobId); 4156 SetParticipantMiningStatus("hashing job " + jobId);
4069 } 4157 }
4070 } 4158 }
@@ -4578,7 +4666,7 @@ bool BitcoinMiner(int nThreadId)
4578 //// debug print 4666 //// debug print
4579 if (LogAcceptsCategory("net")) printf("BitcoinMiner:\n"); 4667 if (LogAcceptsCategory("net")) printf("BitcoinMiner:\n");
4580 if (LogAcceptsCategory("net")) printf("RandomX proof-of-work found \n powhash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); 4668 if (LogAcceptsCategory("net")) printf("RandomX proof-of-work found \n powhash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());
4581 if (LogAcceptsCategory("net")) pblock->print(); 4669 if (LogAcceptsCategory("relay")) pblock->print();
4582 4670
4583 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); 4671 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
4584 CRITICAL_BLOCK(cs_main) 4672 CRITICAL_BLOCK(cs_main)