@@ -35,12 +35,16 @@ CChainLocksHandler::~CChainLocksHandler()
35
35
{
36
36
}
37
37
38
- void CChainLocksHandler::RegisterAsRecoveredSigsListener ()
38
+ void CChainLocksHandler::Start ()
39
39
{
40
40
quorumSigningManager->RegisterRecoveredSigsListener (this );
41
+ scheduler->scheduleEvery ([&]() {
42
+ // regularely retry signing the current chaintip as it might have failed before due to missing ixlocks
43
+ TrySignChainTip ();
44
+ }, 5000 );
41
45
}
42
46
43
- void CChainLocksHandler::UnregisterAsRecoveredSigsListener ()
47
+ void CChainLocksHandler::Stop ()
44
48
{
45
49
quorumSigningManager->UnregisterRecoveredSigsListener (this );
46
50
}
@@ -184,30 +188,52 @@ void CChainLocksHandler::AcceptedBlockHeader(const CBlockIndex* pindexNew)
184
188
185
189
void CChainLocksHandler::UpdatedBlockTip (const CBlockIndex* pindexNew, const CBlockIndex* pindexFork)
186
190
{
191
+ // don't call TrySignChainTip directly but instead let the scheduler call it. This way we ensure that cs_main is
192
+ // never locked and TrySignChainTip is not called twice in parallel
193
+ LOCK (cs);
194
+ if (tryLockChainTipScheduled) {
195
+ return ;
196
+ }
197
+ tryLockChainTipScheduled = true ;
198
+ scheduler->scheduleFromNow ([&]() {
199
+ TrySignChainTip ();
200
+ LOCK (cs);
201
+ tryLockChainTipScheduled = false ;
202
+ }, 0 );
203
+ }
204
+
205
+ void CChainLocksHandler::TrySignChainTip ()
206
+ {
207
+ Cleanup ();
208
+
209
+ const CBlockIndex* pindex;
210
+ {
211
+ LOCK (cs_main);
212
+ pindex = chainActive.Tip ();
213
+ }
214
+
187
215
if (!fMasternodeMode ) {
188
216
return ;
189
217
}
190
- if (!pindexNew ->pprev ) {
218
+ if (!pindex ->pprev ) {
191
219
return ;
192
220
}
193
221
if (!sporkManager.IsSporkActive (SPORK_19_CHAINLOCKS_ENABLED)) {
194
222
return ;
195
223
}
196
224
197
- Cleanup ();
198
-
199
225
// DIP8 defines a process called "Signing attempts" which should run before the CLSIG is finalized
200
226
// To simplify the initial implementation, we skip this process and directly try to create a CLSIG
201
227
// This will fail when multiple blocks compete, but we accept this for the initial implementation.
202
228
// Later, we'll add the multiple attempts process.
203
229
204
- uint256 requestId = ::SerializeHash (std::make_pair (CLSIG_REQUESTID_PREFIX, pindexNew ->nHeight ));
205
- uint256 msgHash = pindexNew ->GetBlockHash ();
230
+ uint256 requestId = ::SerializeHash (std::make_pair (CLSIG_REQUESTID_PREFIX, pindex ->nHeight ));
231
+ uint256 msgHash = pindex ->GetBlockHash ();
206
232
207
233
{
208
234
LOCK (cs);
209
235
210
- if (bestChainLockBlockIndex == pindexNew ) {
236
+ if (bestChainLockBlockIndex == pindex ) {
211
237
// we first got the CLSIG, then the header, and then the block was connected.
212
238
// In this case there is no need to continue here.
213
239
// 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
218
244
return ;
219
245
}
220
246
221
- if (InternalHasConflictingChainLock (pindexNew ->nHeight , pindexNew ->GetBlockHash ())) {
247
+ if (InternalHasConflictingChainLock (pindex ->nHeight , pindex ->GetBlockHash ())) {
222
248
if (!inEnforceBestChainLock) {
223
249
// we accepted this block when there was no lock yet, but now a conflicting lock appeared. Invalidate it.
224
250
LogPrintf (" CChainLocksHandler::%s -- conflicting lock after block was accepted, invalidating now\n " ,
225
251
__func__);
226
- ScheduleInvalidateBlock (pindexNew );
252
+ ScheduleInvalidateBlock (pindex );
227
253
}
228
254
return ;
229
255
}
230
256
231
- if (bestChainLock.nHeight >= pindexNew ->nHeight ) {
257
+ if (bestChainLock.nHeight >= pindex ->nHeight ) {
232
258
// already got the same CLSIG or a better one
233
259
return ;
234
260
}
235
261
236
- if (pindexNew ->nHeight == lastSignedHeight) {
262
+ if (pindex ->nHeight == lastSignedHeight) {
237
263
// already signed this one
238
264
return ;
239
265
}
240
- lastSignedHeight = pindexNew ->nHeight ;
266
+ lastSignedHeight = pindex ->nHeight ;
241
267
lastSignedRequestId = requestId;
242
268
lastSignedMsgHash = msgHash;
243
269
}
0 commit comments