Skip to content

Commit 163a350

Browse files
authored
Merge pull request duality-solutions#269 from crackcomm/v2.4-WIP-miner
Separate miner init and signals
2 parents eb459d2 + 761d4e4 commit 163a350

File tree

12 files changed

+188
-124
lines changed

12 files changed

+188
-124
lines changed

src/init.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2008,13 +2008,11 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
20082008
if (!connman.Start(scheduler, strNodeError, connOptions))
20092009
return InitError(strNodeError);
20102010

2011-
// Create a miner controller
2012-
gMiners.reset(new MinersController(chainparams, connman));
2013-
SetCPUMinerThreads(GetArg("-genproclimit-cpu", DEFAULT_GENERATE_THREADS_CPU));
2014-
SetGPUMinerThreads(GetArg("-genproclimit-gpu", DEFAULT_GENERATE_THREADS_GPU));
2015-
20162011
// Generate coins in the background
20172012
if (GetBoolArg("-gen", DEFAULT_GENERATE)) {
2013+
InitMiners(chainparams, connman);
2014+
SetCPUMinerThreads(GetArg("-genproclimit-cpu", DEFAULT_GENERATE_THREADS_CPU));
2015+
SetGPUMinerThreads(GetArg("-genproclimit-gpu", DEFAULT_GENERATE_THREADS_GPU));
20182016
StartMiners();
20192017
}
20202018

src/miner/internal/miner-base.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,21 @@ void MinerBase::Loop()
3838

3939
CBlock block;
4040
CBlockIndex* chain_tip = nullptr;
41-
std::uint64_t block_flag = 0;
41+
int64_t block_time = 0;
4242
std::shared_ptr<CBlockTemplate> block_template = {nullptr};
4343

