mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
Merge #5940: refactor: consolidate activeMasternodeInfo{Cs} into CActiveMasternodeManager, create NodeContext alias, reduce globals usage
815e4f8026
masternode: protect m_{error,state} with cs (pasta)136e445abc
refactor: pass CActiveMasternodeManager as pointer arg to LLMQContext (Kittywhiskers Van Gogh)5e0f77747a
refactor: pass CActiveMasternodeManager as pointer arg to CJContext (Kittywhiskers Van Gogh)f171c24a29
refactor: add CActiveMasternodeManager NodeContext alias, use in RPC (Kittywhiskers Van Gogh)44beb941cb
refactor: prefix member variable names with m_ (Kittywhiskers Van Gogh)73cef4f5f9
refactor: make bls{Pub}KeyOperator member variables instead of pointers (Kittywhiskers Van Gogh)fbc783635a
refactor: make m_info private, get const refs (or copies) from Get*() functions (Kittywhiskers Van Gogh)1b516ce4ed
refactor: use signing helper function instead of passing blsKeyOperator (Kittywhiskers Van Gogh)33702aca39
refactor: add helper function to decrypt messages with blsKeyOperator (Kittywhiskers Van Gogh)3eb931b596
refactor: add helper function to sign messages with blsKeyOperator (Kittywhiskers Van Gogh)3827355cce
refactor: move key initialization to InitKeys, define destructor (Kittywhiskers Van Gogh)e5295dec1f
refactor: move activeMasternodeInfo{Cs} into CActiveMasternodeManager (Kittywhiskers Van Gogh)b8c1f010e7
refactor: avoid accessing active masternode info if not in masternode mode (Kittywhiskers Van Gogh)9a3c5a3c48
trivial: access activeMasternodeInfo when lock is in scope (Kittywhiskers Van Gogh) Pull request description: ## Additional Information * `CActiveMasternodeManager`, unlike other managers, is _conditionally_ initialized (specifically, when the node is hosting a masternode). This means that checks need to be made to ensure that the conditions needed to initialize the manager are true or that the pointer leads to a valid manager instance. As the codebase currently checks (and fast-fails) based on the node being in "masternode mode" (`fMasternodeMode`) or not, we will continue with this approach, but with additional assertions _after_ the masternode mode check if the manager exists. * Though, since `activeMasternodeInfo`(`Cs`) are global variables, they can be accessed _regardless_ of whether the corresponding manager exists. This means some parts of the codebase attempt to fetch information about the (nonexistent) active masternode _before_ determining if it should use the masternode mode path or not (looking at you, `CMNAuth::ProcessMessage`) Moving them into `CActiveMasternodeManager` meant adding checks _before_ attempting to access information about the masternode, as they would no longer be accessible with dummy values ([here](2110c0c309/src/init.cpp (L1633-L1635)
)) on account of being part of the conditionally initialized manager. * In an attempt to opportunistically dereference the manager, `CDKGSessionManager` (accepting a pointer) was dereferencing the manager before passing it to `CDKGSessionHandler`. This was done under the assumption that `CDKGSessionManager` would only ever be initialized in masternode mode. This is not true. I can confirm that because I spent a few days trying to debug test failures. `CDKGSessionHandler` is initialized in two scenarios: * In masternode mode * If the `-watchquorums` flag is enabled The latter scenario doesn't initialize `CActiveMasternodeManager`. Furthermore, the DKG round thread is started unconditionally ([here](2110c0c309/src/llmq/context.cpp (L79)
)) and the `CDKGSessionHandler::StartThreads` > `CDKGSessionHandler::StartThread` > `CDKGSessionHandler::PhaseHandlerThread` > `CDKGSessionHandler::HandleDKGRound` > `CDKGSessionHandler::InitNewQuorum` > `CActiveMasternodeManager::GetProTxHash` call chain reveals an attempt to fetch active masternode information without any masternode mode checks. This behaviour has now been changed and the thread will only be spun up if in masternode mode. * Dereferencing so far has been limited to objects that primarily hold data (like `CCoinJoinBroadcastTx` or `CGovernanceObject`) as they should not have knowledge of node's state (that responsibility lies with whatever manager manipulates those objects), perform one-off operations and static functions. * `activeMasternodeInfo` allowed its members to be read-write accessible to anybody who asked. Additionally, signing and decrypting involved borrowing the operator secret key from the active masternode state to perform those operations. This behaviour has now been changed. The internal state is now private and accessible read-only as a const ref (or copy) and `Decrypt`/`Sign` functions have been implemented to allow those operations to happen without having another manager access the operator private key in order to do so. * You cannot combine a `WITH_LOCK` and an `Assert` (in either mutex or accessed value), doing so will cause errors if `-Werror=thread-safety` is enabled. This is why `assert`s are added even when it would intuitively seem that `Assert` would've been more appropriate to use. ## Future Considerations Currently there are no unit tests that test the functionality of `CActiveMasternodeManager` as it's never initialized in test contexts, breakage had to be found using functional tests. Perhaps some (rudimentary) tests for `CActiveMasternodeManager` may prove to be valuable. ## Breaking Changes Not _really_. Some behaviour has been modified but nothing that should necessitate updates or upgrades. ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)** - [x] I have added or updated relevant unit/integration/functional/e2e tests - [x] I have made corresponding changes to the documentation **(note: N/A)** - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: PastaPastaPasta: utACK815e4f8026
Tree-SHA512: cbe49ea9e1c35df514e1b40869ee271baef1c348c9d09e4b356e5fc8fe5449cbbe66569258f2d664029faa9a46f711df9bf9e41eb8734c3aefc6cd8e94378948
This commit is contained in:
commit
f217e0ae7b
@ -47,12 +47,10 @@ uint256 CCoinJoinQueue::GetSignatureHash() const
|
|||||||
return SerializeHash(*this, SER_GETHASH, PROTOCOL_VERSION);
|
return SerializeHash(*this, SER_GETHASH, PROTOCOL_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCoinJoinQueue::Sign()
|
bool CCoinJoinQueue::Sign(const CActiveMasternodeManager& mn_activeman)
|
||||||
{
|
{
|
||||||
if (!fMasternodeMode) return false;
|
|
||||||
|
|
||||||
uint256 hash = GetSignatureHash();
|
uint256 hash = GetSignatureHash();
|
||||||
CBLSSignature sig = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.blsKeyOperator->Sign(hash, false));
|
CBLSSignature sig = mn_activeman.Sign(hash, /*is_legacy=*/ false);
|
||||||
if (!sig.IsValid()) {
|
if (!sig.IsValid()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -99,12 +97,10 @@ uint256 CCoinJoinBroadcastTx::GetSignatureHash() const
|
|||||||
return SerializeHash(*this, SER_GETHASH, PROTOCOL_VERSION);
|
return SerializeHash(*this, SER_GETHASH, PROTOCOL_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCoinJoinBroadcastTx::Sign()
|
bool CCoinJoinBroadcastTx::Sign(const CActiveMasternodeManager& mn_activeman)
|
||||||
{
|
{
|
||||||
if (!fMasternodeMode) return false;
|
|
||||||
|
|
||||||
uint256 hash = GetSignatureHash();
|
uint256 hash = GetSignatureHash();
|
||||||
CBLSSignature sig = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.blsKeyOperator->Sign(hash, false));
|
CBLSSignature sig = mn_activeman.Sign(hash, /*is_legacy=*/ false);
|
||||||
if (!sig.IsValid()) {
|
if (!sig.IsValid()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
class CActiveMasternodeManager;
|
||||||
class CChainState;
|
class CChainState;
|
||||||
class CConnman;
|
class CConnman;
|
||||||
class CBLSPublicKey;
|
class CBLSPublicKey;
|
||||||
@ -213,7 +214,7 @@ public:
|
|||||||
* 3) we signed the message successfully, and
|
* 3) we signed the message successfully, and
|
||||||
* 4) we verified the message successfully
|
* 4) we verified the message successfully
|
||||||
*/
|
*/
|
||||||
bool Sign();
|
bool Sign(const CActiveMasternodeManager& mn_activeman);
|
||||||
/// Check if we have a valid Masternode address
|
/// Check if we have a valid Masternode address
|
||||||
[[nodiscard]] bool CheckSignature(const CBLSPublicKey& blsPubKey) const;
|
[[nodiscard]] bool CheckSignature(const CBLSPublicKey& blsPubKey) const;
|
||||||
|
|
||||||
@ -284,7 +285,7 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] uint256 GetSignatureHash() const;
|
[[nodiscard]] uint256 GetSignatureHash() const;
|
||||||
|
|
||||||
bool Sign();
|
bool Sign(const CActiveMasternodeManager& mn_activeman);
|
||||||
[[nodiscard]] bool CheckSignature(const CBLSPublicKey& blsPubKey) const;
|
[[nodiscard]] bool CheckSignature(const CBLSPublicKey& blsPubKey) const;
|
||||||
|
|
||||||
void SetConfirmedHeight(std::optional<int> nConfirmedHeightIn) { assert(nConfirmedHeightIn == std::nullopt || *nConfirmedHeightIn > 0); nConfirmedHeight = nConfirmedHeightIn; }
|
void SetConfirmedHeight(std::optional<int> nConfirmedHeightIn) { assert(nConfirmedHeightIn == std::nullopt || *nConfirmedHeightIn > 0); nConfirmedHeight = nConfirmedHeightIn; }
|
||||||
|
@ -14,13 +14,13 @@
|
|||||||
#include <coinjoin/server.h>
|
#include <coinjoin/server.h>
|
||||||
|
|
||||||
CJContext::CJContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CTxMemPool& mempool,
|
CJContext::CJContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CTxMemPool& mempool,
|
||||||
const CMasternodeSync& mn_sync, bool relay_txes) :
|
const CActiveMasternodeManager* mn_activeman, const CMasternodeSync& mn_sync, bool relay_txes) :
|
||||||
dstxman{std::make_unique<CDSTXManager>()},
|
dstxman{std::make_unique<CDSTXManager>()},
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
walletman{std::make_unique<CoinJoinWalletManager>(connman, dmnman, mempool, mn_sync, queueman)},
|
walletman{std::make_unique<CoinJoinWalletManager>(connman, dmnman, mempool, mn_sync, queueman)},
|
||||||
queueman {relay_txes ? std::make_unique<CCoinJoinClientQueueManager>(connman, *walletman, dmnman, mn_sync) : nullptr},
|
queueman {relay_txes ? std::make_unique<CCoinJoinClientQueueManager>(connman, *walletman, dmnman, mn_sync) : nullptr},
|
||||||
#endif // ENABLE_WALLET
|
#endif // ENABLE_WALLET
|
||||||
server{std::make_unique<CCoinJoinServer>(chainstate, connman, dmnman, *dstxman, mempool, mn_sync)}
|
server{std::make_unique<CCoinJoinServer>(chainstate, connman, dmnman, *dstxman, mempool, mn_activeman, mn_sync)}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
CJContext::~CJContext() {}
|
CJContext::~CJContext() {}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
class CActiveMasternodeManager;
|
||||||
class CBlockPolicyEstimator;
|
class CBlockPolicyEstimator;
|
||||||
class CChainState;
|
class CChainState;
|
||||||
class CCoinJoinServer;
|
class CCoinJoinServer;
|
||||||
@ -29,7 +30,7 @@ struct CJContext {
|
|||||||
CJContext() = delete;
|
CJContext() = delete;
|
||||||
CJContext(const CJContext&) = delete;
|
CJContext(const CJContext&) = delete;
|
||||||
CJContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CTxMemPool& mempool,
|
CJContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CTxMemPool& mempool,
|
||||||
const CMasternodeSync& mn_sync, bool relay_txes);
|
const CActiveMasternodeManager* mn_activeman, const CMasternodeSync& mn_sync, bool relay_txes);
|
||||||
~CJContext();
|
~CJContext();
|
||||||
|
|
||||||
const std::unique_ptr<CDSTXManager> dstxman;
|
const std::unique_ptr<CDSTXManager> dstxman;
|
||||||
|
@ -43,6 +43,8 @@ PeerMsgRet CCoinJoinServer::ProcessMessage(CNode& peer, std::string_view msg_typ
|
|||||||
|
|
||||||
void CCoinJoinServer::ProcessDSACCEPT(CNode& peer, CDataStream& vRecv)
|
void CCoinJoinServer::ProcessDSACCEPT(CNode& peer, CDataStream& vRecv)
|
||||||
{
|
{
|
||||||
|
assert(m_mn_activeman);
|
||||||
|
|
||||||
if (IsSessionReady()) {
|
if (IsSessionReady()) {
|
||||||
// too many users in this session already, reject new ones
|
// too many users in this session already, reject new ones
|
||||||
LogPrint(BCLog::COINJOIN, "DSACCEPT -- queue is already full!\n");
|
LogPrint(BCLog::COINJOIN, "DSACCEPT -- queue is already full!\n");
|
||||||
@ -56,7 +58,7 @@ void CCoinJoinServer::ProcessDSACCEPT(CNode& peer, CDataStream& vRecv)
|
|||||||
LogPrint(BCLog::COINJOIN, "DSACCEPT -- nDenom %d (%s) txCollateral %s", dsa.nDenom, CoinJoin::DenominationToString(dsa.nDenom), dsa.txCollateral.ToString()); /* Continued */
|
LogPrint(BCLog::COINJOIN, "DSACCEPT -- nDenom %d (%s) txCollateral %s", dsa.nDenom, CoinJoin::DenominationToString(dsa.nDenom), dsa.txCollateral.ToString()); /* Continued */
|
||||||
|
|
||||||
auto mnList = m_dmnman.GetListAtChainTip();
|
auto mnList = m_dmnman.GetListAtChainTip();
|
||||||
auto dmn = WITH_LOCK(activeMasternodeInfoCs, return mnList.GetValidMNByCollateral(activeMasternodeInfo.outpoint));
|
auto dmn = WITH_LOCK(m_mn_activeman->cs, return mnList.GetValidMNByCollateral(m_mn_activeman->GetOutPoint()));
|
||||||
if (!dmn) {
|
if (!dmn) {
|
||||||
PushStatus(peer, STATUS_REJECTED, ERR_MN_LIST);
|
PushStatus(peer, STATUS_REJECTED, ERR_MN_LIST);
|
||||||
return;
|
return;
|
||||||
@ -67,7 +69,7 @@ void CCoinJoinServer::ProcessDSACCEPT(CNode& peer, CDataStream& vRecv)
|
|||||||
TRY_LOCK(cs_vecqueue, lockRecv);
|
TRY_LOCK(cs_vecqueue, lockRecv);
|
||||||
if (!lockRecv) return;
|
if (!lockRecv) return;
|
||||||
|
|
||||||
auto mnOutpoint = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.outpoint);
|
auto mnOutpoint = WITH_LOCK(m_mn_activeman->cs, return m_mn_activeman->GetOutPoint());
|
||||||
|
|
||||||
if (ranges::any_of(vecCoinJoinQueue,
|
if (ranges::any_of(vecCoinJoinQueue,
|
||||||
[&mnOutpoint](const auto& q){return q.masternodeOutpoint == mnOutpoint;})) {
|
[&mnOutpoint](const auto& q){return q.masternodeOutpoint == mnOutpoint;})) {
|
||||||
@ -308,6 +310,8 @@ void CCoinJoinServer::CommitFinalTransaction()
|
|||||||
AssertLockNotHeld(cs_coinjoin);
|
AssertLockNotHeld(cs_coinjoin);
|
||||||
if (!fMasternodeMode) return; // check and relay final tx only on masternode
|
if (!fMasternodeMode) return; // check and relay final tx only on masternode
|
||||||
|
|
||||||
|
assert(m_mn_activeman);
|
||||||
|
|
||||||
CTransactionRef finalTransaction = WITH_LOCK(cs_coinjoin, return MakeTransactionRef(finalMutableTransaction));
|
CTransactionRef finalTransaction = WITH_LOCK(cs_coinjoin, return MakeTransactionRef(finalMutableTransaction));
|
||||||
uint256 hashTx = finalTransaction->GetHash();
|
uint256 hashTx = finalTransaction->GetHash();
|
||||||
|
|
||||||
@ -331,10 +335,10 @@ void CCoinJoinServer::CommitFinalTransaction()
|
|||||||
// create and sign masternode dstx transaction
|
// create and sign masternode dstx transaction
|
||||||
if (!m_dstxman.GetDSTX(hashTx)) {
|
if (!m_dstxman.GetDSTX(hashTx)) {
|
||||||
CCoinJoinBroadcastTx dstxNew(finalTransaction,
|
CCoinJoinBroadcastTx dstxNew(finalTransaction,
|
||||||
WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.outpoint),
|
WITH_LOCK(m_mn_activeman->cs, return m_mn_activeman->GetOutPoint()),
|
||||||
WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash),
|
WITH_LOCK(m_mn_activeman->cs, return m_mn_activeman->GetProTxHash()),
|
||||||
GetAdjustedTime());
|
GetAdjustedTime());
|
||||||
dstxNew.Sign();
|
dstxNew.Sign(*m_mn_activeman);
|
||||||
m_dstxman.AddDSTX(dstxNew);
|
m_dstxman.AddDSTX(dstxNew);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,16 +499,18 @@ void CCoinJoinServer::CheckForCompleteQueue()
|
|||||||
{
|
{
|
||||||
if (!fMasternodeMode) return;
|
if (!fMasternodeMode) return;
|
||||||
|
|
||||||
|
assert(m_mn_activeman);
|
||||||
|
|
||||||
if (nState == POOL_STATE_QUEUE && IsSessionReady()) {
|
if (nState == POOL_STATE_QUEUE && IsSessionReady()) {
|
||||||
SetState(POOL_STATE_ACCEPTING_ENTRIES);
|
SetState(POOL_STATE_ACCEPTING_ENTRIES);
|
||||||
|
|
||||||
CCoinJoinQueue dsq(nSessionDenom,
|
CCoinJoinQueue dsq(nSessionDenom,
|
||||||
WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.outpoint),
|
WITH_LOCK(m_mn_activeman->cs, return m_mn_activeman->GetOutPoint()),
|
||||||
WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash),
|
WITH_LOCK(m_mn_activeman->cs, return m_mn_activeman->GetProTxHash()),
|
||||||
GetAdjustedTime(), true);
|
GetAdjustedTime(), true);
|
||||||
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::CheckForCompleteQueue -- queue is ready, signing and relaying (%s) " /* Continued */
|
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::CheckForCompleteQueue -- queue is ready, signing and relaying (%s) " /* Continued */
|
||||||
"with %d participants\n", dsq.ToString(), vecSessionCollaterals.size());
|
"with %d participants\n", dsq.ToString(), vecSessionCollaterals.size());
|
||||||
dsq.Sign();
|
dsq.Sign(*m_mn_activeman);
|
||||||
dsq.Relay(connman);
|
dsq.Relay(connman);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -692,6 +698,8 @@ bool CCoinJoinServer::CreateNewSession(const CCoinJoinAccept& dsa, PoolMessage&
|
|||||||
{
|
{
|
||||||
if (!fMasternodeMode || nSessionID != 0) return false;
|
if (!fMasternodeMode || nSessionID != 0) return false;
|
||||||
|
|
||||||
|
assert(m_mn_activeman);
|
||||||
|
|
||||||
// new session can only be started in idle mode
|
// new session can only be started in idle mode
|
||||||
if (nState != POOL_STATE_IDLE) {
|
if (nState != POOL_STATE_IDLE) {
|
||||||
nMessageIDRet = ERR_MODE;
|
nMessageIDRet = ERR_MODE;
|
||||||
@ -713,11 +721,11 @@ bool CCoinJoinServer::CreateNewSession(const CCoinJoinAccept& dsa, PoolMessage&
|
|||||||
if (!fUnitTest) {
|
if (!fUnitTest) {
|
||||||
//broadcast that I'm accepting entries, only if it's the first entry through
|
//broadcast that I'm accepting entries, only if it's the first entry through
|
||||||
CCoinJoinQueue dsq(nSessionDenom,
|
CCoinJoinQueue dsq(nSessionDenom,
|
||||||
WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.outpoint),
|
WITH_LOCK(m_mn_activeman->cs, return m_mn_activeman->GetOutPoint()),
|
||||||
WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash),
|
WITH_LOCK(m_mn_activeman->cs, return m_mn_activeman->GetProTxHash()),
|
||||||
GetAdjustedTime(), false);
|
GetAdjustedTime(), false);
|
||||||
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::CreateNewSession -- signing and relaying new queue: %s\n", dsq.ToString());
|
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::CreateNewSession -- signing and relaying new queue: %s\n", dsq.ToString());
|
||||||
dsq.Sign();
|
dsq.Sign(*m_mn_activeman);
|
||||||
dsq.Relay(connman);
|
dsq.Relay(connman);
|
||||||
LOCK(cs_vecqueue);
|
LOCK(cs_vecqueue);
|
||||||
vecCoinJoinQueue.push_back(dsq);
|
vecCoinJoinQueue.push_back(dsq);
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <net_types.h>
|
#include <net_types.h>
|
||||||
|
|
||||||
|
class CActiveMasternodeManager;
|
||||||
class CChainState;
|
class CChainState;
|
||||||
class CCoinJoinServer;
|
class CCoinJoinServer;
|
||||||
class CDataStream;
|
class CDataStream;
|
||||||
@ -29,6 +30,7 @@ private:
|
|||||||
CDeterministicMNManager& m_dmnman;
|
CDeterministicMNManager& m_dmnman;
|
||||||
CDSTXManager& m_dstxman;
|
CDSTXManager& m_dstxman;
|
||||||
CTxMemPool& mempool;
|
CTxMemPool& mempool;
|
||||||
|
const CActiveMasternodeManager* m_mn_activeman;
|
||||||
const CMasternodeSync& m_mn_sync;
|
const CMasternodeSync& m_mn_sync;
|
||||||
|
|
||||||
// Mixing uses collateral transactions to trust parties entering the pool
|
// Mixing uses collateral transactions to trust parties entering the pool
|
||||||
@ -85,12 +87,13 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CCoinJoinServer(CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman, CDSTXManager& dstxman,
|
explicit CCoinJoinServer(CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman, CDSTXManager& dstxman,
|
||||||
CTxMemPool& mempool, const CMasternodeSync& mn_sync) :
|
CTxMemPool& mempool, const CActiveMasternodeManager* mn_activeman, const CMasternodeSync& mn_sync) :
|
||||||
m_chainstate(chainstate),
|
m_chainstate(chainstate),
|
||||||
connman(_connman),
|
connman(_connman),
|
||||||
m_dmnman(dmnman),
|
m_dmnman(dmnman),
|
||||||
m_dstxman(dstxman),
|
m_dstxman(dstxman),
|
||||||
mempool(mempool),
|
mempool(mempool),
|
||||||
|
m_mn_activeman(mn_activeman),
|
||||||
m_mn_sync(mn_sync),
|
m_mn_sync(mn_sync),
|
||||||
vecSessionCollaterals(),
|
vecSessionCollaterals(),
|
||||||
fUnitTest(false)
|
fUnitTest(false)
|
||||||
|
@ -21,40 +21,45 @@
|
|||||||
|
|
||||||
void CMNAuth::PushMNAUTH(CNode& peer, CConnman& connman, const CBlockIndex* tip)
|
void CMNAuth::PushMNAUTH(CNode& peer, CConnman& connman, const CBlockIndex* tip)
|
||||||
{
|
{
|
||||||
LOCK(activeMasternodeInfoCs);
|
if (!fMasternodeMode) return;
|
||||||
if (!fMasternodeMode || activeMasternodeInfo.proTxHash.IsNull()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint256 signHash;
|
|
||||||
const auto receivedMNAuthChallenge = peer.GetReceivedMNAuthChallenge();
|
|
||||||
if (receivedMNAuthChallenge.IsNull()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// We include fInbound in signHash to forbid interchanging of challenges by a man in the middle (MITM). This way
|
|
||||||
// we protect ourselves against MITM in this form:
|
|
||||||
// node1 <- Eve -> node2
|
|
||||||
// It does not protect against:
|
|
||||||
// node1 -> Eve -> node2
|
|
||||||
// This is ok as we only use MNAUTH as a DoS protection and not for sensitive stuff
|
|
||||||
int nOurNodeVersion{PROTOCOL_VERSION};
|
|
||||||
if (Params().NetworkIDString() != CBaseChainParams::MAIN && gArgs.IsArgSet("-pushversion")) {
|
|
||||||
nOurNodeVersion = gArgs.GetArg("-pushversion", PROTOCOL_VERSION);
|
|
||||||
}
|
|
||||||
const bool is_basic_scheme_active{DeploymentActiveAfter(tip, Params().GetConsensus(), Consensus::DEPLOYMENT_V19)};
|
|
||||||
const CBLSPublicKeyVersionWrapper pubKey(*activeMasternodeInfo.blsPubKeyOperator, !is_basic_scheme_active);
|
|
||||||
if (peer.nVersion < MNAUTH_NODE_VER_VERSION || nOurNodeVersion < MNAUTH_NODE_VER_VERSION) {
|
|
||||||
signHash = ::SerializeHash(std::make_tuple(pubKey, receivedMNAuthChallenge, peer.IsInboundConn()));
|
|
||||||
} else {
|
|
||||||
signHash = ::SerializeHash(std::make_tuple(pubKey, receivedMNAuthChallenge, peer.IsInboundConn(), nOurNodeVersion));
|
|
||||||
}
|
|
||||||
|
|
||||||
CMNAuth mnauth;
|
CMNAuth mnauth;
|
||||||
mnauth.proRegTxHash = activeMasternodeInfo.proTxHash;
|
uint256 signHash;
|
||||||
mnauth.sig = activeMasternodeInfo.blsKeyOperator->Sign(signHash);
|
{
|
||||||
|
LOCK(::activeMasternodeManager->cs);
|
||||||
|
if (::activeMasternodeManager->GetProTxHash().IsNull()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto receivedMNAuthChallenge = peer.GetReceivedMNAuthChallenge();
|
||||||
|
if (receivedMNAuthChallenge.IsNull()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// We include fInbound in signHash to forbid interchanging of challenges by a man in the middle (MITM). This way
|
||||||
|
// we protect ourselves against MITM in this form:
|
||||||
|
// node1 <- Eve -> node2
|
||||||
|
// It does not protect against:
|
||||||
|
// node1 -> Eve -> node2
|
||||||
|
// This is ok as we only use MNAUTH as a DoS protection and not for sensitive stuff
|
||||||
|
int nOurNodeVersion{PROTOCOL_VERSION};
|
||||||
|
if (Params().NetworkIDString() != CBaseChainParams::MAIN && gArgs.IsArgSet("-pushversion")) {
|
||||||
|
nOurNodeVersion = gArgs.GetArg("-pushversion", PROTOCOL_VERSION);
|
||||||
|
}
|
||||||
|
const bool is_basic_scheme_active{DeploymentActiveAfter(tip, Params().GetConsensus(), Consensus::DEPLOYMENT_V19)};
|
||||||
|
auto pk = ::activeMasternodeManager->GetPubKey();
|
||||||
|
const CBLSPublicKeyVersionWrapper pubKey(pk, !is_basic_scheme_active);
|
||||||
|
if (peer.nVersion < MNAUTH_NODE_VER_VERSION || nOurNodeVersion < MNAUTH_NODE_VER_VERSION) {
|
||||||
|
signHash = ::SerializeHash(std::make_tuple(pubKey, receivedMNAuthChallenge, peer.IsInboundConn()));
|
||||||
|
} else {
|
||||||
|
signHash = ::SerializeHash(std::make_tuple(pubKey, receivedMNAuthChallenge, peer.IsInboundConn(), nOurNodeVersion));
|
||||||
|
}
|
||||||
|
|
||||||
|
mnauth.proRegTxHash = ::activeMasternodeManager->GetProTxHash();
|
||||||
|
} // ::activeMasternodeManager->cs
|
||||||
|
|
||||||
|
mnauth.sig = ::activeMasternodeManager->Sign(signHash);
|
||||||
|
|
||||||
LogPrint(BCLog::NET_NETCONN, "CMNAuth::%s -- Sending MNAUTH, peer=%d\n", __func__, peer.GetId());
|
LogPrint(BCLog::NET_NETCONN, "CMNAuth::%s -- Sending MNAUTH, peer=%d\n", __func__, peer.GetId());
|
||||||
|
|
||||||
connman.PushMessage(&peer, CNetMsgMaker(peer.GetCommonVersion()).Make(NetMsgType::MNAUTH, mnauth));
|
connman.PushMessage(&peer, CNetMsgMaker(peer.GetCommonVersion()).Make(NetMsgType::MNAUTH, mnauth));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +132,9 @@ PeerMsgRet CMNAuth::ProcessMessage(CNode& peer, CConnman& connman, const CDeterm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint256 myProTxHash = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash);
|
const uint256 myProTxHash = fMasternodeMode ?
|
||||||
|
WITH_LOCK(::activeMasternodeManager->cs, return ::activeMasternodeManager->GetProTxHash()) :
|
||||||
|
uint256();
|
||||||
|
|
||||||
connman.ForEachNode([&](CNode* pnode2) {
|
connman.ForEachNode([&](CNode* pnode2) {
|
||||||
if (peer.fDisconnect) {
|
if (peer.fDisconnect) {
|
||||||
|
@ -692,14 +692,14 @@ std::optional<const CGovernanceObject> CGovernanceManager::CreateGovernanceTrigg
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
LOCK(activeMasternodeInfoCs);
|
LOCK(::activeMasternodeManager->cs);
|
||||||
if (mn_payees.front()->proTxHash != activeMasternodeInfo.proTxHash) {
|
if (mn_payees.front()->proTxHash != ::activeMasternodeManager->GetProTxHash()) {
|
||||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s we are not the payee, skipping\n", __func__);
|
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s we are not the payee, skipping\n", __func__);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
gov_sb.SetMasternodeOutpoint(activeMasternodeInfo.outpoint);
|
gov_sb.SetMasternodeOutpoint(::activeMasternodeManager->GetOutPoint());
|
||||||
gov_sb.Sign( *activeMasternodeInfo.blsKeyOperator);
|
} // ::activeMasternodeManager->cs
|
||||||
} // activeMasternodeInfoCs
|
gov_sb.Sign(*::activeMasternodeManager);
|
||||||
|
|
||||||
if (std::string strError; !gov_sb.IsValidLocally(m_dmnman->GetListAtChainTip(), strError, true)) {
|
if (std::string strError; !gov_sb.IsValidLocally(m_dmnman->GetListAtChainTip(), strError, true)) {
|
||||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s Created trigger is invalid:%s\n", __func__, strError);
|
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s Created trigger is invalid:%s\n", __func__, strError);
|
||||||
@ -719,7 +719,8 @@ std::optional<const CGovernanceObject> CGovernanceManager::CreateGovernanceTrigg
|
|||||||
void CGovernanceManager::VoteGovernanceTriggers(const std::optional<const CGovernanceObject>& trigger_opt, CConnman& connman)
|
void CGovernanceManager::VoteGovernanceTriggers(const std::optional<const CGovernanceObject>& trigger_opt, CConnman& connman)
|
||||||
{
|
{
|
||||||
// only active masternodes can vote on triggers
|
// only active masternodes can vote on triggers
|
||||||
if (!fMasternodeMode || WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash.IsNull())) return;
|
if (!fMasternodeMode) return;
|
||||||
|
if (WITH_LOCK(::activeMasternodeManager->cs, return ::activeMasternodeManager->GetProTxHash().IsNull())) return;
|
||||||
|
|
||||||
LOCK2(cs_main, cs);
|
LOCK2(cs_main, cs);
|
||||||
|
|
||||||
@ -762,9 +763,9 @@ void CGovernanceManager::VoteGovernanceTriggers(const std::optional<const CGover
|
|||||||
|
|
||||||
bool CGovernanceManager::VoteFundingTrigger(const uint256& nHash, const vote_outcome_enum_t outcome, CConnman& connman)
|
bool CGovernanceManager::VoteFundingTrigger(const uint256& nHash, const vote_outcome_enum_t outcome, CConnman& connman)
|
||||||
{
|
{
|
||||||
CGovernanceVote vote(WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.outpoint), nHash, VOTE_SIGNAL_FUNDING, outcome);
|
CGovernanceVote vote(WITH_LOCK(::activeMasternodeManager->cs, return ::activeMasternodeManager->GetOutPoint()), nHash, VOTE_SIGNAL_FUNDING, outcome);
|
||||||
vote.SetTime(GetAdjustedTime());
|
vote.SetTime(GetAdjustedTime());
|
||||||
vote.Sign(WITH_LOCK(activeMasternodeInfoCs, return *activeMasternodeInfo.blsKeyOperator));
|
vote.Sign(*::activeMasternodeManager);
|
||||||
|
|
||||||
CGovernanceException exception;
|
CGovernanceException exception;
|
||||||
if (!ProcessVoteAndRelay(vote, exception, connman)) {
|
if (!ProcessVoteAndRelay(vote, exception, connman)) {
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <governance/governance.h>
|
#include <governance/governance.h>
|
||||||
#include <governance/validators.h>
|
#include <governance/validators.h>
|
||||||
#include <masternode/meta.h>
|
#include <masternode/meta.h>
|
||||||
|
#include <masternode/node.h>
|
||||||
#include <masternode/sync.h>
|
#include <masternode/sync.h>
|
||||||
#include <messagesigner.h>
|
#include <messagesigner.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
@ -273,9 +274,9 @@ void CGovernanceObject::SetMasternodeOutpoint(const COutPoint& outpoint)
|
|||||||
m_obj.masternodeOutpoint = outpoint;
|
m_obj.masternodeOutpoint = outpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGovernanceObject::Sign(const CBLSSecretKey& key)
|
bool CGovernanceObject::Sign(const CActiveMasternodeManager& mn_activeman)
|
||||||
{
|
{
|
||||||
CBLSSignature sig = key.Sign(GetSignatureHash(), false);
|
CBLSSignature sig = mn_activeman.Sign(GetSignatureHash(), false);
|
||||||
if (!sig.IsValid()) {
|
if (!sig.IsValid()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
#include <univalue.h>
|
#include <univalue.h>
|
||||||
|
|
||||||
class CBLSSecretKey;
|
class CActiveMasternodeManager;
|
||||||
class CBLSPublicKey;
|
class CBLSPublicKey;
|
||||||
class CDeterministicMNList;
|
class CDeterministicMNList;
|
||||||
class CGovernanceManager;
|
class CGovernanceManager;
|
||||||
@ -217,7 +217,7 @@ public:
|
|||||||
// Signature related functions
|
// Signature related functions
|
||||||
|
|
||||||
void SetMasternodeOutpoint(const COutPoint& outpoint);
|
void SetMasternodeOutpoint(const COutPoint& outpoint);
|
||||||
bool Sign(const CBLSSecretKey& key);
|
bool Sign(const CActiveMasternodeManager& mn_activeman);
|
||||||
bool CheckSignature(const CBLSPublicKey& pubKey) const;
|
bool CheckSignature(const CBLSPublicKey& pubKey) const;
|
||||||
|
|
||||||
uint256 GetSignatureHash() const;
|
uint256 GetSignatureHash() const;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <bls/bls.h>
|
#include <bls/bls.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
#include <key.h>
|
#include <key.h>
|
||||||
|
#include <masternode/node.h>
|
||||||
#include <masternode/sync.h>
|
#include <masternode/sync.h>
|
||||||
#include <messagesigner.h>
|
#include <messagesigner.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
@ -221,9 +222,9 @@ bool CGovernanceVote::CheckSignature(const CKeyID& keyID) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGovernanceVote::Sign(const CBLSSecretKey& key)
|
bool CGovernanceVote::Sign(const CActiveMasternodeManager& mn_activeman)
|
||||||
{
|
{
|
||||||
CBLSSignature sig = key.Sign(GetSignatureHash(), false);
|
CBLSSignature sig = mn_activeman.Sign(GetSignatureHash(), false);
|
||||||
if (!sig.IsValid()) {
|
if (!sig.IsValid()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,11 @@
|
|||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
#include <uint256.h>
|
#include <uint256.h>
|
||||||
|
|
||||||
class CGovernanceVote;
|
class CActiveMasternodeManager;
|
||||||
class CBLSPublicKey;
|
class CBLSPublicKey;
|
||||||
class CBLSSecretKey;
|
|
||||||
class CConnman;
|
class CConnman;
|
||||||
class CDeterministicMNList;
|
class CDeterministicMNList;
|
||||||
|
class CGovernanceVote;
|
||||||
class CKey;
|
class CKey;
|
||||||
class CKeyID;
|
class CKeyID;
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ public:
|
|||||||
|
|
||||||
bool Sign(const CKey& key, const CKeyID& keyID);
|
bool Sign(const CKey& key, const CKeyID& keyID);
|
||||||
bool CheckSignature(const CKeyID& keyID) const;
|
bool CheckSignature(const CKeyID& keyID) const;
|
||||||
bool Sign(const CBLSSecretKey& key);
|
bool Sign(const CActiveMasternodeManager& mn_activeman);
|
||||||
bool CheckSignature(const CBLSPublicKey& pubKey) const;
|
bool CheckSignature(const CBLSPublicKey& pubKey) const;
|
||||||
bool IsValid(const CDeterministicMNList& tip_mn_list, bool useVotingKey) const;
|
bool IsValid(const CDeterministicMNList& tip_mn_list, bool useVotingKey) const;
|
||||||
void Relay(CConnman& connman, const CDeterministicMNList& tip_mn_list) const;
|
void Relay(CConnman& connman, const CDeterministicMNList& tip_mn_list) const;
|
||||||
|
60
src/init.cpp
60
src/init.cpp
@ -369,15 +369,9 @@ void PrepareShutdown(NodeContext& node)
|
|||||||
pdsNotificationInterface = nullptr;
|
pdsNotificationInterface = nullptr;
|
||||||
}
|
}
|
||||||
if (fMasternodeMode) {
|
if (fMasternodeMode) {
|
||||||
UnregisterValidationInterface(activeMasternodeManager.get());
|
UnregisterValidationInterface(node.mn_activeman);
|
||||||
activeMasternodeManager.reset();
|
node.mn_activeman = nullptr;
|
||||||
}
|
::activeMasternodeManager.reset();
|
||||||
|
|
||||||
{
|
|
||||||
LOCK(activeMasternodeInfoCs);
|
|
||||||
// make sure to clean up BLS keys before global destructors are called (they have allocated from the secure memory pool)
|
|
||||||
activeMasternodeInfo.blsKeyOperator.reset();
|
|
||||||
activeMasternodeInfo.blsPubKeyOperator.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
node.chain_clients.clear();
|
node.chain_clients.clear();
|
||||||
@ -1606,31 +1600,6 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
|
|||||||
StartScriptCheckWorkerThreads(script_threads);
|
StartScriptCheckWorkerThreads(script_threads);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(activeMasternodeInfo.blsKeyOperator == nullptr);
|
|
||||||
assert(activeMasternodeInfo.blsPubKeyOperator == nullptr);
|
|
||||||
fMasternodeMode = false;
|
|
||||||
std::string strMasterNodeBLSPrivKey = args.GetArg("-masternodeblsprivkey", "");
|
|
||||||
if (!strMasterNodeBLSPrivKey.empty()) {
|
|
||||||
CBLSSecretKey keyOperator(ParseHex(strMasterNodeBLSPrivKey));
|
|
||||||
if (!keyOperator.IsValid()) {
|
|
||||||
return InitError(_("Invalid masternodeblsprivkey. Please see documentation."));
|
|
||||||
}
|
|
||||||
fMasternodeMode = true;
|
|
||||||
{
|
|
||||||
LOCK(activeMasternodeInfoCs);
|
|
||||||
activeMasternodeInfo.blsKeyOperator = std::make_unique<CBLSSecretKey>(keyOperator);
|
|
||||||
activeMasternodeInfo.blsPubKeyOperator = std::make_unique<CBLSPublicKey>(keyOperator.GetPublicKey());
|
|
||||||
}
|
|
||||||
// We don't know the actual scheme at this point, print both
|
|
||||||
LogPrintf("MASTERNODE:\n blsPubKeyOperator legacy: %s\n blsPubKeyOperator basic: %s\n",
|
|
||||||
activeMasternodeInfo.blsPubKeyOperator->ToString(true),
|
|
||||||
activeMasternodeInfo.blsPubKeyOperator->ToString(false));
|
|
||||||
} else {
|
|
||||||
LOCK(activeMasternodeInfoCs);
|
|
||||||
activeMasternodeInfo.blsKeyOperator = std::make_unique<CBLSSecretKey>();
|
|
||||||
activeMasternodeInfo.blsPubKeyOperator = std::make_unique<CBLSPublicKey>();
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(!node.scheduler);
|
assert(!node.scheduler);
|
||||||
node.scheduler = std::make_unique<CScheduler>();
|
node.scheduler = std::make_unique<CScheduler>();
|
||||||
|
|
||||||
@ -1875,10 +1844,20 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
|
|||||||
);
|
);
|
||||||
RegisterValidationInterface(pdsNotificationInterface);
|
RegisterValidationInterface(pdsNotificationInterface);
|
||||||
|
|
||||||
if (fMasternodeMode) {
|
fMasternodeMode = false;
|
||||||
// Create and register activeMasternodeManager, will init later in ThreadImport
|
std::string strMasterNodeBLSPrivKey = args.GetArg("-masternodeblsprivkey", "");
|
||||||
activeMasternodeManager = std::make_unique<CActiveMasternodeManager>(*node.connman, ::deterministicMNManager);
|
if (!strMasterNodeBLSPrivKey.empty()) {
|
||||||
RegisterValidationInterface(activeMasternodeManager.get());
|
CBLSSecretKey keyOperator(ParseHex(strMasterNodeBLSPrivKey));
|
||||||
|
if (!keyOperator.IsValid()) {
|
||||||
|
return InitError(_("Invalid masternodeblsprivkey. Please see documentation."));
|
||||||
|
}
|
||||||
|
fMasternodeMode = true;
|
||||||
|
{
|
||||||
|
// Create and register activeMasternodeManager, will init later in ThreadImport
|
||||||
|
::activeMasternodeManager = std::make_unique<CActiveMasternodeManager>(keyOperator, *node.connman, ::deterministicMNManager);
|
||||||
|
node.mn_activeman = ::activeMasternodeManager.get();
|
||||||
|
RegisterValidationInterface(node.mn_activeman);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ********************************************************* Step 7a: Load sporks
|
// ********************************************************* Step 7a: Load sporks
|
||||||
@ -1975,7 +1954,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
|
|||||||
node.llmq_ctx->Stop();
|
node.llmq_ctx->Stop();
|
||||||
}
|
}
|
||||||
node.llmq_ctx.reset();
|
node.llmq_ctx.reset();
|
||||||
node.llmq_ctx.reset(new LLMQContext(chainman.ActiveChainstate(), *node.connman, *node.dmnman, *node.evodb, *node.mnhf_manager, *node.sporkman, *node.mempool, node.peerman, false, fReset || fReindexChainState));
|
node.llmq_ctx.reset(new LLMQContext(chainman.ActiveChainstate(), *node.connman, *node.dmnman, *node.evodb, *node.mnhf_manager, *node.sporkman, *node.mempool, node.mn_activeman, node.peerman, false, fReset || fReindexChainState));
|
||||||
// Have to start it early to let VerifyDB check ChainLock signatures in coinbase
|
// Have to start it early to let VerifyDB check ChainLock signatures in coinbase
|
||||||
node.llmq_ctx->Start();
|
node.llmq_ctx->Start();
|
||||||
|
|
||||||
@ -2220,7 +2199,8 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
|
|||||||
|
|
||||||
// ********************************************************* Step 7c: Setup CoinJoin
|
// ********************************************************* Step 7c: Setup CoinJoin
|
||||||
|
|
||||||
node.cj_ctx = std::make_unique<CJContext>(chainman.ActiveChainstate(), *node.connman, *node.dmnman, *node.mempool, *node.mn_sync, !ignores_incoming_txs);
|
node.cj_ctx = std::make_unique<CJContext>(chainman.ActiveChainstate(), *node.connman, *node.dmnman, *node.mempool, node.mn_activeman,
|
||||||
|
*node.mn_sync, !ignores_incoming_txs);
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
node.coinjoin_loader = interfaces::MakeCoinJoinLoader(*node.cj_ctx->walletman);
|
node.coinjoin_loader = interfaces::MakeCoinJoinLoader(*node.cj_ctx->walletman);
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#include <masternode/sync.h>
|
#include <masternode/sync.h>
|
||||||
|
|
||||||
LLMQContext::LLMQContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CEvoDB& evo_db,
|
LLMQContext::LLMQContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CEvoDB& evo_db,
|
||||||
CMNHFManager& mnhfman, CSporkManager& sporkman, CTxMemPool& mempool,
|
CMNHFManager& mnhfman, CSporkManager& sporkman, CTxMemPool& mempool, const CActiveMasternodeManager* mn_activeman,
|
||||||
const std::unique_ptr<PeerManager>& peerman, bool unit_tests, bool wipe) :
|
const std::unique_ptr<PeerManager>& peerman, bool unit_tests, bool wipe) :
|
||||||
bls_worker{std::make_shared<CBLSWorker>()},
|
bls_worker{std::make_shared<CBLSWorker>()},
|
||||||
dkg_debugman{std::make_unique<llmq::CDKGDebugManager>()},
|
dkg_debugman{std::make_unique<llmq::CDKGDebugManager>()},
|
||||||
@ -29,14 +29,14 @@ LLMQContext::LLMQContext(CChainState& chainstate, CConnman& connman, CDeterminis
|
|||||||
llmq::quorumBlockProcessor = std::make_unique<llmq::CQuorumBlockProcessor>(chainstate, connman, dmnman, evo_db);
|
llmq::quorumBlockProcessor = std::make_unique<llmq::CQuorumBlockProcessor>(chainstate, connman, dmnman, evo_db);
|
||||||
return llmq::quorumBlockProcessor.get();
|
return llmq::quorumBlockProcessor.get();
|
||||||
}()},
|
}()},
|
||||||
qdkgsman{std::make_unique<llmq::CDKGSessionManager>(*bls_worker, chainstate, connman, dmnman, *dkg_debugman, *quorum_block_processor, sporkman, unit_tests, wipe)},
|
qdkgsman{std::make_unique<llmq::CDKGSessionManager>(*bls_worker, chainstate, connman, dmnman, *dkg_debugman, *quorum_block_processor, mn_activeman, sporkman, unit_tests, wipe)},
|
||||||
qman{[&]() -> llmq::CQuorumManager* const {
|
qman{[&]() -> llmq::CQuorumManager* const {
|
||||||
assert(llmq::quorumManager == nullptr);
|
assert(llmq::quorumManager == nullptr);
|
||||||
llmq::quorumManager = std::make_unique<llmq::CQuorumManager>(*bls_worker, chainstate, connman, dmnman, *qdkgsman, evo_db, *quorum_block_processor, sporkman, ::masternodeSync);
|
llmq::quorumManager = std::make_unique<llmq::CQuorumManager>(*bls_worker, chainstate, connman, dmnman, *qdkgsman, evo_db, *quorum_block_processor, mn_activeman, sporkman, ::masternodeSync);
|
||||||
return llmq::quorumManager.get();
|
return llmq::quorumManager.get();
|
||||||
}()},
|
}()},
|
||||||
sigman{std::make_unique<llmq::CSigningManager>(connman, *llmq::quorumManager, unit_tests, wipe)},
|
sigman{std::make_unique<llmq::CSigningManager>(connman, mn_activeman, *llmq::quorumManager, unit_tests, wipe)},
|
||||||
shareman{std::make_unique<llmq::CSigSharesManager>(connman, *sigman, *llmq::quorumManager, sporkman, peerman)},
|
shareman{std::make_unique<llmq::CSigSharesManager>(connman, *sigman, mn_activeman, *llmq::quorumManager, sporkman, peerman)},
|
||||||
clhandler{[&]() -> llmq::CChainLocksHandler* const {
|
clhandler{[&]() -> llmq::CChainLocksHandler* const {
|
||||||
assert(llmq::chainLocksHandler == nullptr);
|
assert(llmq::chainLocksHandler == nullptr);
|
||||||
llmq::chainLocksHandler = std::make_unique<llmq::CChainLocksHandler>(chainstate, connman, *::masternodeSync, *llmq::quorumManager, *sigman, *shareman, sporkman, mempool);
|
llmq::chainLocksHandler = std::make_unique<llmq::CChainLocksHandler>(chainstate, connman, *::masternodeSync, *llmq::quorumManager, *sigman, *shareman, sporkman, mempool);
|
||||||
@ -77,7 +77,9 @@ void LLMQContext::Start() {
|
|||||||
assert(isman == llmq::quorumInstantSendManager.get());
|
assert(isman == llmq::quorumInstantSendManager.get());
|
||||||
|
|
||||||
bls_worker->Start();
|
bls_worker->Start();
|
||||||
qdkgsman->StartThreads();
|
if (fMasternodeMode) {
|
||||||
|
qdkgsman->StartThreads();
|
||||||
|
}
|
||||||
qman->Start();
|
qman->Start();
|
||||||
shareman->RegisterAsRecoveredSigsListener();
|
shareman->RegisterAsRecoveredSigsListener();
|
||||||
shareman->StartWorkerThread();
|
shareman->StartWorkerThread();
|
||||||
@ -100,6 +102,8 @@ void LLMQContext::Stop() {
|
|||||||
shareman->UnregisterAsRecoveredSigsListener();
|
shareman->UnregisterAsRecoveredSigsListener();
|
||||||
sigman->StopWorkerThread();
|
sigman->StopWorkerThread();
|
||||||
qman->Stop();
|
qman->Stop();
|
||||||
qdkgsman->StopThreads();
|
if (fMasternodeMode) {
|
||||||
|
qdkgsman->StopThreads();
|
||||||
|
}
|
||||||
bls_worker->Stop();
|
bls_worker->Stop();
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
class CActiveMasternodeManager;
|
||||||
class CBLSWorker;
|
class CBLSWorker;
|
||||||
class CChainState;
|
class CChainState;
|
||||||
class CConnman;
|
class CConnman;
|
||||||
@ -34,7 +35,7 @@ struct LLMQContext {
|
|||||||
LLMQContext() = delete;
|
LLMQContext() = delete;
|
||||||
LLMQContext(const LLMQContext&) = delete;
|
LLMQContext(const LLMQContext&) = delete;
|
||||||
LLMQContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CEvoDB& evo_db,
|
LLMQContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CEvoDB& evo_db,
|
||||||
CMNHFManager& mnhfman, CSporkManager& sporkman, CTxMemPool& mempool,
|
CMNHFManager& mnhfman, CSporkManager& sporkman, CTxMemPool& mempool, const CActiveMasternodeManager* mn_activeman,
|
||||||
const std::unique_ptr<PeerManager>& peerman, bool unit_tests, bool wipe);
|
const std::unique_ptr<PeerManager>& peerman, bool unit_tests, bool wipe);
|
||||||
~LLMQContext();
|
~LLMQContext();
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ void CDKGSession::SendContributions(CDKGPendingMessages& pendingMessages)
|
|||||||
|
|
||||||
logger.Batch("encrypted contributions. time=%d", t1.count());
|
logger.Batch("encrypted contributions. time=%d", t1.count());
|
||||||
|
|
||||||
qc.sig = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.blsKeyOperator->Sign(qc.GetSignHash()));
|
qc.sig = m_mn_activeman->Sign(qc.GetSignHash());
|
||||||
|
|
||||||
logger.Flush();
|
logger.Flush();
|
||||||
|
|
||||||
@ -316,7 +316,7 @@ void CDKGSession::ReceiveMessage(const CDKGContribution& qc, bool& retBan)
|
|||||||
|
|
||||||
bool complain = false;
|
bool complain = false;
|
||||||
CBLSSecretKey skContribution;
|
CBLSSecretKey skContribution;
|
||||||
if (!qc.contributions->Decrypt(*myIdx, WITH_LOCK(activeMasternodeInfoCs, return *activeMasternodeInfo.blsKeyOperator), skContribution, PROTOCOL_VERSION)) {
|
if (!m_mn_activeman->Decrypt(*qc.contributions, *myIdx, skContribution, PROTOCOL_VERSION)) {
|
||||||
logger.Batch("contribution from %s could not be decrypted", member->dmn->proTxHash.ToString());
|
logger.Batch("contribution from %s could not be decrypted", member->dmn->proTxHash.ToString());
|
||||||
complain = true;
|
complain = true;
|
||||||
} else if (member->idx != myIdx && ShouldSimulateError(DKGError::type::COMPLAIN_LIE)) {
|
} else if (member->idx != myIdx && ShouldSimulateError(DKGError::type::COMPLAIN_LIE)) {
|
||||||
@ -517,7 +517,7 @@ void CDKGSession::SendComplaint(CDKGPendingMessages& pendingMessages)
|
|||||||
|
|
||||||
logger.Batch("sending complaint. badCount=%d, complaintCount=%d", badCount, complaintCount);
|
logger.Batch("sending complaint. badCount=%d, complaintCount=%d", badCount, complaintCount);
|
||||||
|
|
||||||
qc.sig = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.blsKeyOperator->Sign(qc.GetSignHash()));
|
qc.sig = m_mn_activeman->Sign(qc.GetSignHash());
|
||||||
|
|
||||||
logger.Flush();
|
logger.Flush();
|
||||||
|
|
||||||
@ -711,7 +711,7 @@ void CDKGSession::SendJustification(CDKGPendingMessages& pendingMessages, const
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qj.sig = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.blsKeyOperator->Sign(qj.GetSignHash()));
|
qj.sig = m_mn_activeman->Sign(qj.GetSignHash());
|
||||||
|
|
||||||
logger.Flush();
|
logger.Flush();
|
||||||
|
|
||||||
@ -1003,7 +1003,7 @@ void CDKGSession::SendCommitment(CDKGPendingMessages& pendingMessages)
|
|||||||
(*commitmentHash.begin())++;
|
(*commitmentHash.begin())++;
|
||||||
}
|
}
|
||||||
|
|
||||||
qc.sig = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.blsKeyOperator->Sign(commitmentHash));
|
qc.sig = m_mn_activeman->Sign(commitmentHash);
|
||||||
qc.quorumSig = skShare.Sign(commitmentHash);
|
qc.quorumSig = skShare.Sign(commitmentHash);
|
||||||
|
|
||||||
if (lieType == 3) {
|
if (lieType == 3) {
|
||||||
|
@ -15,11 +15,13 @@
|
|||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
class UniValue;
|
class CActiveMasternodeManager;
|
||||||
class CInv;
|
class CInv;
|
||||||
class CConnman;
|
class CConnman;
|
||||||
class CDeterministicMN;
|
class CDeterministicMN;
|
||||||
class CSporkManager;
|
class CSporkManager;
|
||||||
|
class UniValue;
|
||||||
|
|
||||||
using CDeterministicMNCPtr = std::shared_ptr<const CDeterministicMN>;
|
using CDeterministicMNCPtr = std::shared_ptr<const CDeterministicMN>;
|
||||||
|
|
||||||
namespace llmq
|
namespace llmq
|
||||||
@ -273,6 +275,7 @@ private:
|
|||||||
CDeterministicMNManager& m_dmnman;
|
CDeterministicMNManager& m_dmnman;
|
||||||
CDKGSessionManager& dkgManager;
|
CDKGSessionManager& dkgManager;
|
||||||
CDKGDebugManager& dkgDebugManager;
|
CDKGDebugManager& dkgDebugManager;
|
||||||
|
const CActiveMasternodeManager* m_mn_activeman;
|
||||||
const CSporkManager& m_sporkman;
|
const CSporkManager& m_sporkman;
|
||||||
|
|
||||||
const CBlockIndex* m_quorum_base_block_index{nullptr};
|
const CBlockIndex* m_quorum_base_block_index{nullptr};
|
||||||
@ -314,8 +317,11 @@ private:
|
|||||||
std::set<uint256> validCommitments GUARDED_BY(invCs);
|
std::set<uint256> validCommitments GUARDED_BY(invCs);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CDKGSession(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker, CDeterministicMNManager& dmnman, CDKGSessionManager& _dkgManager, CDKGDebugManager& _dkgDebugManager, CConnman& _connman, const CSporkManager& sporkman) :
|
CDKGSession(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker, CDeterministicMNManager& dmnman,
|
||||||
params(_params), blsWorker(_blsWorker), cache(_blsWorker), m_dmnman(dmnman), dkgManager(_dkgManager), dkgDebugManager(_dkgDebugManager), m_sporkman(sporkman), connman(_connman) {}
|
CDKGSessionManager& _dkgManager, CDKGDebugManager& _dkgDebugManager, CConnman& _connman,
|
||||||
|
const CActiveMasternodeManager* mn_activeman, const CSporkManager& sporkman) :
|
||||||
|
params(_params), blsWorker(_blsWorker), cache(_blsWorker), m_dmnman(dmnman), dkgManager(_dkgManager),
|
||||||
|
dkgDebugManager(_dkgDebugManager), m_mn_activeman(mn_activeman), m_sporkman(sporkman), connman(_connman) {}
|
||||||
|
|
||||||
bool Init(gsl::not_null<const CBlockIndex*> pQuorumBaseBlockIndex, Span<CDeterministicMNCPtr> mns, const uint256& _myProTxHash, int _quorumIndex);
|
bool Init(gsl::not_null<const CBlockIndex*> pQuorumBaseBlockIndex, Span<CDeterministicMNCPtr> mns, const uint256& _myProTxHash, int _quorumIndex);
|
||||||
|
|
||||||
|
@ -26,7 +26,8 @@ namespace llmq
|
|||||||
|
|
||||||
CDKGSessionHandler::CDKGSessionHandler(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman,
|
CDKGSessionHandler::CDKGSessionHandler(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman,
|
||||||
CDKGDebugManager& _dkgDebugManager, CDKGSessionManager& _dkgManager, CQuorumBlockProcessor& _quorumBlockProcessor,
|
CDKGDebugManager& _dkgDebugManager, CDKGSessionManager& _dkgManager, CQuorumBlockProcessor& _quorumBlockProcessor,
|
||||||
const CSporkManager& sporkman, const Consensus::LLMQParams& _params, int _quorumIndex) :
|
const CActiveMasternodeManager* mn_activeman, const CSporkManager& sporkman, const Consensus::LLMQParams& _params,
|
||||||
|
int _quorumIndex) :
|
||||||
blsWorker(_blsWorker),
|
blsWorker(_blsWorker),
|
||||||
m_chainstate(chainstate),
|
m_chainstate(chainstate),
|
||||||
connman(_connman),
|
connman(_connman),
|
||||||
@ -34,10 +35,11 @@ CDKGSessionHandler::CDKGSessionHandler(CBLSWorker& _blsWorker, CChainState& chai
|
|||||||
dkgDebugManager(_dkgDebugManager),
|
dkgDebugManager(_dkgDebugManager),
|
||||||
dkgManager(_dkgManager),
|
dkgManager(_dkgManager),
|
||||||
quorumBlockProcessor(_quorumBlockProcessor),
|
quorumBlockProcessor(_quorumBlockProcessor),
|
||||||
|
m_mn_activeman(mn_activeman),
|
||||||
m_sporkman(sporkman),
|
m_sporkman(sporkman),
|
||||||
params(_params),
|
params(_params),
|
||||||
quorumIndex(_quorumIndex),
|
quorumIndex(_quorumIndex),
|
||||||
curSession(std::make_unique<CDKGSession>(_params, _blsWorker, dmnman, _dkgManager, _dkgDebugManager, _connman, sporkman)),
|
curSession(std::make_unique<CDKGSession>(_params, _blsWorker, dmnman, _dkgManager, _dkgDebugManager, _connman, m_mn_activeman, sporkman)),
|
||||||
pendingContributions((size_t)_params.size * 2, MSG_QUORUM_CONTRIB), // we allow size*2 messages as we need to make sure we see bad behavior (double messages)
|
pendingContributions((size_t)_params.size * 2, MSG_QUORUM_CONTRIB), // we allow size*2 messages as we need to make sure we see bad behavior (double messages)
|
||||||
pendingComplaints((size_t)_params.size * 2, MSG_QUORUM_COMPLAINT),
|
pendingComplaints((size_t)_params.size * 2, MSG_QUORUM_COMPLAINT),
|
||||||
pendingJustifications((size_t)_params.size * 2, MSG_QUORUM_JUSTIFICATION),
|
pendingJustifications((size_t)_params.size * 2, MSG_QUORUM_JUSTIFICATION),
|
||||||
@ -185,14 +187,14 @@ void CDKGSessionHandler::StopThread()
|
|||||||
|
|
||||||
bool CDKGSessionHandler::InitNewQuorum(const CBlockIndex* pQuorumBaseBlockIndex)
|
bool CDKGSessionHandler::InitNewQuorum(const CBlockIndex* pQuorumBaseBlockIndex)
|
||||||
{
|
{
|
||||||
curSession = std::make_unique<CDKGSession>(params, blsWorker, m_dmnman, dkgManager, dkgDebugManager, connman, m_sporkman);
|
curSession = std::make_unique<CDKGSession>(params, blsWorker, m_dmnman, dkgManager, dkgDebugManager, connman, m_mn_activeman, m_sporkman);
|
||||||
|
|
||||||
if (!DeploymentDIP0003Enforced(pQuorumBaseBlockIndex->nHeight, Params().GetConsensus())) {
|
if (!DeploymentDIP0003Enforced(pQuorumBaseBlockIndex->nHeight, Params().GetConsensus())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto mns = utils::GetAllQuorumMembers(params.type, m_dmnman, pQuorumBaseBlockIndex);
|
auto mns = utils::GetAllQuorumMembers(params.type, m_dmnman, pQuorumBaseBlockIndex);
|
||||||
if (!curSession->Init(pQuorumBaseBlockIndex, mns, WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash), quorumIndex)) {
|
if (!curSession->Init(pQuorumBaseBlockIndex, mns, WITH_LOCK(m_mn_activeman->cs, return m_mn_activeman->GetProTxHash()), quorumIndex)) {
|
||||||
LogPrintf("CDKGSessionManager::%s -- height[%d] quorum initialization failed for %s qi[%d] mns[%d]\n", __func__, pQuorumBaseBlockIndex->nHeight, curSession->params.name, quorumIndex, mns.size());
|
LogPrintf("CDKGSessionManager::%s -- height[%d] quorum initialization failed for %s qi[%d] mns[%d]\n", __func__, pQuorumBaseBlockIndex->nHeight, curSession->params.name, quorumIndex, mns.size());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
|
class CActiveMasternodeManager;
|
||||||
class CBlockIndex;
|
class CBlockIndex;
|
||||||
class CBLSWorker;
|
class CBLSWorker;
|
||||||
class CChainState;
|
class CChainState;
|
||||||
@ -125,6 +126,7 @@ private:
|
|||||||
CDKGDebugManager& dkgDebugManager;
|
CDKGDebugManager& dkgDebugManager;
|
||||||
CDKGSessionManager& dkgManager;
|
CDKGSessionManager& dkgManager;
|
||||||
CQuorumBlockProcessor& quorumBlockProcessor;
|
CQuorumBlockProcessor& quorumBlockProcessor;
|
||||||
|
const CActiveMasternodeManager* m_mn_activeman;
|
||||||
const CSporkManager& m_sporkman;
|
const CSporkManager& m_sporkman;
|
||||||
const Consensus::LLMQParams params;
|
const Consensus::LLMQParams params;
|
||||||
const int quorumIndex;
|
const int quorumIndex;
|
||||||
@ -146,7 +148,8 @@ private:
|
|||||||
public:
|
public:
|
||||||
CDKGSessionHandler(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman,
|
CDKGSessionHandler(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman,
|
||||||
CDKGDebugManager& _dkgDebugManager, CDKGSessionManager& _dkgManager, CQuorumBlockProcessor& _quorumBlockProcessor,
|
CDKGDebugManager& _dkgDebugManager, CDKGSessionManager& _dkgManager, CQuorumBlockProcessor& _quorumBlockProcessor,
|
||||||
const CSporkManager& sporkman, const Consensus::LLMQParams& _params, int _quorumIndex);
|
const CActiveMasternodeManager* mn_activeman, const CSporkManager& sporkman, const Consensus::LLMQParams& _params,
|
||||||
|
int _quorumIndex);
|
||||||
~CDKGSessionHandler() = default;
|
~CDKGSessionHandler() = default;
|
||||||
|
|
||||||
void UpdatedBlockTip(const CBlockIndex *pindexNew);
|
void UpdatedBlockTip(const CBlockIndex *pindexNew);
|
||||||
|
@ -25,8 +25,8 @@ static const std::string DB_SKCONTRIB = "qdkg_S";
|
|||||||
static const std::string DB_ENC_CONTRIB = "qdkg_E";
|
static const std::string DB_ENC_CONTRIB = "qdkg_E";
|
||||||
|
|
||||||
CDKGSessionManager::CDKGSessionManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman,
|
CDKGSessionManager::CDKGSessionManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman,
|
||||||
CDKGDebugManager& _dkgDebugManager, CQuorumBlockProcessor& _quorumBlockProcessor, const CSporkManager& sporkman,
|
CDKGDebugManager& _dkgDebugManager, CQuorumBlockProcessor& _quorumBlockProcessor, const CActiveMasternodeManager* mn_activeman,
|
||||||
bool unitTests, bool fWipe) :
|
const CSporkManager& sporkman, bool unitTests, bool fWipe) :
|
||||||
db(std::make_unique<CDBWrapper>(unitTests ? "" : (GetDataDir() / "llmq/dkgdb"), 1 << 20, unitTests, fWipe)),
|
db(std::make_unique<CDBWrapper>(unitTests ? "" : (GetDataDir() / "llmq/dkgdb"), 1 << 20, unitTests, fWipe)),
|
||||||
blsWorker(_blsWorker),
|
blsWorker(_blsWorker),
|
||||||
m_chainstate(chainstate),
|
m_chainstate(chainstate),
|
||||||
@ -49,7 +49,7 @@ CDKGSessionManager::CDKGSessionManager(CBLSWorker& _blsWorker, CChainState& chai
|
|||||||
for (const auto i : irange::range(session_count)) {
|
for (const auto i : irange::range(session_count)) {
|
||||||
dkgSessionHandlers.emplace(std::piecewise_construct,
|
dkgSessionHandlers.emplace(std::piecewise_construct,
|
||||||
std::forward_as_tuple(params.type, i),
|
std::forward_as_tuple(params.type, i),
|
||||||
std::forward_as_tuple(blsWorker, m_chainstate, connman, dmnman, dkgDebugManager, *this, quorumBlockProcessor, spork_manager, params, i));
|
std::forward_as_tuple(blsWorker, m_chainstate, connman, dmnman, dkgDebugManager, *this, quorumBlockProcessor, mn_activeman, spork_manager, params, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
class CActiveMasternodeManager;
|
||||||
class CBlockIndex;
|
class CBlockIndex;
|
||||||
class CChainState;
|
class CChainState;
|
||||||
class CDBWrapper;
|
class CDBWrapper;
|
||||||
@ -66,8 +67,8 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
CDKGSessionManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman,
|
CDKGSessionManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman,
|
||||||
CDKGDebugManager& _dkgDebugManager, CQuorumBlockProcessor& _quorumBlockProcessor, const CSporkManager& sporkman,
|
CDKGDebugManager& _dkgDebugManager, CQuorumBlockProcessor& _quorumBlockProcessor, const CActiveMasternodeManager* mn_activeman,
|
||||||
bool unitTests, bool fWipe);
|
const CSporkManager& sporkman, bool unitTests, bool fWipe);
|
||||||
~CDKGSessionManager() = default;
|
~CDKGSessionManager() = default;
|
||||||
|
|
||||||
void StartThreads();
|
void StartThreads();
|
||||||
|
@ -101,9 +101,9 @@ bool CQuorum::SetVerificationVector(const std::vector<CBLSPublicKey>& quorumVecI
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CQuorum::SetSecretKeyShare(const CBLSSecretKey& secretKeyShare)
|
bool CQuorum::SetSecretKeyShare(const CBLSSecretKey& secretKeyShare, const CActiveMasternodeManager& mn_activeman)
|
||||||
{
|
{
|
||||||
if (!secretKeyShare.IsValid() || (secretKeyShare.GetPublicKey() != GetPubKeyShare(WITH_LOCK(activeMasternodeInfoCs, return GetMemberIndex(activeMasternodeInfo.proTxHash))))) {
|
if (!secretKeyShare.IsValid() || (secretKeyShare.GetPublicKey() != GetPubKeyShare(WITH_LOCK(mn_activeman.cs, return GetMemberIndex(mn_activeman.GetProTxHash()))))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
@ -205,8 +205,10 @@ bool CQuorum::ReadContributions(CEvoDB& evoDb)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CQuorumManager::CQuorumManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman, CDKGSessionManager& _dkgManager,
|
CQuorumManager::CQuorumManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman,
|
||||||
CEvoDB& _evoDb, CQuorumBlockProcessor& _quorumBlockProcessor, const CSporkManager& sporkman, const std::unique_ptr<CMasternodeSync>& mn_sync) :
|
CDKGSessionManager& _dkgManager, CEvoDB& _evoDb, CQuorumBlockProcessor& _quorumBlockProcessor,
|
||||||
|
const CActiveMasternodeManager* mn_activeman, const CSporkManager& sporkman,
|
||||||
|
const std::unique_ptr<CMasternodeSync>& mn_sync) :
|
||||||
blsWorker(_blsWorker),
|
blsWorker(_blsWorker),
|
||||||
m_chainstate(chainstate),
|
m_chainstate(chainstate),
|
||||||
connman(_connman),
|
connman(_connman),
|
||||||
@ -214,6 +216,7 @@ CQuorumManager::CQuorumManager(CBLSWorker& _blsWorker, CChainState& chainstate,
|
|||||||
dkgManager(_dkgManager),
|
dkgManager(_dkgManager),
|
||||||
m_evoDb(_evoDb),
|
m_evoDb(_evoDb),
|
||||||
quorumBlockProcessor(_quorumBlockProcessor),
|
quorumBlockProcessor(_quorumBlockProcessor),
|
||||||
|
m_mn_activeman(mn_activeman),
|
||||||
m_sporkman(sporkman),
|
m_sporkman(sporkman),
|
||||||
m_mn_sync(mn_sync)
|
m_mn_sync(mn_sync)
|
||||||
{
|
{
|
||||||
@ -250,7 +253,12 @@ void CQuorumManager::TriggerQuorumDataRecoveryThreads(const CBlockIndex* pIndex)
|
|||||||
const auto vecQuorums = ScanQuorums(params.type, pIndex, params.keepOldConnections);
|
const auto vecQuorums = ScanQuorums(params.type, pIndex, params.keepOldConnections);
|
||||||
|
|
||||||
// First check if we are member of any quorum of this type
|
// First check if we are member of any quorum of this type
|
||||||
auto proTxHash = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash);
|
const uint256 proTxHash = [this]() {
|
||||||
|
if (!fMasternodeMode) return uint256();
|
||||||
|
assert(m_mn_activeman);
|
||||||
|
return WITH_LOCK(m_mn_activeman->cs, return m_mn_activeman->GetProTxHash());
|
||||||
|
}();
|
||||||
|
|
||||||
bool fWeAreQuorumTypeMember = ranges::any_of(vecQuorums, [&proTxHash](const auto& pQuorum) {
|
bool fWeAreQuorumTypeMember = ranges::any_of(vecQuorums, [&proTxHash](const auto& pQuorum) {
|
||||||
return pQuorum->IsValidMember(proTxHash);
|
return pQuorum->IsValidMember(proTxHash);
|
||||||
});
|
});
|
||||||
@ -341,7 +349,12 @@ void CQuorumManager::CheckQuorumConnections(const Consensus::LLMQParams& llmqPar
|
|||||||
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- llmqType[%d] h[%d] keeping mn quorum connections for quorum: [%d:%s]\n", __func__, ToUnderlying(llmqParams.type), pindexNew->nHeight, curDkgHeight, curDkgBlock.ToString());
|
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- llmqType[%d] h[%d] keeping mn quorum connections for quorum: [%d:%s]\n", __func__, ToUnderlying(llmqParams.type), pindexNew->nHeight, curDkgHeight, curDkgBlock.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto myProTxHash = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash);
|
const uint256 myProTxHash = [this]() {
|
||||||
|
if (!fMasternodeMode) return uint256();
|
||||||
|
assert(m_mn_activeman);
|
||||||
|
return WITH_LOCK(m_mn_activeman->cs, return m_mn_activeman->GetProTxHash());
|
||||||
|
}();
|
||||||
|
|
||||||
bool isISType = llmqParams.type == Params().GetConsensus().llmqTypeDIP0024InstantSend;
|
bool isISType = llmqParams.type == Params().GetConsensus().llmqTypeDIP0024InstantSend;
|
||||||
|
|
||||||
bool watchOtherISQuorums = isISType && !myProTxHash.IsNull() &&
|
bool watchOtherISQuorums = isISType && !myProTxHash.IsNull() &&
|
||||||
@ -640,6 +653,8 @@ CQuorumCPtr CQuorumManager::GetQuorum(Consensus::LLMQType llmqType, gsl::not_nul
|
|||||||
|
|
||||||
size_t CQuorumManager::GetQuorumRecoveryStartOffset(const CQuorumCPtr pQuorum, const CBlockIndex* pIndex) const
|
size_t CQuorumManager::GetQuorumRecoveryStartOffset(const CQuorumCPtr pQuorum, const CBlockIndex* pIndex) const
|
||||||
{
|
{
|
||||||
|
assert(m_mn_activeman);
|
||||||
|
|
||||||
auto mns = m_dmnman.GetListForBlock(pIndex);
|
auto mns = m_dmnman.GetListForBlock(pIndex);
|
||||||
std::vector<uint256> vecProTxHashes;
|
std::vector<uint256> vecProTxHashes;
|
||||||
vecProTxHashes.reserve(mns.GetValidMNsCount());
|
vecProTxHashes.reserve(mns.GetValidMNsCount());
|
||||||
@ -649,10 +664,10 @@ size_t CQuorumManager::GetQuorumRecoveryStartOffset(const CQuorumCPtr pQuorum, c
|
|||||||
std::sort(vecProTxHashes.begin(), vecProTxHashes.end());
|
std::sort(vecProTxHashes.begin(), vecProTxHashes.end());
|
||||||
size_t nIndex{0};
|
size_t nIndex{0};
|
||||||
{
|
{
|
||||||
LOCK(activeMasternodeInfoCs);
|
LOCK(m_mn_activeman->cs);
|
||||||
for (const auto i : irange::range(vecProTxHashes.size())) {
|
for (const auto i : irange::range(vecProTxHashes.size())) {
|
||||||
// cppcheck-suppress useStlAlgorithm
|
// cppcheck-suppress useStlAlgorithm
|
||||||
if (activeMasternodeInfo.proTxHash == vecProTxHashes[i]) {
|
if (m_mn_activeman->GetProTxHash() == vecProTxHashes[i]) {
|
||||||
nIndex = i;
|
nIndex = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -813,6 +828,7 @@ PeerMsgRet CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_t
|
|||||||
|
|
||||||
// Check if request has ENCRYPTED_CONTRIBUTIONS data
|
// Check if request has ENCRYPTED_CONTRIBUTIONS data
|
||||||
if (request.GetDataMask() & CQuorumDataRequest::ENCRYPTED_CONTRIBUTIONS) {
|
if (request.GetDataMask() & CQuorumDataRequest::ENCRYPTED_CONTRIBUTIONS) {
|
||||||
|
assert(fMasternodeMode);
|
||||||
|
|
||||||
if (WITH_LOCK(pQuorum->cs, return pQuorum->quorumVvec->size() != size_t(pQuorum->params.threshold))) {
|
if (WITH_LOCK(pQuorum->cs, return pQuorum->quorumVvec->size() != size_t(pQuorum->params.threshold))) {
|
||||||
return errorHandler("No valid quorum verification vector available", 0); // Don't bump score because we asked for it
|
return errorHandler("No valid quorum verification vector available", 0); // Don't bump score because we asked for it
|
||||||
@ -828,15 +844,14 @@ PeerMsgRet CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_t
|
|||||||
|
|
||||||
std::vector<CBLSSecretKey> vecSecretKeys;
|
std::vector<CBLSSecretKey> vecSecretKeys;
|
||||||
vecSecretKeys.resize(vecEncrypted.size());
|
vecSecretKeys.resize(vecEncrypted.size());
|
||||||
auto secret = WITH_LOCK(activeMasternodeInfoCs, return *activeMasternodeInfo.blsKeyOperator);
|
|
||||||
for (const auto i : irange::range(vecEncrypted.size())) {
|
for (const auto i : irange::range(vecEncrypted.size())) {
|
||||||
if (!vecEncrypted[i].Decrypt(memberIdx, secret, vecSecretKeys[i], PROTOCOL_VERSION)) {
|
if (!Assert(m_mn_activeman)->Decrypt(vecEncrypted[i], memberIdx, vecSecretKeys[i], PROTOCOL_VERSION)) {
|
||||||
return errorHandler("Failed to decrypt");
|
return errorHandler("Failed to decrypt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CBLSSecretKey secretKeyShare = blsWorker.AggregateSecretKeys(vecSecretKeys);
|
CBLSSecretKey secretKeyShare = blsWorker.AggregateSecretKeys(vecSecretKeys);
|
||||||
if (!pQuorum->SetSecretKeyShare(secretKeyShare)) {
|
if (!pQuorum->SetSecretKeyShare(secretKeyShare, *m_mn_activeman)) {
|
||||||
return errorHandler("Invalid secret key share received");
|
return errorHandler("Invalid secret key share received");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -878,6 +893,8 @@ void CQuorumManager::StartCachePopulatorThread(const CQuorumCPtr pQuorum) const
|
|||||||
|
|
||||||
void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, const CBlockIndex* pIndex, uint16_t nDataMaskIn) const
|
void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, const CBlockIndex* pIndex, uint16_t nDataMaskIn) const
|
||||||
{
|
{
|
||||||
|
assert(m_mn_activeman);
|
||||||
|
|
||||||
if (pQuorum->fQuorumDataRecoveryThreadRunning) {
|
if (pQuorum->fQuorumDataRecoveryThreadRunning) {
|
||||||
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- Already running\n", __func__);
|
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- Already running\n", __func__);
|
||||||
return;
|
return;
|
||||||
@ -911,7 +928,7 @@ void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, co
|
|||||||
|
|
||||||
vecMemberHashes.reserve(pQuorum->qc->validMembers.size());
|
vecMemberHashes.reserve(pQuorum->qc->validMembers.size());
|
||||||
for (auto& member : pQuorum->members) {
|
for (auto& member : pQuorum->members) {
|
||||||
if (pQuorum->IsValidMember(member->proTxHash) && member->proTxHash != WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash)) {
|
if (pQuorum->IsValidMember(member->proTxHash) && member->proTxHash != WITH_LOCK(m_mn_activeman->cs, return m_mn_activeman->GetProTxHash())) {
|
||||||
vecMemberHashes.push_back(member->proTxHash);
|
vecMemberHashes.push_back(member->proTxHash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -960,7 +977,7 @@ void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, co
|
|||||||
printLog("Connect");
|
printLog("Connect");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto proTxHash = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash);
|
auto proTxHash = WITH_LOCK(m_mn_activeman->cs, return m_mn_activeman->GetProTxHash());
|
||||||
connman.ForEachNode([&](CNode* pNode) {
|
connman.ForEachNode([&](CNode* pNode) {
|
||||||
auto verifiedProRegTxHash = pNode->GetVerifiedProRegTxHash();
|
auto verifiedProRegTxHash = pNode->GetVerifiedProRegTxHash();
|
||||||
if (pCurrentMemberHash == nullptr || verifiedProRegTxHash != *pCurrentMemberHash) {
|
if (pCurrentMemberHash == nullptr || verifiedProRegTxHash != *pCurrentMemberHash) {
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
class CActiveMasternodeManager;
|
||||||
class CBlockIndex;
|
class CBlockIndex;
|
||||||
class CChainState;
|
class CChainState;
|
||||||
class CConnman;
|
class CConnman;
|
||||||
@ -192,7 +193,7 @@ public:
|
|||||||
void Init(CFinalCommitmentPtr _qc, const CBlockIndex* _pQuorumBaseBlockIndex, const uint256& _minedBlockHash, Span<CDeterministicMNCPtr> _members);
|
void Init(CFinalCommitmentPtr _qc, const CBlockIndex* _pQuorumBaseBlockIndex, const uint256& _minedBlockHash, Span<CDeterministicMNCPtr> _members);
|
||||||
|
|
||||||
bool SetVerificationVector(const std::vector<CBLSPublicKey>& quorumVecIn);
|
bool SetVerificationVector(const std::vector<CBLSPublicKey>& quorumVecIn);
|
||||||
bool SetSecretKeyShare(const CBLSSecretKey& secretKeyShare);
|
bool SetSecretKeyShare(const CBLSSecretKey& secretKeyShare, const CActiveMasternodeManager& mn_activeman);
|
||||||
|
|
||||||
bool HasVerificationVector() const;
|
bool HasVerificationVector() const;
|
||||||
bool IsMember(const uint256& proTxHash) const;
|
bool IsMember(const uint256& proTxHash) const;
|
||||||
@ -223,6 +224,7 @@ private:
|
|||||||
CDKGSessionManager& dkgManager;
|
CDKGSessionManager& dkgManager;
|
||||||
CEvoDB& m_evoDb;
|
CEvoDB& m_evoDb;
|
||||||
CQuorumBlockProcessor& quorumBlockProcessor;
|
CQuorumBlockProcessor& quorumBlockProcessor;
|
||||||
|
const CActiveMasternodeManager* m_mn_activeman;
|
||||||
const CSporkManager& m_sporkman;
|
const CSporkManager& m_sporkman;
|
||||||
const std::unique_ptr<CMasternodeSync>& m_mn_sync;
|
const std::unique_ptr<CMasternodeSync>& m_mn_sync;
|
||||||
|
|
||||||
@ -237,8 +239,9 @@ private:
|
|||||||
mutable CThreadInterrupt quorumThreadInterrupt;
|
mutable CThreadInterrupt quorumThreadInterrupt;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CQuorumManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman, CDKGSessionManager& _dkgManager,
|
CQuorumManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman,
|
||||||
CEvoDB& _evoDb, CQuorumBlockProcessor& _quorumBlockProcessor, const CSporkManager& sporkman, const std::unique_ptr<CMasternodeSync>& mn_sync);
|
CDKGSessionManager& _dkgManager, CEvoDB& _evoDb, CQuorumBlockProcessor& _quorumBlockProcessor,
|
||||||
|
const CActiveMasternodeManager* mn_activeman, const CSporkManager& sporkman, const std::unique_ptr<CMasternodeSync>& mn_sync);
|
||||||
~CQuorumManager() { Stop(); };
|
~CQuorumManager() { Stop(); };
|
||||||
|
|
||||||
void Start();
|
void Start();
|
||||||
|
@ -539,9 +539,9 @@ void CRecoveredSigsDb::CleanupOldVotes(int64_t maxAge)
|
|||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
|
|
||||||
CSigningManager::CSigningManager(CConnman& _connman, const CQuorumManager& _qman,
|
CSigningManager::CSigningManager(CConnman& _connman, const CActiveMasternodeManager* mn_activeman, const CQuorumManager& _qman,
|
||||||
bool fMemory, bool fWipe) :
|
bool fMemory, bool fWipe) :
|
||||||
db(fMemory, fWipe), connman(_connman), qman(_qman)
|
db(fMemory, fWipe), connman(_connman), m_mn_activeman(mn_activeman), qman(_qman)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -895,9 +895,10 @@ void CSigningManager::UnregisterRecoveredSigsListener(CRecoveredSigsListener* l)
|
|||||||
|
|
||||||
bool CSigningManager::AsyncSignIfMember(Consensus::LLMQType llmqType, CSigSharesManager& shareman, const uint256& id, const uint256& msgHash, const uint256& quorumHash, bool allowReSign)
|
bool CSigningManager::AsyncSignIfMember(Consensus::LLMQType llmqType, CSigSharesManager& shareman, const uint256& id, const uint256& msgHash, const uint256& quorumHash, bool allowReSign)
|
||||||
{
|
{
|
||||||
if (!fMasternodeMode || WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash.IsNull())) {
|
if (!fMasternodeMode) return false;
|
||||||
return false;
|
|
||||||
}
|
assert(m_mn_activeman);
|
||||||
|
if (WITH_LOCK(m_mn_activeman->cs, return m_mn_activeman->GetProTxHash().IsNull())) return false;
|
||||||
|
|
||||||
const CQuorumCPtr quorum = [&]() {
|
const CQuorumCPtr quorum = [&]() {
|
||||||
if (quorumHash.IsNull()) {
|
if (quorumHash.IsNull()) {
|
||||||
@ -919,7 +920,7 @@ bool CSigningManager::AsyncSignIfMember(Consensus::LLMQType llmqType, CSigShares
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!WITH_LOCK(activeMasternodeInfoCs, return quorum->IsValidMember(activeMasternodeInfo.proTxHash))) {
|
if (!WITH_LOCK(m_mn_activeman->cs, return quorum->IsValidMember(m_mn_activeman->GetProTxHash()))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
class CActiveMasternodeManager;
|
||||||
class CConnman;
|
class CConnman;
|
||||||
class CDataStream;
|
class CDataStream;
|
||||||
class CDBBatch;
|
class CDBBatch;
|
||||||
@ -162,6 +163,7 @@ private:
|
|||||||
|
|
||||||
CRecoveredSigsDb db;
|
CRecoveredSigsDb db;
|
||||||
CConnman& connman;
|
CConnman& connman;
|
||||||
|
const CActiveMasternodeManager* m_mn_activeman;
|
||||||
const CQuorumManager& qman;
|
const CQuorumManager& qman;
|
||||||
|
|
||||||
std::atomic<PeerManager*> m_peerman{nullptr};
|
std::atomic<PeerManager*> m_peerman{nullptr};
|
||||||
@ -177,7 +179,7 @@ private:
|
|||||||
std::vector<CRecoveredSigsListener*> recoveredSigsListeners GUARDED_BY(cs);
|
std::vector<CRecoveredSigsListener*> recoveredSigsListeners GUARDED_BY(cs);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CSigningManager(CConnman& _connman, const CQuorumManager& _qman, bool fMemory, bool fWipe);
|
CSigningManager(CConnman& _connman, const CActiveMasternodeManager* mn_activeman, const CQuorumManager& _qman, bool fMemory, bool fWipe);
|
||||||
|
|
||||||
bool AlreadyHave(const CInv& inv) const;
|
bool AlreadyHave(const CInv& inv) const;
|
||||||
bool GetRecoveredSigForGetData(const uint256& hash, CRecoveredSig& ret) const;
|
bool GetRecoveredSigForGetData(const uint256& hash, CRecoveredSig& ret) const;
|
||||||
|
@ -218,9 +218,10 @@ void CSigSharesManager::InterruptWorkerThread()
|
|||||||
void CSigSharesManager::ProcessMessage(const CNode& pfrom, const CSporkManager& sporkman, const std::string& msg_type, CDataStream& vRecv)
|
void CSigSharesManager::ProcessMessage(const CNode& pfrom, const CSporkManager& sporkman, const std::string& msg_type, CDataStream& vRecv)
|
||||||
{
|
{
|
||||||
// non-masternodes are not interested in sigshares
|
// non-masternodes are not interested in sigshares
|
||||||
if (!fMasternodeMode || WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash.IsNull())) {
|
if (!fMasternodeMode) return;
|
||||||
return;
|
|
||||||
}
|
assert(m_mn_activeman);
|
||||||
|
if (WITH_LOCK(m_mn_activeman->cs, return m_mn_activeman->GetProTxHash().IsNull())) return;
|
||||||
|
|
||||||
if (sporkman.IsSporkActive(SPORK_21_QUORUM_ALL_CONNECTED) && msg_type == NetMsgType::QSIGSHARE) {
|
if (sporkman.IsSporkActive(SPORK_21_QUORUM_ALL_CONNECTED) && msg_type == NetMsgType::QSIGSHARE) {
|
||||||
std::vector<CSigShare> receivedSigShares;
|
std::vector<CSigShare> receivedSigShares;
|
||||||
@ -408,7 +409,7 @@ bool CSigSharesManager::ProcessMessageBatchedSigShares(const CNode& pfrom, const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bool ban{false}; !PreVerifyBatchedSigShares(qman, sessionInfo, batchedSigShares, ban)) {
|
if (bool ban{false}; !PreVerifyBatchedSigShares(*Assert(m_mn_activeman), qman, sessionInfo, batchedSigShares, ban)) {
|
||||||
return !ban;
|
return !ban;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,6 +458,8 @@ bool CSigSharesManager::ProcessMessageBatchedSigShares(const CNode& pfrom, const
|
|||||||
|
|
||||||
void CSigSharesManager::ProcessMessageSigShare(NodeId fromId, const CSigShare& sigShare)
|
void CSigSharesManager::ProcessMessageSigShare(NodeId fromId, const CSigShare& sigShare)
|
||||||
{
|
{
|
||||||
|
assert(m_mn_activeman);
|
||||||
|
|
||||||
auto quorum = qman.GetQuorum(sigShare.getLlmqType(), sigShare.getQuorumHash());
|
auto quorum = qman.GetQuorum(sigShare.getLlmqType(), sigShare.getQuorumHash());
|
||||||
if (!quorum) {
|
if (!quorum) {
|
||||||
return;
|
return;
|
||||||
@ -465,7 +468,7 @@ void CSigSharesManager::ProcessMessageSigShare(NodeId fromId, const CSigShare& s
|
|||||||
// quorum is too old
|
// quorum is too old
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!quorum->IsMember(WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash))) {
|
if (!quorum->IsMember(WITH_LOCK(m_mn_activeman->cs, return m_mn_activeman->GetProTxHash()))) {
|
||||||
// we're not a member so we can't verify it (we actually shouldn't have received it)
|
// we're not a member so we can't verify it (we actually shouldn't have received it)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -506,7 +509,8 @@ void CSigSharesManager::ProcessMessageSigShare(NodeId fromId, const CSigShare& s
|
|||||||
sigShare.GetSignHash().ToString(), sigShare.getId().ToString(), sigShare.getMsgHash().ToString(), sigShare.getQuorumMember(), fromId);
|
sigShare.GetSignHash().ToString(), sigShare.getId().ToString(), sigShare.getMsgHash().ToString(), sigShare.getQuorumMember(), fromId);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSigSharesManager::PreVerifyBatchedSigShares(const CQuorumManager& quorum_manager, const CSigSharesNodeState::SessionInfo& session, const CBatchedSigShares& batchedSigShares, bool& retBan)
|
bool CSigSharesManager::PreVerifyBatchedSigShares(const CActiveMasternodeManager& mn_activeman, const CQuorumManager& quorum_manager,
|
||||||
|
const CSigSharesNodeState::SessionInfo& session, const CBatchedSigShares& batchedSigShares, bool& retBan)
|
||||||
{
|
{
|
||||||
retBan = false;
|
retBan = false;
|
||||||
|
|
||||||
@ -514,7 +518,7 @@ bool CSigSharesManager::PreVerifyBatchedSigShares(const CQuorumManager& quorum_m
|
|||||||
// quorum is too old
|
// quorum is too old
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!session.quorum->IsMember(WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash))) {
|
if (!session.quorum->IsMember(WITH_LOCK(mn_activeman.cs, return mn_activeman.GetProTxHash()))) {
|
||||||
// we're not a member so we can't verify it (we actually shouldn't have received it)
|
// we're not a member so we can't verify it (we actually shouldn't have received it)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -692,13 +696,14 @@ void CSigSharesManager::ProcessPendingSigShares(const std::vector<CSigShare>& si
|
|||||||
// sig shares are already verified when entering this method
|
// sig shares are already verified when entering this method
|
||||||
void CSigSharesManager::ProcessSigShare(const CSigShare& sigShare, const CConnman& connman, const CQuorumCPtr& quorum)
|
void CSigSharesManager::ProcessSigShare(const CSigShare& sigShare, const CConnman& connman, const CQuorumCPtr& quorum)
|
||||||
{
|
{
|
||||||
auto llmqType = quorum->params.type;
|
assert(m_mn_activeman);
|
||||||
|
|
||||||
|
auto llmqType = quorum->params.type;
|
||||||
bool canTryRecovery = false;
|
bool canTryRecovery = false;
|
||||||
|
|
||||||
// prepare node set for direct-push in case this is our sig share
|
// prepare node set for direct-push in case this is our sig share
|
||||||
std::set<NodeId> quorumNodes;
|
std::set<NodeId> quorumNodes;
|
||||||
if (!IsAllMembersConnectedEnabled(llmqType, m_sporkman) && sigShare.getQuorumMember() == quorum->GetMemberIndex(WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash))) {
|
if (!IsAllMembersConnectedEnabled(llmqType, m_sporkman) && sigShare.getQuorumMember() == quorum->GetMemberIndex(WITH_LOCK(m_mn_activeman->cs, return m_mn_activeman->GetProTxHash()))) {
|
||||||
quorumNodes = connman.GetMasternodeQuorumNodes(sigShare.getLlmqType(), sigShare.getQuorumHash());
|
quorumNodes = connman.GetMasternodeQuorumNodes(sigShare.getLlmqType(), sigShare.getQuorumHash());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1488,8 +1493,10 @@ void CSigSharesManager::SignPendingSigShares()
|
|||||||
|
|
||||||
std::optional<CSigShare> CSigSharesManager::CreateSigShare(const CQuorumCPtr& quorum, const uint256& id, const uint256& msgHash) const
|
std::optional<CSigShare> CSigSharesManager::CreateSigShare(const CQuorumCPtr& quorum, const uint256& id, const uint256& msgHash) const
|
||||||
{
|
{
|
||||||
|
assert(m_mn_activeman);
|
||||||
|
|
||||||
cxxtimer::Timer t(true);
|
cxxtimer::Timer t(true);
|
||||||
auto activeMasterNodeProTxHash = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash);
|
auto activeMasterNodeProTxHash = WITH_LOCK(m_mn_activeman->cs, return m_mn_activeman->GetProTxHash());
|
||||||
|
|
||||||
if (!quorum->IsValidMember(activeMasterNodeProTxHash)) {
|
if (!quorum->IsValidMember(activeMasterNodeProTxHash)) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
@ -401,6 +401,7 @@ private:
|
|||||||
|
|
||||||
CConnman& connman;
|
CConnman& connman;
|
||||||
CSigningManager& sigman;
|
CSigningManager& sigman;
|
||||||
|
const CActiveMasternodeManager* m_mn_activeman;
|
||||||
const CQuorumManager& qman;
|
const CQuorumManager& qman;
|
||||||
const CSporkManager& m_sporkman;
|
const CSporkManager& m_sporkman;
|
||||||
|
|
||||||
@ -410,8 +411,9 @@ private:
|
|||||||
std::atomic<uint32_t> recoveredSigsCounter{0};
|
std::atomic<uint32_t> recoveredSigsCounter{0};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CSigSharesManager(CConnman& _connman, CSigningManager& _sigman, const CQuorumManager& _qman, const CSporkManager& sporkman, const std::unique_ptr<PeerManager>& peerman) :
|
explicit CSigSharesManager(CConnman& _connman, CSigningManager& _sigman, const CActiveMasternodeManager* mn_activeman,
|
||||||
connman(_connman), sigman(_sigman), qman(_qman), m_sporkman(sporkman), m_peerman(peerman)
|
const CQuorumManager& _qman, const CSporkManager& sporkman, const std::unique_ptr<PeerManager>& peerman) :
|
||||||
|
connman(_connman), sigman(_sigman), m_mn_activeman(mn_activeman), qman(_qman), m_sporkman(sporkman), m_peerman(peerman)
|
||||||
{
|
{
|
||||||
workInterrupt.reset();
|
workInterrupt.reset();
|
||||||
};
|
};
|
||||||
@ -443,7 +445,8 @@ private:
|
|||||||
void ProcessMessageSigShare(NodeId fromId, const CSigShare& sigShare);
|
void ProcessMessageSigShare(NodeId fromId, const CSigShare& sigShare);
|
||||||
|
|
||||||
static bool VerifySigSharesInv(Consensus::LLMQType llmqType, const CSigSharesInv& inv);
|
static bool VerifySigSharesInv(Consensus::LLMQType llmqType, const CSigSharesInv& inv);
|
||||||
static bool PreVerifyBatchedSigShares(const CQuorumManager& quorum_manager, const CSigSharesNodeState::SessionInfo& session, const CBatchedSigShares& batchedSigShares, bool& retBan);
|
static bool PreVerifyBatchedSigShares(const CActiveMasternodeManager& mn_activeman, const CQuorumManager& quorum_manager,
|
||||||
|
const CSigSharesNodeState::SessionInfo& session, const CBatchedSigShares& batchedSigShares, bool& retBan);
|
||||||
|
|
||||||
void CollectPendingSigSharesToVerify(size_t maxUniqueSessions,
|
void CollectPendingSigSharesToVerify(size_t maxUniqueSessions,
|
||||||
std::unordered_map<NodeId, std::vector<CSigShare>>& retSigShares,
|
std::unordered_map<NodeId, std::vector<CSigShare>>& retSigShares,
|
||||||
|
@ -4,24 +4,34 @@
|
|||||||
|
|
||||||
#include <masternode/node.h>
|
#include <masternode/node.h>
|
||||||
|
|
||||||
#include <evo/deterministicmns.h>
|
#include <bls/bls_ies.h>
|
||||||
|
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
#include <deploymentstatus.h>
|
#include <deploymentstatus.h>
|
||||||
|
#include <evo/deterministicmns.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
#include <netbase.h>
|
#include <netbase.h>
|
||||||
#include <protocol.h>
|
#include <protocol.h>
|
||||||
|
#include <util/check.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
#include <warnings.h>
|
#include <warnings.h>
|
||||||
|
|
||||||
// Keep track of the active Masternode
|
// Keep track of the active Masternode
|
||||||
RecursiveMutex activeMasternodeInfoCs;
|
|
||||||
CActiveMasternodeInfo activeMasternodeInfo GUARDED_BY(activeMasternodeInfoCs);
|
|
||||||
std::unique_ptr<CActiveMasternodeManager> activeMasternodeManager;
|
std::unique_ptr<CActiveMasternodeManager> activeMasternodeManager;
|
||||||
|
|
||||||
|
CActiveMasternodeManager::CActiveMasternodeManager(const CBLSSecretKey& sk, CConnman& connman, const std::unique_ptr<CDeterministicMNManager>& dmnman) :
|
||||||
|
m_info(sk, sk.GetPublicKey()),
|
||||||
|
m_connman{connman},
|
||||||
|
m_dmnman{dmnman}
|
||||||
|
{
|
||||||
|
assert(sk.IsValid()); /* We can assume pk is valid if sk is valid */
|
||||||
|
LogPrintf("MASTERNODE:\n blsPubKeyOperator legacy: %s\n blsPubKeyOperator basic: %s\n",
|
||||||
|
m_info.blsPubKeyOperator.ToString(/*specificLegacyScheme=*/ true),
|
||||||
|
m_info.blsPubKeyOperator.ToString(/*specificLegacyScheme=*/ false));
|
||||||
|
}
|
||||||
|
|
||||||
std::string CActiveMasternodeManager::GetStateString() const
|
std::string CActiveMasternodeManager::GetStateString() const
|
||||||
{
|
{
|
||||||
switch (state) {
|
switch (WITH_LOCK(cs, return m_state)) {
|
||||||
case MASTERNODE_WAITING_FOR_PROTX:
|
case MASTERNODE_WAITING_FOR_PROTX:
|
||||||
return "WAITING_FOR_PROTX";
|
return "WAITING_FOR_PROTX";
|
||||||
case MASTERNODE_POSE_BANNED:
|
case MASTERNODE_POSE_BANNED:
|
||||||
@ -43,7 +53,8 @@ std::string CActiveMasternodeManager::GetStateString() const
|
|||||||
|
|
||||||
std::string CActiveMasternodeManager::GetStatus() const
|
std::string CActiveMasternodeManager::GetStatus() const
|
||||||
{
|
{
|
||||||
switch (state) {
|
LOCK(cs);
|
||||||
|
switch (m_state) {
|
||||||
case MASTERNODE_WAITING_FOR_PROTX:
|
case MASTERNODE_WAITING_FOR_PROTX:
|
||||||
return "Waiting for ProTx to appear on-chain";
|
return "Waiting for ProTx to appear on-chain";
|
||||||
case MASTERNODE_POSE_BANNED:
|
case MASTERNODE_POSE_BANNED:
|
||||||
@ -57,7 +68,7 @@ std::string CActiveMasternodeManager::GetStatus() const
|
|||||||
case MASTERNODE_READY:
|
case MASTERNODE_READY:
|
||||||
return "Ready";
|
return "Ready";
|
||||||
case MASTERNODE_ERROR:
|
case MASTERNODE_ERROR:
|
||||||
return "Error. " + strError;
|
return "Error. " + m_error;
|
||||||
default:
|
default:
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
@ -65,7 +76,7 @@ std::string CActiveMasternodeManager::GetStatus() const
|
|||||||
|
|
||||||
void CActiveMasternodeManager::Init(const CBlockIndex* pindex)
|
void CActiveMasternodeManager::Init(const CBlockIndex* pindex)
|
||||||
{
|
{
|
||||||
LOCK2(cs_main, activeMasternodeInfoCs);
|
LOCK(cs);
|
||||||
|
|
||||||
if (!fMasternodeMode) return;
|
if (!fMasternodeMode) return;
|
||||||
|
|
||||||
@ -74,20 +85,20 @@ void CActiveMasternodeManager::Init(const CBlockIndex* pindex)
|
|||||||
// Check that our local network configuration is correct
|
// Check that our local network configuration is correct
|
||||||
if (!fListen && Params().RequireRoutableExternalIP()) {
|
if (!fListen && Params().RequireRoutableExternalIP()) {
|
||||||
// listen option is probably overwritten by something else, no good
|
// listen option is probably overwritten by something else, no good
|
||||||
state = MASTERNODE_ERROR;
|
m_state = MASTERNODE_ERROR;
|
||||||
strError = "Masternode must accept connections from outside. Make sure listen configuration option is not overwritten by some another parameter.";
|
m_error = "Masternode must accept connections from outside. Make sure listen configuration option is not overwritten by some another parameter.";
|
||||||
LogPrintf("CActiveMasternodeManager::Init -- ERROR: %s\n", strError);
|
LogPrintf("CActiveMasternodeManager::Init -- ERROR: %s\n", m_error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GetLocalAddress(activeMasternodeInfo.service)) {
|
if (!GetLocalAddress(m_info.service)) {
|
||||||
state = MASTERNODE_ERROR;
|
m_state = MASTERNODE_ERROR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CDeterministicMNList mnList = Assert(m_dmnman)->GetListForBlock(pindex);
|
CDeterministicMNList mnList = Assert(m_dmnman)->GetListForBlock(pindex);
|
||||||
|
|
||||||
CDeterministicMNCPtr dmn = mnList.GetMNByOperatorKey(*activeMasternodeInfo.blsPubKeyOperator);
|
CDeterministicMNCPtr dmn = mnList.GetMNByOperatorKey(m_info.blsPubKeyOperator);
|
||||||
if (!dmn) {
|
if (!dmn) {
|
||||||
// MN not appeared on the chain yet
|
// MN not appeared on the chain yet
|
||||||
return;
|
return;
|
||||||
@ -95,87 +106,80 @@ void CActiveMasternodeManager::Init(const CBlockIndex* pindex)
|
|||||||
|
|
||||||
if (!mnList.IsMNValid(dmn->proTxHash)) {
|
if (!mnList.IsMNValid(dmn->proTxHash)) {
|
||||||
if (mnList.IsMNPoSeBanned(dmn->proTxHash)) {
|
if (mnList.IsMNPoSeBanned(dmn->proTxHash)) {
|
||||||
state = MASTERNODE_POSE_BANNED;
|
m_state = MASTERNODE_POSE_BANNED;
|
||||||
} else {
|
} else {
|
||||||
state = MASTERNODE_REMOVED;
|
m_state = MASTERNODE_REMOVED;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrintf("CActiveMasternodeManager::Init -- proTxHash=%s, proTx=%s\n", dmn->proTxHash.ToString(), dmn->ToString());
|
LogPrintf("CActiveMasternodeManager::Init -- proTxHash=%s, proTx=%s\n", dmn->proTxHash.ToString(), dmn->ToString());
|
||||||
|
|
||||||
if (activeMasternodeInfo.service != dmn->pdmnState->addr) {
|
if (m_info.service != dmn->pdmnState->addr) {
|
||||||
state = MASTERNODE_ERROR;
|
m_state = MASTERNODE_ERROR;
|
||||||
strError = "Local address does not match the address from ProTx";
|
m_error = "Local address does not match the address from ProTx";
|
||||||
LogPrintf("CActiveMasternodeManager::Init -- ERROR: %s\n", strError);
|
LogPrintf("CActiveMasternodeManager::Init -- ERROR: %s\n", m_error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check socket connectivity
|
// Check socket connectivity
|
||||||
LogPrintf("CActiveMasternodeManager::Init -- Checking inbound connection to '%s'\n", activeMasternodeInfo.service.ToString());
|
LogPrintf("CActiveMasternodeManager::Init -- Checking inbound connection to '%s'\n", m_info.service.ToString());
|
||||||
std::unique_ptr<Sock> sock = CreateSock(activeMasternodeInfo.service);
|
std::unique_ptr<Sock> sock = CreateSock(m_info.service);
|
||||||
if (!sock) {
|
if (!sock) {
|
||||||
state = MASTERNODE_ERROR;
|
m_state = MASTERNODE_ERROR;
|
||||||
strError = "Could not create socket to connect to " + activeMasternodeInfo.service.ToString();
|
m_error = "Could not create socket to connect to " + m_info.service.ToString();
|
||||||
LogPrintf("CActiveMasternodeManager::Init -- ERROR: %s\n", strError);
|
LogPrintf("CActiveMasternodeManager::Init -- ERROR: %s\n", m_error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool fConnected = ConnectSocketDirectly(activeMasternodeInfo.service, *sock, nConnectTimeout, true) && IsSelectableSocket(sock->Get());
|
bool fConnected = ConnectSocketDirectly(m_info.service, *sock, nConnectTimeout, true) && IsSelectableSocket(sock->Get());
|
||||||
sock->Reset();
|
sock->Reset();
|
||||||
|
|
||||||
if (!fConnected && Params().RequireRoutableExternalIP()) {
|
if (!fConnected && Params().RequireRoutableExternalIP()) {
|
||||||
state = MASTERNODE_ERROR;
|
m_state = MASTERNODE_ERROR;
|
||||||
strError = "Could not connect to " + activeMasternodeInfo.service.ToString();
|
m_error = "Could not connect to " + m_info.service.ToString();
|
||||||
LogPrintf("CActiveMasternodeManager::Init -- ERROR: %s\n", strError);
|
LogPrintf("CActiveMasternodeManager::Init -- ERROR: %s\n", m_error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
activeMasternodeInfo.proTxHash = dmn->proTxHash;
|
m_info.proTxHash = dmn->proTxHash;
|
||||||
activeMasternodeInfo.outpoint = dmn->collateralOutpoint;
|
m_info.outpoint = dmn->collateralOutpoint;
|
||||||
activeMasternodeInfo.legacy = dmn->pdmnState->nVersion == CProRegTx::LEGACY_BLS_VERSION;
|
m_info.legacy = dmn->pdmnState->nVersion == CProRegTx::LEGACY_BLS_VERSION;
|
||||||
state = MASTERNODE_READY;
|
m_state = MASTERNODE_READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CActiveMasternodeManager::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload)
|
void CActiveMasternodeManager::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload)
|
||||||
{
|
{
|
||||||
LOCK2(cs_main, activeMasternodeInfoCs);
|
|
||||||
|
|
||||||
if (!fMasternodeMode) return;
|
if (!fMasternodeMode) return;
|
||||||
|
|
||||||
if (!DeploymentDIP0003Enforced(pindexNew->nHeight, Params().GetConsensus())) return;
|
if (!DeploymentDIP0003Enforced(pindexNew->nHeight, Params().GetConsensus())) return;
|
||||||
|
|
||||||
if (state == MASTERNODE_READY) {
|
const auto [cur_state, cur_protx_hash] = WITH_LOCK(cs, return std::make_pair(m_state, m_info.proTxHash));
|
||||||
|
if (cur_state == MASTERNODE_READY) {
|
||||||
auto oldMNList = Assert(m_dmnman)->GetListForBlock(pindexNew->pprev);
|
auto oldMNList = Assert(m_dmnman)->GetListForBlock(pindexNew->pprev);
|
||||||
auto newMNList = m_dmnman->GetListForBlock(pindexNew);
|
auto newMNList = m_dmnman->GetListForBlock(pindexNew);
|
||||||
if (!newMNList.IsMNValid(activeMasternodeInfo.proTxHash)) {
|
auto reset = [this, pindexNew] (masternode_state_t state) -> void {
|
||||||
// MN disappeared from MN list
|
LOCK(cs);
|
||||||
state = MASTERNODE_REMOVED;
|
m_state = state;
|
||||||
activeMasternodeInfo.proTxHash = uint256();
|
m_info.proTxHash = uint256();
|
||||||
activeMasternodeInfo.outpoint.SetNull();
|
m_info.outpoint.SetNull();
|
||||||
// MN might have reappeared in same block with a new ProTx
|
// MN might have reappeared in same block with a new ProTx
|
||||||
Init(pindexNew);
|
Init(pindexNew);
|
||||||
return;
|
};
|
||||||
|
|
||||||
|
if (!newMNList.IsMNValid(cur_protx_hash)) {
|
||||||
|
// MN disappeared from MN list
|
||||||
|
return reset(MASTERNODE_REMOVED);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto oldDmn = oldMNList.GetMN(activeMasternodeInfo.proTxHash);
|
auto oldDmn = oldMNList.GetMN(cur_protx_hash);
|
||||||
auto newDmn = newMNList.GetMN(activeMasternodeInfo.proTxHash);
|
auto newDmn = newMNList.GetMN(cur_protx_hash);
|
||||||
if (newDmn->pdmnState->pubKeyOperator != oldDmn->pdmnState->pubKeyOperator) {
|
if (newDmn->pdmnState->pubKeyOperator != oldDmn->pdmnState->pubKeyOperator) {
|
||||||
// MN operator key changed or revoked
|
// MN operator key changed or revoked
|
||||||
state = MASTERNODE_OPERATOR_KEY_CHANGED;
|
return reset(MASTERNODE_OPERATOR_KEY_CHANGED);
|
||||||
activeMasternodeInfo.proTxHash = uint256();
|
|
||||||
activeMasternodeInfo.outpoint.SetNull();
|
|
||||||
// MN might have reappeared in same block with a new ProTx
|
|
||||||
Init(pindexNew);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newDmn->pdmnState->addr != oldDmn->pdmnState->addr) {
|
if (newDmn->pdmnState->addr != oldDmn->pdmnState->addr) {
|
||||||
// MN IP changed
|
// MN IP changed
|
||||||
state = MASTERNODE_PROTX_IP_CHANGED;
|
return reset(MASTERNODE_PROTX_IP_CHANGED);
|
||||||
activeMasternodeInfo.proTxHash = uint256();
|
|
||||||
activeMasternodeInfo.outpoint.SetNull();
|
|
||||||
Init(pindexNew);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// MN might have (re)appeared with a new ProTx or we've found some peers
|
// MN might have (re)appeared with a new ProTx or we've found some peers
|
||||||
@ -203,8 +207,8 @@ bool CActiveMasternodeManager::GetLocalAddress(CService& addrRet)
|
|||||||
if (!fFoundLocal) {
|
if (!fFoundLocal) {
|
||||||
bool empty = true;
|
bool empty = true;
|
||||||
// If we have some peers, let's try to find our local address from one of them
|
// If we have some peers, let's try to find our local address from one of them
|
||||||
auto service = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.service);
|
auto service = WITH_LOCK(cs, return m_info.service);
|
||||||
connman.ForEachNodeContinueIf(CConnman::AllNodes, [&](CNode* pnode) {
|
m_connman.ForEachNodeContinueIf(CConnman::AllNodes, [&](CNode* pnode) {
|
||||||
empty = false;
|
empty = false;
|
||||||
if (pnode->addr.IsIPv4())
|
if (pnode->addr.IsIPv4())
|
||||||
fFoundLocal = GetLocal(service, &pnode->addr) && IsValidNetAddr(service);
|
fFoundLocal = GetLocal(service, &pnode->addr) && IsValidNetAddr(service);
|
||||||
@ -212,8 +216,9 @@ bool CActiveMasternodeManager::GetLocalAddress(CService& addrRet)
|
|||||||
});
|
});
|
||||||
// nothing and no live connections, can't do anything for now
|
// nothing and no live connections, can't do anything for now
|
||||||
if (empty) {
|
if (empty) {
|
||||||
strError = "Can't detect valid external address. Please consider using the externalip configuration option if problem persists. Make sure to use IPv4 address only.";
|
LOCK(cs);
|
||||||
LogPrintf("CActiveMasternodeManager::GetLocalAddress -- ERROR: %s\n", strError);
|
m_error = "Can't detect valid external address. Please consider using the externalip configuration option if problem persists. Make sure to use IPv4 address only.";
|
||||||
|
LogPrintf("CActiveMasternodeManager::GetLocalAddress -- ERROR: %s\n", m_error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,3 +232,34 @@ bool CActiveMasternodeManager::IsValidNetAddr(const CService& addrIn)
|
|||||||
return !Params().RequireRoutableExternalIP() ||
|
return !Params().RequireRoutableExternalIP() ||
|
||||||
(addrIn.IsIPv4() && IsReachable(addrIn) && addrIn.IsRoutable());
|
(addrIn.IsIPv4() && IsReachable(addrIn) && addrIn.IsRoutable());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <template <typename> class EncryptedObj, typename Obj>
|
||||||
|
[[nodiscard]] bool CActiveMasternodeManager::Decrypt(const EncryptedObj<Obj>& obj, size_t idx, Obj& ret_obj,
|
||||||
|
int version) const
|
||||||
|
{
|
||||||
|
AssertLockNotHeld(cs);
|
||||||
|
return WITH_LOCK(cs, return obj.Decrypt(idx, m_info.blsKeyOperator, ret_obj, version));
|
||||||
|
}
|
||||||
|
template bool CActiveMasternodeManager::Decrypt(const CBLSIESEncryptedObject<CBLSSecretKey>& obj, size_t idx,
|
||||||
|
CBLSSecretKey& ret_obj, int version) const;
|
||||||
|
template bool CActiveMasternodeManager::Decrypt(const CBLSIESMultiRecipientObjects<CBLSSecretKey>& obj, size_t idx,
|
||||||
|
CBLSSecretKey& ret_obj, int version) const;
|
||||||
|
|
||||||
|
[[nodiscard]] CBLSSignature CActiveMasternodeManager::Sign(const uint256& hash) const
|
||||||
|
{
|
||||||
|
AssertLockNotHeld(cs);
|
||||||
|
return WITH_LOCK(cs, return m_info.blsKeyOperator.Sign(hash));
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] CBLSSignature CActiveMasternodeManager::Sign(const uint256& hash, const bool is_legacy) const
|
||||||
|
{
|
||||||
|
AssertLockNotHeld(cs);
|
||||||
|
return WITH_LOCK(cs, return m_info.blsKeyOperator.Sign(hash, is_legacy));
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to pass a copy as opposed to a const ref because CBLSPublicKeyVersionWrapper
|
||||||
|
// does not accept a const ref in its construction args
|
||||||
|
[[nodiscard]] CBLSPublicKey CActiveMasternodeManager::GetPubKey() const
|
||||||
|
{
|
||||||
|
return m_info.blsPubKeyOperator;
|
||||||
|
}
|
||||||
|
@ -5,33 +5,28 @@
|
|||||||
#ifndef BITCOIN_MASTERNODE_NODE_H
|
#ifndef BITCOIN_MASTERNODE_NODE_H
|
||||||
#define BITCOIN_MASTERNODE_NODE_H
|
#define BITCOIN_MASTERNODE_NODE_H
|
||||||
|
|
||||||
|
#include <bls/bls.h>
|
||||||
#include <netaddress.h>
|
#include <netaddress.h>
|
||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
|
#include <threadsafety.h>
|
||||||
#include <validationinterface.h>
|
#include <validationinterface.h>
|
||||||
|
|
||||||
class CActiveMasternodeManager;
|
|
||||||
class CBLSPublicKey;
|
|
||||||
class CBLSSecretKey;
|
|
||||||
class CDeterministicMNManager;
|
class CDeterministicMNManager;
|
||||||
|
|
||||||
struct CActiveMasternodeInfo;
|
|
||||||
|
|
||||||
extern CActiveMasternodeInfo activeMasternodeInfo;
|
|
||||||
extern RecursiveMutex activeMasternodeInfoCs;
|
|
||||||
extern std::unique_ptr<CActiveMasternodeManager> activeMasternodeManager;
|
|
||||||
|
|
||||||
struct CActiveMasternodeInfo {
|
struct CActiveMasternodeInfo {
|
||||||
// Keys for the active Masternode
|
// Keys for the active Masternode
|
||||||
std::unique_ptr<CBLSPublicKey> blsPubKeyOperator;
|
const CBLSSecretKey blsKeyOperator;
|
||||||
std::unique_ptr<CBLSSecretKey> blsKeyOperator;
|
const CBLSPublicKey blsPubKeyOperator;
|
||||||
|
|
||||||
// Initialized while registering Masternode
|
// Initialized while registering Masternode
|
||||||
uint256 proTxHash;
|
uint256 proTxHash;
|
||||||
COutPoint outpoint;
|
COutPoint outpoint;
|
||||||
CService service;
|
CService service;
|
||||||
bool legacy{true};
|
bool legacy{true};
|
||||||
};
|
|
||||||
|
|
||||||
|
CActiveMasternodeInfo(const CBLSSecretKey& blsKeyOperator, const CBLSPublicKey& blsPubKeyOperator) :
|
||||||
|
blsKeyOperator(blsKeyOperator), blsPubKeyOperator(blsPubKeyOperator) {};
|
||||||
|
};
|
||||||
|
|
||||||
class CActiveMasternodeManager final : public CValidationInterface
|
class CActiveMasternodeManager final : public CValidationInterface
|
||||||
{
|
{
|
||||||
@ -46,16 +41,18 @@ public:
|
|||||||
MASTERNODE_ERROR,
|
MASTERNODE_ERROR,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mutable RecursiveMutex cs;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
masternode_state_t state{MASTERNODE_WAITING_FOR_PROTX};
|
masternode_state_t m_state GUARDED_BY(cs) {MASTERNODE_WAITING_FOR_PROTX};
|
||||||
std::string strError;
|
CActiveMasternodeInfo m_info GUARDED_BY(cs);
|
||||||
CConnman& connman;
|
std::string m_error GUARDED_BY(cs);
|
||||||
|
|
||||||
|
CConnman& m_connman;
|
||||||
const std::unique_ptr<CDeterministicMNManager>& m_dmnman;
|
const std::unique_ptr<CDeterministicMNManager>& m_dmnman;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CActiveMasternodeManager(CConnman& _connman, const std::unique_ptr<CDeterministicMNManager>& dmnman) :
|
explicit CActiveMasternodeManager(const CBLSSecretKey& sk, CConnman& connman, const std::unique_ptr<CDeterministicMNManager>& dmnman);
|
||||||
connman(_connman), m_dmnman(dmnman) {};
|
|
||||||
~CActiveMasternodeManager() = default;
|
|
||||||
|
|
||||||
void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload) override;
|
void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload) override;
|
||||||
|
|
||||||
@ -66,8 +63,23 @@ public:
|
|||||||
|
|
||||||
static bool IsValidNetAddr(const CService& addrIn);
|
static bool IsValidNetAddr(const CService& addrIn);
|
||||||
|
|
||||||
|
template <template <typename> class EncryptedObj, typename Obj>
|
||||||
|
[[nodiscard]] bool Decrypt(const EncryptedObj<Obj>& obj, size_t idx, Obj& ret_obj, int version) const
|
||||||
|
LOCKS_EXCLUDED(cs);
|
||||||
|
[[nodiscard]] CBLSSignature Sign(const uint256& hash) const LOCKS_EXCLUDED(cs);
|
||||||
|
[[nodiscard]] CBLSSignature Sign(const uint256& hash, const bool is_legacy) const LOCKS_EXCLUDED(cs);
|
||||||
|
|
||||||
|
/* TODO: Reconsider external locking */
|
||||||
|
[[nodiscard]] const COutPoint& GetOutPoint() const EXCLUSIVE_LOCKS_REQUIRED(cs) { return m_info.outpoint; }
|
||||||
|
[[nodiscard]] const uint256& GetProTxHash() const EXCLUSIVE_LOCKS_REQUIRED(cs) { return m_info.proTxHash; }
|
||||||
|
[[nodiscard]] const CService& GetService() const EXCLUSIVE_LOCKS_REQUIRED(cs) { return m_info.service; }
|
||||||
|
[[nodiscard]] CBLSPublicKey GetPubKey() const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||||
|
[[nodiscard]] bool IsLegacy() const EXCLUSIVE_LOCKS_REQUIRED(cs) { return m_info.legacy; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool GetLocalAddress(CService& addrRet);
|
bool GetLocalAddress(CService& addrRet);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern std::unique_ptr<CActiveMasternodeManager> activeMasternodeManager;
|
||||||
|
|
||||||
#endif // BITCOIN_MASTERNODE_NODE_H
|
#endif // BITCOIN_MASTERNODE_NODE_H
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
class ArgsManager;
|
class ArgsManager;
|
||||||
class BanMan;
|
class BanMan;
|
||||||
|
class CActiveMasternodeManager;
|
||||||
class CAddrMan;
|
class CAddrMan;
|
||||||
class CBlockPolicyEstimator;
|
class CBlockPolicyEstimator;
|
||||||
class CConnman;
|
class CConnman;
|
||||||
@ -79,6 +80,7 @@ struct NodeContext {
|
|||||||
std::unique_ptr<CNetFulfilledRequestManager> netfulfilledman;
|
std::unique_ptr<CNetFulfilledRequestManager> netfulfilledman;
|
||||||
std::unique_ptr<CSporkManager> sporkman;
|
std::unique_ptr<CSporkManager> sporkman;
|
||||||
std::unique_ptr<LLMQContext> llmq_ctx;
|
std::unique_ptr<LLMQContext> llmq_ctx;
|
||||||
|
CActiveMasternodeManager* mn_activeman{nullptr};
|
||||||
CDeterministicMNManager* dmnman{nullptr};
|
CDeterministicMNManager* dmnman{nullptr};
|
||||||
CMasternodeMetaMan* mn_metaman{nullptr};
|
CMasternodeMetaMan* mn_metaman{nullptr};
|
||||||
CMasternodeSync* mn_sync{nullptr};
|
CMasternodeSync* mn_sync{nullptr};
|
||||||
|
@ -38,8 +38,9 @@ static RPCHelpMan coinjoin()
|
|||||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
|
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
|
||||||
if (!wallet) return NullUniValue;
|
if (!wallet) return NullUniValue;
|
||||||
|
|
||||||
if (fMasternodeMode)
|
if (fMasternodeMode) {
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Client-side mixing is not supported on masternodes");
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "Client-side mixing is not supported on masternodes");
|
||||||
|
}
|
||||||
|
|
||||||
if (!CCoinJoinClientOptions::IsEnabled()) {
|
if (!CCoinJoinClientOptions::IsEnabled()) {
|
||||||
if (!gArgs.GetBoolArg("-enablecoinjoin", true)) {
|
if (!gArgs.GetBoolArg("-enablecoinjoin", true)) {
|
||||||
|
@ -315,11 +315,23 @@ static UniValue gobject_submit(const JSONRPCRequest& request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto mnList = node.dmnman->GetListAtChainTip();
|
auto mnList = node.dmnman->GetListAtChainTip();
|
||||||
bool fMnFound = WITH_LOCK(activeMasternodeInfoCs, return mnList.HasValidMNByCollateral(activeMasternodeInfo.outpoint));
|
|
||||||
|
|
||||||
LogPrint(BCLog::GOBJECT, "gobject_submit -- pubKeyOperator = %s, outpoint = %s, params.size() = %lld, fMnFound = %d\n",
|
if (fMasternodeMode) {
|
||||||
(WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.blsPubKeyOperator ? activeMasternodeInfo.blsPubKeyOperator->ToString(activeMasternodeInfo.legacy) : "N/A")),
|
CHECK_NONFATAL(node.mn_activeman);
|
||||||
WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.outpoint.ToStringShort()), request.params.size(), fMnFound);
|
|
||||||
|
LOCK(node.mn_activeman->cs);
|
||||||
|
const bool fMnFound = mnList.HasValidMNByCollateral(node.mn_activeman->GetOutPoint());
|
||||||
|
|
||||||
|
LogPrint(BCLog::GOBJECT, "gobject_submit -- pubKeyOperator = %s, outpoint = %s, params.size() = %lld, fMnFound = %d\n",
|
||||||
|
node.mn_activeman->GetPubKey().ToString(node.mn_activeman->IsLegacy()),
|
||||||
|
node.mn_activeman->GetOutPoint().ToStringShort(),
|
||||||
|
request.params.size(),
|
||||||
|
fMnFound);
|
||||||
|
} else {
|
||||||
|
LogPrint(BCLog::GOBJECT, "gobject_submit -- pubKeyOperator = N/A, outpoint = N/A, params.size() = %lld, fMnFound = %d\n",
|
||||||
|
request.params.size(),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
// ASSEMBLE NEW GOVERNANCE OBJECT FROM USER PARAMETERS
|
// ASSEMBLE NEW GOVERNANCE OBJECT FROM USER PARAMETERS
|
||||||
|
|
||||||
|
@ -257,20 +257,22 @@ static UniValue masternode_status(const JSONRPCRequest& request)
|
|||||||
{
|
{
|
||||||
masternode_status_help(request);
|
masternode_status_help(request);
|
||||||
|
|
||||||
if (!fMasternodeMode)
|
if (!fMasternodeMode) {
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "This is not a masternode");
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "This node does not run an active masternode.");
|
||||||
|
}
|
||||||
|
|
||||||
const NodeContext& node = EnsureAnyNodeContext(request.context);
|
const NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
|
CHECK_NONFATAL(node.mn_activeman);
|
||||||
|
|
||||||
UniValue mnObj(UniValue::VOBJ);
|
UniValue mnObj(UniValue::VOBJ);
|
||||||
CDeterministicMNCPtr dmn;
|
CDeterministicMNCPtr dmn;
|
||||||
{
|
{
|
||||||
LOCK(activeMasternodeInfoCs);
|
LOCK(node.mn_activeman->cs);
|
||||||
|
|
||||||
// keep compatibility with legacy status for now (might get deprecated/removed later)
|
// keep compatibility with legacy status for now (might get deprecated/removed later)
|
||||||
mnObj.pushKV("outpoint", activeMasternodeInfo.outpoint.ToStringShort());
|
mnObj.pushKV("outpoint", node.mn_activeman->GetOutPoint().ToStringShort());
|
||||||
mnObj.pushKV("service", activeMasternodeInfo.service.ToString());
|
mnObj.pushKV("service", node.mn_activeman->GetService().ToString());
|
||||||
dmn = node.dmnman->GetListAtChainTip().GetMN(activeMasternodeInfo.proTxHash);
|
dmn = node.dmnman->GetListAtChainTip().GetMN(node.mn_activeman->GetProTxHash());
|
||||||
}
|
}
|
||||||
if (dmn) {
|
if (dmn) {
|
||||||
mnObj.pushKV("proTxHash", dmn->proTxHash.ToString());
|
mnObj.pushKV("proTxHash", dmn->proTxHash.ToString());
|
||||||
@ -279,8 +281,8 @@ static UniValue masternode_status(const JSONRPCRequest& request)
|
|||||||
mnObj.pushKV("collateralIndex", (int)dmn->collateralOutpoint.n);
|
mnObj.pushKV("collateralIndex", (int)dmn->collateralOutpoint.n);
|
||||||
mnObj.pushKV("dmnState", dmn->pdmnState->ToJson(dmn->nType));
|
mnObj.pushKV("dmnState", dmn->pdmnState->ToJson(dmn->nType));
|
||||||
}
|
}
|
||||||
mnObj.pushKV("state", activeMasternodeManager->GetStateString());
|
mnObj.pushKV("state", node.mn_activeman->GetStateString());
|
||||||
mnObj.pushKV("status", activeMasternodeManager->GetStatus());
|
mnObj.pushKV("status", node.mn_activeman->GetStatus());
|
||||||
|
|
||||||
return mnObj;
|
return mnObj;
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,8 @@ static void quorum_dkgstatus_help(const JSONRPCRequest& request)
|
|||||||
}.Check(request);
|
}.Check(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
static UniValue quorum_dkgstatus(const JSONRPCRequest& request, CDeterministicMNManager& dmnman, const ChainstateManager& chainman, const CSporkManager& sporkman, const LLMQContext& llmq_ctx)
|
static UniValue quorum_dkgstatus(const JSONRPCRequest& request, CDeterministicMNManager& dmnman, const CActiveMasternodeManager* mn_activeman,
|
||||||
|
const ChainstateManager& chainman, const CSporkManager& sporkman, const LLMQContext& llmq_ctx)
|
||||||
{
|
{
|
||||||
quorum_dkgstatus_help(request);
|
quorum_dkgstatus_help(request);
|
||||||
|
|
||||||
@ -295,7 +296,11 @@ static UniValue quorum_dkgstatus(const JSONRPCRequest& request, CDeterministicMN
|
|||||||
CBlockIndex* pindexTip = WITH_LOCK(cs_main, return chainman.ActiveChain().Tip());
|
CBlockIndex* pindexTip = WITH_LOCK(cs_main, return chainman.ActiveChain().Tip());
|
||||||
int tipHeight = pindexTip->nHeight;
|
int tipHeight = pindexTip->nHeight;
|
||||||
|
|
||||||
auto proTxHash = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash);
|
const uint256 proTxHash = [&mn_activeman]() {
|
||||||
|
if (!fMasternodeMode) return uint256();
|
||||||
|
CHECK_NONFATAL(mn_activeman);
|
||||||
|
return WITH_LOCK(mn_activeman->cs, return mn_activeman->GetProTxHash());
|
||||||
|
}();
|
||||||
|
|
||||||
UniValue minableCommitments(UniValue::VARR);
|
UniValue minableCommitments(UniValue::VARR);
|
||||||
UniValue quorumArrConnections(UniValue::VARR);
|
UniValue quorumArrConnections(UniValue::VARR);
|
||||||
@ -879,7 +884,7 @@ static UniValue _quorum(const JSONRPCRequest& request)
|
|||||||
} else if (command == "quorumdkginfo") {
|
} else if (command == "quorumdkginfo") {
|
||||||
return quorum_dkginfo(new_request, llmq_ctx, chainman);
|
return quorum_dkginfo(new_request, llmq_ctx, chainman);
|
||||||
} else if (command == "quorumdkgstatus") {
|
} else if (command == "quorumdkgstatus") {
|
||||||
return quorum_dkgstatus(new_request, *node.dmnman, chainman, *node.sporkman, llmq_ctx);
|
return quorum_dkgstatus(new_request, *node.dmnman, node.mn_activeman, chainman, *node.sporkman, llmq_ctx);
|
||||||
} else if (command == "quorummemberof") {
|
} else if (command == "quorummemberof") {
|
||||||
return quorum_memberof(new_request, chainman, node, llmq_ctx);
|
return quorum_memberof(new_request, chainman, node, llmq_ctx);
|
||||||
} else if (command == "quorumsign" || command == "quorumverify" || command == "quorumhasrecsig" || command == "quorumgetrecsig" || command == "quorumisconflicting") {
|
} else if (command == "quorumsign" || command == "quorumverify" || command == "quorumhasrecsig" || command == "quorumgetrecsig" || command == "quorumisconflicting") {
|
||||||
|
@ -111,11 +111,12 @@ void DashTestSetup(NodeContext& node, const CChainParams& chainparams)
|
|||||||
|
|
||||||
::deterministicMNManager = std::make_unique<CDeterministicMNManager>(chainstate, *node.connman, *node.evodb);
|
::deterministicMNManager = std::make_unique<CDeterministicMNManager>(chainstate, *node.connman, *node.evodb);
|
||||||
node.dmnman = ::deterministicMNManager.get();
|
node.dmnman = ::deterministicMNManager.get();
|
||||||
node.cj_ctx = std::make_unique<CJContext>(chainstate, *node.connman, *node.dmnman, *node.mempool, *node.mn_sync, /* relay_txes */ true);
|
node.cj_ctx = std::make_unique<CJContext>(chainstate, *node.connman, *node.dmnman, *node.mempool, /* mn_activeman = */ nullptr, *node.mn_sync, /* relay_txes = */ true);
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
node.coinjoin_loader = interfaces::MakeCoinJoinLoader(*node.cj_ctx->walletman);
|
node.coinjoin_loader = interfaces::MakeCoinJoinLoader(*node.cj_ctx->walletman);
|
||||||
#endif // ENABLE_WALLET
|
#endif // ENABLE_WALLET
|
||||||
node.llmq_ctx = std::make_unique<LLMQContext>(chainstate, *node.connman, *node.dmnman, *node.evodb, *node.mnhf_manager, *node.sporkman, *node.mempool, node.peerman, true, false);
|
node.llmq_ctx = std::make_unique<LLMQContext>(chainstate, *node.connman, *node.dmnman, *node.evodb, *node.mnhf_manager, *node.sporkman, *node.mempool,
|
||||||
|
/* mn_activeman = */ nullptr, node.peerman, /* unit_tests = */ true, /* wipe = */ false);
|
||||||
node.chain_helper = std::make_unique<CChainstateHelper>(*node.cpoolman, *node.dmnman, *node.mnhf_manager, *node.govman, *(node.llmq_ctx->quorum_block_processor),
|
node.chain_helper = std::make_unique<CChainstateHelper>(*node.cpoolman, *node.dmnman, *node.mnhf_manager, *node.govman, *(node.llmq_ctx->quorum_block_processor),
|
||||||
chainparams.GetConsensus(), *node.mn_sync, *node.sporkman, *(node.llmq_ctx->clhandler));
|
chainparams.GetConsensus(), *node.mn_sync, *node.sporkman, *(node.llmq_ctx->clhandler));
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ EXPECTED_CIRCULAR_DEPENDENCIES=(
|
|||||||
"spork -> validation -> spork"
|
"spork -> validation -> spork"
|
||||||
"governance/governance -> validation -> governance/governance"
|
"governance/governance -> validation -> governance/governance"
|
||||||
"evo/deterministicmns -> validationinterface -> governance/vote -> evo/deterministicmns"
|
"evo/deterministicmns -> validationinterface -> governance/vote -> evo/deterministicmns"
|
||||||
"governance/vote -> validation -> validationinterface -> governance/vote"
|
"governance/vote -> masternode/node -> validationinterface -> governance/vote"
|
||||||
"llmq/signing -> masternode/node -> validationinterface -> llmq/signing"
|
"llmq/signing -> masternode/node -> validationinterface -> llmq/signing"
|
||||||
"evo/mnhftx -> validation -> evo/mnhftx"
|
"evo/mnhftx -> validation -> evo/mnhftx"
|
||||||
"evo/deterministicmns -> validation -> evo/deterministicmns"
|
"evo/deterministicmns -> validation -> evo/deterministicmns"
|
||||||
|
Loading…
Reference in New Issue
Block a user