mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 20:12:57 +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);
|
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);
|
quorumSigningManager->UnregisterRecoveredSigsListener(this);
|
||||||
}
|
}
|
||||||
@ -184,30 +188,52 @@ void CChainLocksHandler::AcceptedBlockHeader(const CBlockIndex* pindexNew)
|
|||||||
|
|
||||||
void CChainLocksHandler::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork)
|
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) {
|
if (!fMasternodeMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!pindexNew->pprev) {
|
if (!pindex->pprev) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!sporkManager.IsSporkActive(SPORK_19_CHAINLOCKS_ENABLED)) {
|
if (!sporkManager.IsSporkActive(SPORK_19_CHAINLOCKS_ENABLED)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cleanup();
|
|
||||||
|
|
||||||
// DIP8 defines a process called "Signing attempts" which should run before the CLSIG is finalized
|
// 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
|
// 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.
|
// This will fail when multiple blocks compete, but we accept this for the initial implementation.
|
||||||
// Later, we'll add the multiple attempts process.
|
// Later, we'll add the multiple attempts process.
|
||||||
|
|
||||||
uint256 requestId = ::SerializeHash(std::make_pair(CLSIG_REQUESTID_PREFIX, pindexNew->nHeight));
|
uint256 requestId = ::SerializeHash(std::make_pair(CLSIG_REQUESTID_PREFIX, pindex->nHeight));
|
||||||
uint256 msgHash = pindexNew->GetBlockHash();
|
uint256 msgHash = pindex->GetBlockHash();
|
||||||
|
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
|
|
||||||
if (bestChainLockBlockIndex == pindexNew) {
|
if (bestChainLockBlockIndex == pindex) {
|
||||||
// we first got the CLSIG, then the header, and then the block was connected.
|
// we first got the CLSIG, then the header, and then the block was connected.
|
||||||
// In this case there is no need to continue here.
|
// In this case there is no need to continue here.
|
||||||
// However, NotifyChainLock might not have been called yet, so call it now if needed
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InternalHasConflictingChainLock(pindexNew->nHeight, pindexNew->GetBlockHash())) {
|
if (InternalHasConflictingChainLock(pindex->nHeight, pindex->GetBlockHash())) {
|
||||||
if (!inEnforceBestChainLock) {
|
if (!inEnforceBestChainLock) {
|
||||||
// we accepted this block when there was no lock yet, but now a conflicting lock appeared. Invalidate it.
|
// 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",
|
LogPrintf("CChainLocksHandler::%s -- conflicting lock after block was accepted, invalidating now\n",
|
||||||
__func__);
|
__func__);
|
||||||
ScheduleInvalidateBlock(pindexNew);
|
ScheduleInvalidateBlock(pindex);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bestChainLock.nHeight >= pindexNew->nHeight) {
|
if (bestChainLock.nHeight >= pindex->nHeight) {
|
||||||
// already got the same CLSIG or a better one
|
// already got the same CLSIG or a better one
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pindexNew->nHeight == lastSignedHeight) {
|
if (pindex->nHeight == lastSignedHeight) {
|
||||||
// already signed this one
|
// already signed this one
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lastSignedHeight = pindexNew->nHeight;
|
lastSignedHeight = pindex->nHeight;
|
||||||
lastSignedRequestId = requestId;
|
lastSignedRequestId = requestId;
|
||||||
lastSignedMsgHash = msgHash;
|
lastSignedMsgHash = msgHash;
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ class CChainLocksHandler : public CRecoveredSigsListener
|
|||||||
private:
|
private:
|
||||||
CScheduler* scheduler;
|
CScheduler* scheduler;
|
||||||
CCriticalSection cs;
|
CCriticalSection cs;
|
||||||
|
bool tryLockChainTipScheduled{false};
|
||||||
std::atomic<bool> inEnforceBestChainLock{false};
|
std::atomic<bool> inEnforceBestChainLock{false};
|
||||||
|
|
||||||
uint256 bestChainLockHash;
|
uint256 bestChainLockHash;
|
||||||
@ -74,8 +75,8 @@ public:
|
|||||||
CChainLocksHandler(CScheduler* _scheduler);
|
CChainLocksHandler(CScheduler* _scheduler);
|
||||||
~CChainLocksHandler();
|
~CChainLocksHandler();
|
||||||
|
|
||||||
void RegisterAsRecoveredSigsListener();
|
void Start();
|
||||||
void UnregisterAsRecoveredSigsListener();
|
void Stop();
|
||||||
|
|
||||||
bool AlreadyHave(const CInv& inv);
|
bool AlreadyHave(const CInv& inv);
|
||||||
bool GetChainLockByHash(const uint256& hash, CChainLockSig& ret);
|
bool GetChainLockByHash(const uint256& hash, CChainLockSig& ret);
|
||||||
@ -86,6 +87,7 @@ public:
|
|||||||
void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork);
|
void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork);
|
||||||
void NewPoWValidBlock(const CBlockIndex* pindex, const std::shared_ptr<const CBlock>& block);
|
void NewPoWValidBlock(const CBlockIndex* pindex, const std::shared_ptr<const CBlock>& block);
|
||||||
void SyncTransaction(const CTransaction &tx, const CBlockIndex *pindex, int posInBlock);
|
void SyncTransaction(const CTransaction &tx, const CBlockIndex *pindex, int posInBlock);
|
||||||
|
void TrySignChainTip();
|
||||||
void EnforceBestChainLock();
|
void EnforceBestChainLock();
|
||||||
virtual void HandleNewRecoveredSig(const CRecoveredSig& recoveredSig);
|
virtual void HandleNewRecoveredSig(const CRecoveredSig& recoveredSig);
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ void StartLLMQSystem()
|
|||||||
quorumSigSharesManager->StartWorkerThread();
|
quorumSigSharesManager->StartWorkerThread();
|
||||||
}
|
}
|
||||||
if (chainLocksHandler) {
|
if (chainLocksHandler) {
|
||||||
chainLocksHandler->RegisterAsRecoveredSigsListener();
|
chainLocksHandler->Start();
|
||||||
}
|
}
|
||||||
if (quorumInstantSendManager) {
|
if (quorumInstantSendManager) {
|
||||||
quorumInstantSendManager->RegisterAsRecoveredSigsListener();
|
quorumInstantSendManager->RegisterAsRecoveredSigsListener();
|
||||||
@ -79,7 +79,7 @@ void StopLLMQSystem()
|
|||||||
quorumInstantSendManager->UnregisterAsRecoveredSigsListener();
|
quorumInstantSendManager->UnregisterAsRecoveredSigsListener();
|
||||||
}
|
}
|
||||||
if (chainLocksHandler) {
|
if (chainLocksHandler) {
|
||||||
chainLocksHandler->UnregisterAsRecoveredSigsListener();
|
chainLocksHandler->Stop();
|
||||||
}
|
}
|
||||||
if (quorumSigSharesManager) {
|
if (quorumSigSharesManager) {
|
||||||
quorumSigSharesManager->StopWorkerThread();
|
quorumSigSharesManager->StopWorkerThread();
|
||||||
|
Loading…
Reference in New Issue
Block a user