diff options
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 104 |
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) |