Skip to content

Commit c76ae43

Browse files
committed
Use atomic block flag
1 parent 110786f commit c76ae43

File tree

3 files changed

+43
-39
lines changed

3 files changed

+43
-39
lines changed

src/miner/internal/miner-base.cpp

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,28 @@ void MinerBase::Loop()
2525
RenameThread(tfm::format("dynamic-%s-miner-%d", DeviceName(), _device_index).data());
2626

2727
CBlock block;
28-
CBlockIndex* current_tip = nullptr;
28+
CBlockIndex* chain_tip = nullptr;
29+
std::uint64_t block_flag = 0;
2930
std::shared_ptr<CBlockTemplate> block_template = {nullptr};
3031

3132
try {
3233
while (true) {
33-
// Get blockchain tip
34-
CBlockIndex* next_tip = _ctx->tip();
35-
// Get shared block template
36-
auto next_template = _ctx->block_template();
37-
assert(next_template != nullptr);
38-
CBlock& next_block = next_template->block;
3934
// Update block and tip if changed
40-
if (current_tip != next_tip || (next_block.nBits != block.nBits && next_block.nTime > block.nTime)) {
41-
block = next_block;
42-
block_template = next_template;
43-
current_tip = next_tip;
35+
if (block_flag != _ctx->block_flag()) {
36+
// set new block template
37+
block_template = _ctx->block_template();
38+
block = block_template->block;
39+
// set block flag only after template
40+
// so we've waited for RecreateBlock
41+
block_flag = _ctx->block_flag();
42+
// block chain tip
43+
chain_tip = _ctx->tip();
4444
}
4545
// Make sure we have a tip
46-
assert(current_tip != nullptr);
46+
assert(chain_tip != nullptr);
47+
assert(block_template != nullptr);
4748
// Increment nonce
48-
IncrementExtraNonce(block, current_tip, _extra_nonce);
49+
IncrementExtraNonce(block, chain_tip, _extra_nonce);
4950
LogPrintf("DynamicMiner -- Running miner on device %s#%d with %u transactions in block (%u bytes)\n", DeviceName(), _device_index, block.vtx.size(),
5051
GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION));
5152
// set loop start for counter
@@ -58,12 +59,17 @@ void MinerBase::Loop()
5859
_ctx->counter->Increment(hashes);
5960
// Check for stop or if block needs to be rebuilt
6061
boost::this_thread::interruption_point();
62+
// Check if block was recreated
63+
if (block_flag != _ctx->block_flag()) {
64+
break;
65+
}
66+
// Recreate block if nonce too big
6167
if (block.nNonce >= 0xffff0000) {
6268
_ctx->RecreateBlock();
6369
break;
6470
}
6571
// Update block time
66-
if (UpdateTime(block, _ctx->chainparams().GetConsensus(), current_tip) < 0) {
72+
if (UpdateTime(block, _ctx->chainparams().GetConsensus(), chain_tip) < 0) {
6773
// Recreate the block if the clock has run backwards,
6874
// so that we can use the correct time.
6975
_ctx->RecreateBlock();

src/miner/internal/miner-context.cpp

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@
66
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
77

88
#include "miner/internal/miner-context.h"
9-
#include "chain.h"
109
#include "miner/miner-util.h"
11-
#include "net.h"
12-
#include "txmempool.h"
1310
#include "validation.h"
1411
#include "validationinterface.h"
1512

@@ -27,20 +24,12 @@ void MinerSharedContext::InitializeCoinbaseScript()
2724

2825
void MinerSharedContext::RecreateBlock()
2926
{
27+
// First we increment flag
28+
// so all miner threads know new block is coming
29+
_block_flag += 1;
30+
// Then we acquire unique lock so that miners wait
31+
// for the new block to be created
3032
boost::unique_lock<boost::shared_mutex> guard(_mutex);
31-
32-
_tip = chainActive.Tip();
33+
_chain_tip = chainActive.Tip();
3334
_block_template = CreateNewBlock(chainparams, _coinbase_script->reserveScript);
3435
}
35-
36-
CBlockIndex* MinerSharedContext::tip()
37-
{
38-
boost::shared_lock<boost::shared_mutex> guard(_mutex);
39-
return _tip;
40-
}
41-
42-
std::shared_ptr<CBlockTemplate> MinerSharedContext::block_template()
43-
{
44-
boost::shared_lock<boost::shared_mutex> guard(_mutex);
45-
return _block_template;
46-
}

src/miner/internal/miner-context.h

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include <boost/thread/locks.hpp>
1111
#include <boost/thread/shared_mutex.hpp>
1212

13+
#include <atomic>
14+
1315
class CBlock;
1416
class CChainParams;
1517
class CConnman;
@@ -39,17 +41,23 @@ struct MinerSharedContext {
3941
void RecreateBlock();
4042
void InitializeCoinbaseScript();
4143

42-
CBlockIndex* tip();
43-
std::shared_ptr<CBlockTemplate> block_template();
44-
std::shared_ptr<CReserveScript> coinbase_script() { return _coinbase_script; }
45-
bool has_block() { return !!_block_template; }
44+
CBlockIndex* tip() const { return _chain_tip; }
45+
uint64_t block_flag() const { return _block_flag; }
46+
std::shared_ptr<CReserveScript> coinbase_script() const { return _coinbase_script; }
47+
bool has_block() const { return _block_template != nullptr; }
48+
49+
std::shared_ptr<CBlockTemplate> block_template()
50+
{
51+
boost::shared_lock<boost::shared_mutex> guard(_mutex);
52+
return _block_template;
53+
}
4654

4755
private:
48-
// curent blockchain tip
49-
// updated with block recreation
50-
CBlockIndex* _tip = nullptr;
56+
// current block chain tip
57+
std::atomic<CBlockIndex*> _chain_tip{nullptr};
58+
// atomic flag incremented on recreated block
59+
std::atomic<std::uint64_t> _block_flag{0};
5160
// shared block template for miners
52-
// they have to randomize (...)
5361
std::shared_ptr<CBlockTemplate> _block_template{nullptr};
5462
// coinbase script for all miners
5563
std::shared_ptr<CReserveScript> _coinbase_script{nullptr};
@@ -90,6 +98,7 @@ class MinerContext
9098
CConnman& connman() const { return shared->connman; }
9199
const CChainParams& chainparams() const { return shared->chainparams; }
92100
CBlockIndex* tip() const { return shared->tip(); }
101+
uint64_t block_flag() const { return shared->block_flag(); }
93102
std::shared_ptr<CBlockTemplate> block_template() const { return shared->block_template(); }
94103
std::shared_ptr<CReserveScript> coinbase_script() const { return shared->coinbase_script(); }
95104
bool has_block() const { return shared->has_block(); }

0 commit comments

Comments
 (0)