|
|
@ -126,7 +126,7 @@ void Client::killChain() |
|
|
|
|
|
|
|
m_tq.clear(); |
|
|
|
m_bq.clear(); |
|
|
|
m_miners.clear(); |
|
|
|
m_localMiners.clear(); |
|
|
|
m_preMine = State(); |
|
|
|
m_postMine = State(); |
|
|
|
|
|
|
@ -167,8 +167,8 @@ void Client::clearPending() |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
|
ReadGuard l(x_miners); |
|
|
|
for (auto& m: m_miners) |
|
|
|
ReadGuard l(x_localMiners); |
|
|
|
for (auto& m: m_localMiners) |
|
|
|
m.noteStateChange(); |
|
|
|
} |
|
|
|
|
|
|
@ -320,8 +320,8 @@ void Client::appendFromNewBlock(h256 const& _block, h256Set& io_changed) |
|
|
|
void Client::setForceMining(bool _enable) |
|
|
|
{ |
|
|
|
m_forceMining = _enable; |
|
|
|
ReadGuard l(x_miners); |
|
|
|
for (auto& m: m_miners) |
|
|
|
ReadGuard l(x_localMiners); |
|
|
|
for (auto& m: m_localMiners) |
|
|
|
m.noteStateChange(); |
|
|
|
} |
|
|
|
|
|
|
@ -330,19 +330,19 @@ void Client::setMiningThreads(unsigned _threads) |
|
|
|
stopMining(); |
|
|
|
|
|
|
|
auto t = _threads ? _threads : thread::hardware_concurrency(); |
|
|
|
WriteGuard l(x_miners); |
|
|
|
m_miners.clear(); |
|
|
|
m_miners.resize(t); |
|
|
|
WriteGuard l(x_localMiners); |
|
|
|
m_localMiners.clear(); |
|
|
|
m_localMiners.resize(t); |
|
|
|
unsigned i = 0; |
|
|
|
for (auto& m: m_miners) |
|
|
|
for (auto& m: m_localMiners) |
|
|
|
m.setup(this, i++); |
|
|
|
} |
|
|
|
|
|
|
|
MineProgress Client::miningProgress() const |
|
|
|
{ |
|
|
|
MineProgress ret; |
|
|
|
ReadGuard l(x_miners); |
|
|
|
for (auto& m: m_miners) |
|
|
|
ReadGuard l(x_localMiners); |
|
|
|
for (auto& m: m_localMiners) |
|
|
|
ret.combine(m.miningProgress()); |
|
|
|
return ret; |
|
|
|
} |
|
|
@ -351,13 +351,13 @@ std::list<MineInfo> Client::miningHistory() |
|
|
|
{ |
|
|
|
std::list<MineInfo> ret; |
|
|
|
|
|
|
|
ReadGuard l(x_miners); |
|
|
|
if (m_miners.empty()) |
|
|
|
ReadGuard l(x_localMiners); |
|
|
|
if (m_localMiners.empty()) |
|
|
|
return ret; |
|
|
|
ret = m_miners[0].miningHistory(); |
|
|
|
for (unsigned i = 1; i < m_miners.size(); ++i) |
|
|
|
ret = m_localMiners[0].miningHistory(); |
|
|
|
for (unsigned i = 1; i < m_localMiners.size(); ++i) |
|
|
|
{ |
|
|
|
auto l = m_miners[i].miningHistory(); |
|
|
|
auto l = m_localMiners[i].miningHistory(); |
|
|
|
auto ri = ret.begin(); |
|
|
|
auto li = l.begin(); |
|
|
|
for (; ri != ret.end() && li != l.end(); ++ri, ++li) |
|
|
@ -474,6 +474,22 @@ void Client::inject(bytesConstRef _rlp) |
|
|
|
m_tq.attemptImport(_rlp); |
|
|
|
} |
|
|
|
|
|
|
|
pair<h256, u256> Client::getWork() |
|
|
|
{ |
|
|
|
Guard l(x_remoteMiner); |
|
|
|
{ |
|
|
|
ReadGuard l(x_stateDB); |
|
|
|
m_remoteMiner.update(m_postMine, m_bc); |
|
|
|
} |
|
|
|
return make_pair(m_remoteMiner.workHash(), m_remoteMiner.difficulty()); |
|
|
|
} |
|
|
|
|
|
|
|
bool Client::submitNonce(h256 const&_nonce) |
|
|
|
{ |
|
|
|
Guard l(x_remoteMiner); |
|
|
|
return m_remoteMiner.submitWork(_nonce); |
|
|
|
} |
|
|
|
|
|
|
|
void Client::doWork() |
|
|
|
{ |
|
|
|
// TODO: Use condition variable rather than polling.
|
|
|
@ -481,9 +497,8 @@ void Client::doWork() |
|
|
|
cworkin << "WORK"; |
|
|
|
h256Set changeds; |
|
|
|
|
|
|
|
auto maintainMiner = [&](Miner& m) |
|
|
|
{ |
|
|
|
ReadGuard l(x_miners); |
|
|
|
for (auto& m: m_miners) |
|
|
|
if (m.isComplete()) |
|
|
|
{ |
|
|
|
cwork << "CHAIN <== postSTATE"; |
|
|
@ -494,14 +509,22 @@ void Client::doWork() |
|
|
|
} |
|
|
|
if (hs.size()) |
|
|
|
{ |
|
|
|
for (auto h: hs) |
|
|
|
for (auto const& h: hs) |
|
|
|
appendFromNewBlock(h, changeds); |
|
|
|
changeds.insert(ChainChangedFilter); |
|
|
|
//changeds.insert(PendingChangedFilter); // if we mined the new block, then we've probably reset the pending transactions.
|
|
|
|
} |
|
|
|
for (auto& m: m_miners) |
|
|
|
for (auto& m: m_localMiners) |
|
|
|
m.noteStateChange(); |
|
|
|
} |
|
|
|
}; |
|
|
|
{ |
|
|
|
ReadGuard l(x_localMiners); |
|
|
|
for (auto& m: m_localMiners) |
|
|
|
maintainMiner(m); |
|
|
|
} |
|
|
|
{ |
|
|
|
Guard l(x_remoteMiner); |
|
|
|
maintainMiner(m_remoteMiner); |
|
|
|
} |
|
|
|
|
|
|
|
// Synchronise state to block chain.
|
|
|
@ -511,7 +534,7 @@ void Client::doWork() |
|
|
|
// if there are no checkpoints before our fork) reverting to the genesis block and replaying
|
|
|
|
// all blocks.
|
|
|
|
// Resynchronise state with block chain & trans
|
|
|
|
bool rsm = false; |
|
|
|
bool resyncStateNeeded = false; |
|
|
|
{ |
|
|
|
WriteGuard l(x_stateDB); |
|
|
|
cwork << "BQ ==> CHAIN ==> STATE"; |
|
|
@ -534,7 +557,7 @@ void Client::doWork() |
|
|
|
if (isMining()) |
|
|
|
cnote << "New block on chain: Restarting mining operation."; |
|
|
|
m_postMine = m_preMine; |
|
|
|
rsm = true; |
|
|
|
resyncStateNeeded = true; |
|
|
|
changeds.insert(PendingChangedFilter); |
|
|
|
// TODO: Move transactions pending from m_postMine back to transaction queue.
|
|
|
|
} |
|
|
@ -550,13 +573,13 @@ void Client::doWork() |
|
|
|
|
|
|
|
if (isMining()) |
|
|
|
cnote << "Additional transaction ready: Restarting mining operation."; |
|
|
|
rsm = true; |
|
|
|
resyncStateNeeded = true; |
|
|
|
} |
|
|
|
} |
|
|
|
if (rsm) |
|
|
|
if (resyncStateNeeded) |
|
|
|
{ |
|
|
|
ReadGuard l(x_miners); |
|
|
|
for (auto& m: m_miners) |
|
|
|
ReadGuard l(x_localMiners); |
|
|
|
for (auto& m: m_localMiners) |
|
|
|
m.noteStateChange(); |
|
|
|
} |
|
|
|
|
|
|
|