4444
try {
4545
while (true) {
4646
// Update block and tip if changed
47-
if (block_flag != _ctx->shared->block_flag()) {
47+
if (block_time != _ctx->shared->block_time()) {
4848
// set new block template
4949
block_template = _ctx->shared->block_template();
5050
block = block_template->block;
5151
// set block reserve script
5252
SetBlockPubkeyScript(block, _coinbase_script->reserveScript);
5353
// set block flag only after template
5454
// so we've waited for RecreateBlock
55-
block_flag = _ctx->shared->block_flag();
55+
block_time = _ctx->shared->block_time();
5656
// block template chain tip
5757
chain_tip = _ctx->shared->tip();
5858
}
@@ -74,7 +74,7 @@ void MinerBase::Loop()
7474
// Check for stop or if block needs to be rebuilt
7575
boost::this_thread::interruption_point();
7676
// Check if block was recreated
77-
if (block_flag != _ctx->shared->block_flag()) {
77+
if (block_time != _ctx->shared->block_time()) {
7878
break;
7979
}
8080
// Recreate block if nonce too big

src/miner/internal/miner-context.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "miner/internal/miner-context.h"
66
#include "miner/miner-util.h"
7+
#include "txmempool.h"
78
#include "validation.h"
89

910
MinerContext::MinerContext(const CChainParams& chainparams_, CConnman& connman_)
@@ -15,12 +16,15 @@ MinerContext::MinerContext(MinerSharedContextRef shared_, HashRateCounterRef cou
1516

1617
void MinerSharedContext::RecreateBlock()
1718
{
18-
// First we increment flag
19-
// so all miner threads know new block is coming
20-
_block_flag += 1;
2119
// Then we acquire unique lock so that miners wait
2220
// for the new block to be created
2321
boost::unique_lock<boost::shared_mutex> guard(_mutex);
22+
uint32_t txn_time = mempool.GetTransactionsUpdated();
23+
// pass if nothing changed
24+
if (_chain_tip == chainActive.Tip() && _last_txn == txn_time)
25+
return;
2426
_chain_tip = chainActive.Tip();
27+
_block_time = GetTime();
2528
_block_template = CreateNewBlock(chainparams);
29+
_last_txn = txn_time;
2630
}

src/miner/internal/miner-context.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ struct CBlockTemplate;
2020

2121
class MinerBase;
2222
class MinerContext;
23+
class MinerSignals;
2324
class MinersController;
2425

2526
/** Miner context shared_ptr */
@@ -36,12 +37,11 @@ struct MinerSharedContext {
3637
// Returns chain tip of current block template
3738
CBlockIndex* tip() const { return _chain_tip; }
3839

39-
// Returns miner block flag
40-
// It's incremented every time new template is generated
41-
uint64_t block_flag() const { return _block_flag; }
40+
// Returns miner block template creation time
41+
int64_t block_time() const { return _block_time; }
4242

43-
// Returns true if block was created
44-
bool has_block() const { return _block_template != nullptr; }
43+
// Returns time of last transaction in the block
44+
uint32_t last_txn() const { return _last_txn; }
4545

4646
// Returns miner block template
4747
std::shared_ptr<CBlockTemplate> block_template()
@@ -52,6 +52,7 @@ struct MinerSharedContext {
5252

5353
protected:
5454
friend class MinerBase;
55+
friend class MinerSignals;
5556
friend class MinersController;
5657

5758
// recreates miners block template
@@ -61,7 +62,9 @@ struct MinerSharedContext {
6162
// current block chain tip
6263
std::atomic<CBlockIndex*> _chain_tip{nullptr};
6364
// atomic flag incremented on recreated block
64-
std::atomic<std::uint64_t> _block_flag{0};
65+
std::atomic<int64_t> _block_time{0};
66+
// last transaction update time
67+
std::atomic<uint32_t> _last_txn{0};
6568
// shared block template for miners
6669
std::shared_ptr<CBlockTemplate> _block_template{nullptr};
6770
// mutex protecting multiple threads recreating block

src/miner/internal/miners-controller.cpp

Lines changed: 25 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,9 @@
77
#include "miner/internal/miner-context.h"
88
#include "miner/miner-util.h"
99
#include "net.h"
10-
#include "txmempool.h"
1110
#include "validation.h"
1211
#include "validationinterface.h"
1312

14-
void ConnectMinerSignals(MinersController* miners_)
15-
{
16-
miners_->ctx()->connman().ConnectSignalNode(boost::bind(&MinersController::NotifyNode, miners_, _1));
17-
GetMainSignals().UpdatedBlockTip.connect(boost::bind(&MinersController::NotifyBlock, miners_, _1, _2, _3));
18-
GetMainSignals().SyncTransaction.connect(boost::bind(&MinersController::NotifyTransaction, miners_, _1, _2, _3));
19-
}
2013

2114
MinersController::MinersController(const CChainParams& chainparams, CConnman& connman)
2215
: MinersController(std::make_shared<MinerContext>(chainparams, connman)){};
@@ -27,14 +20,15 @@ MinersController::MinersController(MinerContextRef ctx)
2720
#ifdef ENABLE_GPU
2821
_group_gpu(_ctx->MakeChild()),
2922
#endif // ENABLE_GPU
30-
_connected(!_ctx->chainparams().MiningRequiresPeers())
31-
{
32-
ConnectMinerSignals(this);
33-
};
23+
_connected(!_ctx->chainparams().MiningRequiresPeers()){};
3424

3525
void MinersController::Start()
3626
{
3727
_enable_start = true;
28+
_signals = std::make_shared<MinerSignals>(this);
29+
// initialize block template
30+
_ctx->shared->RecreateBlock();
31+
3832
if (can_start()) {
3933
_group_cpu.Start();
4034
#ifdef ENABLE_GPU
@@ -46,6 +40,7 @@ void MinersController::Start()
4640
void MinersController::Shutdown()
4741
{
4842
_enable_start = false;
43+
_signals = nullptr; // remove signals receiver
4944

5045
_group_cpu.Shutdown();
5146
#ifdef ENABLE_GPU
@@ -62,48 +57,45 @@ int64_t MinersController::GetHashRate() const
6257
#endif // ENABLE_GPU
6358
}
6459

65-
void MinersController::NotifyNode(const CNode* node)
60+
MinerSignals::MinerSignals(MinersController* ctr)
61+
: _ctr(ctr),
62+
_node(_ctr->ctx()->connman().ConnectSignalNode(boost::bind(&MinerSignals::NotifyNode, this, _1))),
63+
_block(GetMainSignals().UpdatedBlockTip.connect(boost::bind(&MinerSignals::NotifyBlock, this, _1, _2, _3))),
64+
_txn(GetMainSignals().SyncTransaction.connect(boost::bind(&MinerSignals::NotifyTransaction, this, _1, _2, _3))){};
65+
66+
void MinerSignals::NotifyNode(const CNode* node)
6667
{
6768
if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) >= 2) {
68-
_connected = true;
69-
}
70-
else if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) <= 1) {
71-
_connected = false;
69+
_ctr->_connected = true;
70+
} else if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) <= 1) {
71+
_ctr->_connected = false;
7272
}
7373
};
7474

75-
void MinersController::NotifyBlock(const CBlockIndex* index_new, const CBlockIndex* index_fork, bool fInitialDownload)
75+
void MinerSignals::NotifyBlock(const CBlockIndex* index_new, const CBlockIndex* index_fork, bool fInitialDownload)
7676
{
7777
if (fInitialDownload)
7878
return;
7979
// Compare with current tip (checks for unexpected behaviour or old block)
8080
if (index_new != chainActive.Tip())
8181
return;
8282
// Create new block template for miners
83-
_last_sync_time = GetTime();
84-
_last_txn_time = mempool.GetTransactionsUpdated();
85-
_ctx->shared->RecreateBlock();
83+
_ctr->_ctx->shared->RecreateBlock();
8684
// start miners
87-
if (can_start()) {
88-
_group_cpu.Start();
85+
if (_ctr->can_start()) {
86+
_ctr->_group_cpu.Start();
8987
#ifdef ENABLE_GPU
90-
_group_gpu.Start();
88+
_ctr->_group_gpu.Start();
9189
#endif // ENABLE_GPU
9290
}
9391
};
9492

95-
void MinersController::NotifyTransaction(const CTransaction& txn, const CBlockIndex* index, int posInBlock)
93+
void MinerSignals::NotifyTransaction(const CTransaction& txn, const CBlockIndex* index, int posInBlock)
9694
{
9795
// check if blockchain has synced, has more than 1 peer and is enabled before recreating blocks
98-
if (IsInitialBlockDownload() || !can_start())
99-
return;
100-
101-
const int64_t latest_txn = mempool.GetTransactionsUpdated();
102-
if (latest_txn == _last_txn_time) {
96+
if (IsInitialBlockDownload() || !_ctr->can_start())
10397
return;
104-
}
105-
if (GetTime() - _last_txn_time > 60) {
106-
_last_txn_time = latest_txn;
107-
_ctx->shared->RecreateBlock();
98+
if (GetTime() - _ctr->_ctx->shared->last_txn() > 60) {
99+
_ctr->_ctx->shared->RecreateBlock();
108100
}
109101
};

src/miner/internal/miners-controller.h

Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#ifndef DYNAMIC_INTERNAL_MINERS_CONTROLLER_H
66
#define DYNAMIC_INTERNAL_MINERS_CONTROLLER_H
77

8+
#include <boost/signals2.hpp>
9+
810
#include "chainparams.h"
911
#include "miner/impl/miner-cpu.h"
1012
#include "miner/impl/miner-gpu.h"
@@ -18,6 +20,7 @@ class CBlockIndex;
1820
class CTransaction;
1921
struct CBlockTemplate;
2022

23+
class MinerSignals;
2124
class MinersController;
2225

2326
void ConnectMinerSignals(MinersController*);
@@ -27,19 +30,6 @@ void ConnectMinerSignals(MinersController*);
2730
*/
2831
class MinersController
2932
{
30-
private:
31-
MinerContextRef _ctx;
32-
MinersThreadGroup<CPUMiner> _group_cpu;
33-
#ifdef ENABLE_GPU
34-
MinersThreadGroup<GPUMiner> _group_gpu;
35-
#endif // ENABLE_GPU
36-
37-
bool _connected = false;
38-
bool _enable_start = false;
39-
40-
int64_t _last_txn_time = 0;
41-
int64_t _last_sync_time = 0;
42-
4333
public:
4434
MinersController(const CChainParams& chainparams, CConnman& connman);
4535
MinersController(MinerContextRef ctx);
@@ -65,27 +55,65 @@ class MinersController
6555
}
6656
#endif // ENABLE_GPU
6757

68-
private:
69-
void StartIfEnabled();
70-
71-
// Returns true if can start
72-
bool can_start() const { return _connected && _enable_start && _ctx->shared->has_block(); }
73-
7458
protected:
7559
// Returns shared miner context
7660
MinerContextRef ctx() const { return _ctx; }
7761

62+
// Starts miner only if can
63+
void StartIfEnabled();
64+
65+
// Returns true if enabled, connected and has block.
66+
bool can_start() const { return _connected && _enable_start && _ctx->shared->block_template(); }
67+
68+
// Miner signals class
69+
friend class MinerSignals;
70+
71+
// Optional miner signals
72+
// It can be empty when miner is shutdown
73+
std::shared_ptr<MinerSignals> _signals{nullptr};
74+
75+
// Miner context
76+
MinerContextRef _ctx;
77+
// Miner CPU Thread group
78+
MinersThreadGroup<CPUMiner> _group_cpu;
79+
#ifdef ENABLE_GPU
80+
// Miner GPU Thread group
81+
MinersThreadGroup<GPUMiner> _group_gpu;
82+
#endif // ENABLE_GPU
83+
84+
// Set to true when at least one node is connected
85+
bool _connected = false;
86+
87+
// Set to true when user requested start
88+
bool _enable_start = false;
89+
90+
// Time of last transaction signal
91+
int64_t _last_txn_time = 0;
92+
// Time of last time block template was created
93+
int64_t _last_sync_time = 0;
94+
};
95+
96+
class MinerSignals
97+
{
98+
private:
99+
MinersController* _ctr;
100+
101+
boost::signals2::scoped_connection _node;
102+
boost::signals2::scoped_connection _block;
103+
boost::signals2::scoped_connection _txn;
104+
105+
public:
106+
MinerSignals(MinersController* _ctr);
107+
108+
private:
78109
// Handles new node connection
79110
virtual void NotifyNode(const CNode* node);
80111

81112
// Handles updated blockchain tip
82113
virtual void NotifyBlock(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload);
83114

84115
// Handles new transaction
85-
virtual void NotifyTransaction(const CTransaction& tx, const CBlockIndex* pindex, int posInBlock);
86-
87-
// Connects signals to controller
88-
friend void ConnectMinerSignals(MinersController*);
116+
virtual void NotifyTransaction(const CTransaction& txn, const CBlockIndex* pindex, int posInBlock);
89117
};
90118

91119
#endif // DYNAMIC_INTERNAL_MINERS_CONTROLLER_H

src/miner/internal/miners-group.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,20 @@ class MinersThreadGroup : public ThreadGroup<T, MinerContextRef>
2323
void Shutdown()
2424
{
2525
// Shutdown all threads
26-
ThreadGroup<T, MinerContextRef>::Shutdown();
26+
SetSize(0);
2727
// It's not updated and instead of reading
2828
// system time and comparing with last update
2929
// it is just reset when all threads are shut
3030
this->_ctx->counter->Reset();
3131
};
3232

3333
// Sets amount of threads
34-
void SetNumThreads(uint8_t target)
34+
void SetSize(uint8_t size)
3535
{
36-
// Set amount of target threads
37-
ThreadGroup<T, MinerContextRef>::SetNumThreads(target);
36+
// Set thread group size
37+
ThreadGroup<T, MinerContextRef>::SetSize(size);
3838
// Reset hash rate counter
39-
if (target == 0) {
39+
if (size == 0) {
4040
this->_ctx->counter->Reset();
4141
}
4242
};

0 commit comments

Comments
 (0)