mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 12:02:48 +01:00
Move ChainLock signing into TrySignChainTip and call it periodically
Later commits will introduce checks for "safe TXs" which might abort the signing on first try, but succeed a few seconds later, so we periodically retry to sign the tip.
This commit is contained in:
parent
bd7edc8ae9
commit
0a5e8eb862
@ -35,12 +35,16 @@ CChainLocksHandler::~CChainLocksHandler()
|
||||
{
|
||||
}
|
||||
|
||||
void CChainLocksHandler::RegisterAsRecoveredSigsListener()
|
||||
void CChainLocksHandler::Start()
|
||||
{
|
||||
quorumSigningManager->RegisterRecoveredSigsListener(this);
|
||||
scheduler->scheduleEvery([&]() {
|
||||
// regularely retry signing the current chaintip as it might have failed before due to missing ixlocks
|
||||
TrySignChainTip();
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
void CChainLocksHandler::UnregisterAsRecoveredSigsListener()
|
||||
void CChainLocksHandler::Stop()
|
||||
{
|
||||
quorumSigningManager->UnregisterRecoveredSigsListener(this);
|
||||
}
|
||||
@ -184,30 +188,52 @@ void CChainLocksHandler::AcceptedBlockHeader(const CBlockIndex* pindexNew)
|
||||
|
||||
void CChainLocksHandler::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork)
|
||||
{
|
||||
// don't call TrySignChainTip directly but instead let the scheduler call it. This way we ensure that cs_main is
|
||||
// never locked and TrySignChainTip is not called twice in parallel
|
||||
LOCK(cs);
|
||||
if (tryLockChainTipScheduled) {
|
||||
return;
|
||||
}
|
||||
tryLockChainTipScheduled = true;
|
||||
scheduler->scheduleFromNow([&]() {
|
||||
TrySignChainTip();
|
||||
LOCK(cs);
|
||||
tryLockChainTipScheduled = false;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
void CChainLocksHandler::TrySignChainTip()
|
||||
{
|
||||
Cleanup();
|
||||
|
||||
const CBlockIndex* pindex;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
pindex = chainActive.Tip();
|
||||
}
|
||||
|
||||
if (!fMasternodeMode) {
|
||||
return;
|
||||
}
|
||||
if (!pindexNew->pprev) {
|
||||
if (!pindex->pprev) {
|
||||
return;
|
||||
}
|
||||
if (!sporkManager.IsSporkActive(SPORK_19_CHAINLOCKS_ENABLED)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Cleanup();
|
||||
|
||||
// DIP8 defines a process called "Signing attempts" which should run before the CLSIG is finalized
|
||||
// To simplify the initial implementation, we skip this process and directly try to create a CLSIG
|
||||
// This will fail when multiple blocks compete, but we accept this for the initial implementation.
|
||||
// Later, we'll add the multiple attempts process.
|
||||
|
||||
uint256 requestId = ::SerializeHash(std::make_pair(CLSIG_REQUESTID_PREFIX, pindexNew->nHeight));
|
||||
uint256 msgHash = pindexNew->GetBlockHash();
|
||||
uint256 requestId = ::SerializeHash(std::make_pair(CLSIG_REQUESTID_PREFIX, pindex->nHeight));
|
||||
uint256 msgHash = pindex->GetBlockHash();
|
||||
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
if (bestChainLockBlockIndex == pindexNew) {
|
||||
if (bestChainLockBlockIndex == pindex) {
|
||||
// we first got the CLSIG, then the header, and then the block was connected.
|
||||
// In this case there is no need to continue here.
|
||||
// However, NotifyChainLock might not have been called yet, so call it now if needed
|
||||
@ -218,26 +244,26 @@ void CChainLocksHandler::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBl
|
||||
return;
|
||||
}
|
||||
|
||||
if (InternalHasConflictingChainLock(pindexNew->nHeight, pindexNew->GetBlockHash())) {
|
||||
if (InternalHasConflictingChainLock(pindex->nHeight, pindex->GetBlockHash())) {
|
||||
if (!inEnforceBestChainLock) {
|
||||
// we accepted this block when there was no lock yet, but now a conflicting lock appeared. Invalidate it.
|
||||
LogPrintf("CChainLocksHandler::%s -- conflicting lock after block was accepted, invalidating now\n",
|
||||
__func__);
|
||||
ScheduleInvalidateBlock(pindexNew);
|
||||
ScheduleInvalidateBlock(pindex);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (bestChainLock.nHeight >= pindexNew->nHeight) {
|
||||
if (bestChainLock.nHeight >= pindex->nHeight) {
|
||||
// already got the same CLSIG or a better one
|
||||
return;
|
||||
}
|
||||
|
||||
if (pindexNew->nHeight == lastSignedHeight) {
|
||||
if (pindex->nHeight == lastSignedHeight) {
|
||||
// already signed this one
|
||||
return;
|
||||
}
|
||||
lastSignedHeight = pindexNew->nHeight;
|
||||
lastSignedHeight = pindex->nHeight;
|
||||
lastSignedRequestId = requestId;
|
||||
lastSignedMsgHash = msgHash;
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ class CChainLocksHandler : public CRecoveredSigsListener
|
||||
private:
|
||||
CScheduler* scheduler;
|
||||
CCriticalSection cs;
|
||||
bool tryLockChainTipScheduled{false};
|
||||
std::atomic<bool> inEnforceBestChainLock{false};
|
||||
|
||||
uint256 bestChainLockHash;
|
||||
@ -74,8 +75,8 @@ public:
|
||||
CChainLocksHandler(CScheduler* _scheduler);
|
||||
~CChainLocksHandler();
|
||||
|
||||
void RegisterAsRecoveredSigsListener();
|
||||
void UnregisterAsRecoveredSigsListener();
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
bool AlreadyHave(const CInv& inv);
|
||||
bool GetChainLockByHash(const uint256& hash, CChainLockSig& ret);
|
||||
@ -86,6 +87,7 @@ public:
|
||||
void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork);
|
||||
void NewPoWValidBlock(const CBlockIndex* pindex, const std::shared_ptr<const CBlock>& block);
|
||||
void SyncTransaction(const CTransaction &tx, const CBlockIndex *pindex, int posInBlock);
|
||||
void TrySignChainTip();
|
||||
void EnforceBestChainLock();
|
||||
virtual void HandleNewRecoveredSig(const CRecoveredSig& recoveredSig);
|
||||
|
||||
|
@ -66,7 +66,7 @@ void StartLLMQSystem()
|
||||
quorumSigSharesManager->StartWorkerThread();
|
||||
}
|
||||
if (chainLocksHandler) {
|
||||
chainLocksHandler->RegisterAsRecoveredSigsListener();
|
||||
chainLocksHandler->Start();
|
||||
}
|
||||
if (quorumInstantSendManager) {
|
||||
quorumInstantSendManager->RegisterAsRecoveredSigsListener();
|
||||
@ -79,7 +79,7 @@ void StopLLMQSystem()
|
||||
quorumInstantSendManager->UnregisterAsRecoveredSigsListener();
|
||||
}
|
||||
if (chainLocksHandler) {
|
||||
chainLocksHandler->UnregisterAsRecoveredSigsListener();
|
||||
chainLocksHandler->Stop();
|
||||
}
|
||||
if (quorumSigSharesManager) {
|
||||
quorumSigSharesManager->StopWorkerThread();
|
||||
|
Loading…
Reference in New Issue
Block a user