Fix segfault by indirectly monitoring chainActive.Tip(), locking on mutex
This commit is contained in:
@@ -205,8 +205,7 @@ std::set<std::vector<eh_index>> Equihash<N,K>::BasicSolve(const eh_HashState& ba
|
|||||||
X.reserve(init_size);
|
X.reserve(init_size);
|
||||||
for (eh_index i = 0; i < init_size; i++) {
|
for (eh_index i = 0; i < init_size; i++) {
|
||||||
X.emplace_back(N, base_state, i);
|
X.emplace_back(N, base_state, i);
|
||||||
// Slow down checking to prevent segfaults (??)
|
if (cancelled(ListGeneration)) throw solver_cancelled;
|
||||||
if (i % 10000 == 0 && cancelled(ListGeneration)) throw solver_cancelled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3) Repeat step 2 until 2n/(k+1) bits remain
|
// 3) Repeat step 2 until 2n/(k+1) bits remain
|
||||||
@@ -375,8 +374,7 @@ std::set<std::vector<eh_index>> Equihash<N,K>::OptimisedSolve(const eh_HashState
|
|||||||
Xt.reserve(init_size);
|
Xt.reserve(init_size);
|
||||||
for (eh_index i = 0; i < init_size; i++) {
|
for (eh_index i = 0; i < init_size; i++) {
|
||||||
Xt.emplace_back(N, base_state, i, CollisionBitLength + 1);
|
Xt.emplace_back(N, base_state, i, CollisionBitLength + 1);
|
||||||
// Slow down checking to prevent segfaults (??)
|
if (cancelled(ListGeneration)) throw solver_cancelled;
|
||||||
if (i % 10000 == 0 && cancelled(ListGeneration)) throw solver_cancelled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3) Repeat step 2 until 2n/(k+1) bits remain
|
// 3) Repeat step 2 until 2n/(k+1) bits remain
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
#include <boost/tuple/tuple.hpp>
|
#include <boost/tuple/tuple.hpp>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -455,6 +456,15 @@ void static BitcoinMiner(CWallet *pwallet)
|
|||||||
unsigned int n = chainparams.EquihashN();
|
unsigned int n = chainparams.EquihashN();
|
||||||
unsigned int k = chainparams.EquihashK();
|
unsigned int k = chainparams.EquihashK();
|
||||||
|
|
||||||
|
std::mutex m_cs;
|
||||||
|
bool cancelSolver = false;
|
||||||
|
boost::signals2::connection c = uiInterface.NotifyBlockTip.connect(
|
||||||
|
[&m_cs, &cancelSolver](const uint256& hashNewTip) mutable {
|
||||||
|
std::lock_guard<std::mutex> lock{m_cs};
|
||||||
|
cancelSolver = true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (chainparams.MiningRequiresPeers()) {
|
if (chainparams.MiningRequiresPeers()) {
|
||||||
@@ -521,12 +531,15 @@ void static BitcoinMiner(CWallet *pwallet)
|
|||||||
pblock->nNonce.ToString());
|
pblock->nNonce.ToString());
|
||||||
std::set<std::vector<unsigned int>> solns;
|
std::set<std::vector<unsigned int>> solns;
|
||||||
try {
|
try {
|
||||||
std::function<bool(EhSolverCancelCheck)> cancelled = [pindexPrev](EhSolverCancelCheck pos) {
|
std::function<bool(EhSolverCancelCheck)> cancelled = [&m_cs, &cancelSolver](EhSolverCancelCheck pos) {
|
||||||
return pindexPrev != chainActive.Tip();
|
std::lock_guard<std::mutex> lock{m_cs};
|
||||||
|
return cancelSolver;
|
||||||
};
|
};
|
||||||
EhOptimisedSolve(n, k, curr_state, solns, cancelled);
|
EhOptimisedSolve(n, k, curr_state, solns, cancelled);
|
||||||
} catch (EhSolverCancelledException&) {
|
} catch (EhSolverCancelledException&) {
|
||||||
LogPrint("pow", "Equihash solver cancelled\n");
|
LogPrint("pow", "Equihash solver cancelled\n");
|
||||||
|
std::lock_guard<std::mutex> lock{m_cs};
|
||||||
|
cancelSolver = false;
|
||||||
}
|
}
|
||||||
LogPrint("pow", "Solutions: %d\n", solns.size());
|
LogPrint("pow", "Solutions: %d\n", solns.size());
|
||||||
|
|
||||||
@@ -542,7 +555,11 @@ void static BitcoinMiner(CWallet *pwallet)
|
|||||||
SetThreadPriority(THREAD_PRIORITY_NORMAL);
|
SetThreadPriority(THREAD_PRIORITY_NORMAL);
|
||||||
LogPrintf("ZcashMiner:\n");
|
LogPrintf("ZcashMiner:\n");
|
||||||
LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex());
|
LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex());
|
||||||
ProcessBlockFound(pblock, *pwallet, reservekey);
|
if (ProcessBlockFound(pblock, *pwallet, reservekey)) {
|
||||||
|
// Ignore chain updates caused by us
|
||||||
|
std::lock_guard<std::mutex> lock{m_cs};
|
||||||
|
cancelSolver = false;
|
||||||
|
}
|
||||||
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
||||||
|
|
||||||
// In regression test mode, stop mining after a block is found.
|
// In regression test mode, stop mining after a block is found.
|
||||||
@@ -585,6 +602,7 @@ void static BitcoinMiner(CWallet *pwallet)
|
|||||||
LogPrintf("ZcashMiner runtime error: %s\n", e.what());
|
LogPrintf("ZcashMiner runtime error: %s\n", e.what());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
c.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads)
|
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads)
|
||||||
|
|||||||
Reference in New Issue
Block a user