@@ -331,13 +331,26 @@ bool CheckCbTxBestChainlock(const CBlock& block, const CBlockIndex* pindex,
331
331
return true ;
332
332
}
333
333
334
+ static Mutex cached_mutex;
335
+ static const CBlockIndex* cached_pindex GUARDED_BY (cached_mutex){nullptr };
336
+ static std::optional<std::pair<CBLSSignature, uint32_t >> cached_chainlock GUARDED_BY (cached_mutex){std::nullopt};
337
+
334
338
auto best_clsig = chainlock_handler.GetBestChainLock ();
335
339
if (best_clsig.getHeight () == pindex->nHeight - 1 && cbTx.bestCLHeightDiff == 0 && cbTx.bestCLSignature == best_clsig.getSig ()) {
336
340
// matches our best clsig which still hold values for the previous block
341
+ LOCK (cached_mutex);
342
+ cached_chainlock = std::make_pair (cbTx.bestCLSignature , cbTx.bestCLHeightDiff );
343
+ cached_pindex = pindex;
337
344
return true ;
338
345
}
339
346
340
- const auto prevBlockCoinbaseChainlock = GetNonNullCoinbaseChainlock (pindex->pprev );
347
+ std::optional<std::pair<CBLSSignature, uint32_t >> prevBlockCoinbaseChainlock{std::nullopt};
348
+ if (LOCK (cached_mutex); cached_pindex == pindex->pprev ) {
349
+ prevBlockCoinbaseChainlock = cached_chainlock;
350
+ }
351
+ if (!prevBlockCoinbaseChainlock.has_value ()) {
352
+ prevBlockCoinbaseChainlock = GetNonNullCoinbaseChainlock (pindex->pprev );
353
+ }
341
354
// If std::optional prevBlockCoinbaseChainlock is empty, then up to the previous block, coinbase Chainlock is null.
342
355
if (prevBlockCoinbaseChainlock.has_value ()) {
343
356
// Previous block Coinbase has a non-null Chainlock: current block's Chainlock must be non-null and at least as new as the previous one
@@ -355,12 +368,18 @@ bool CheckCbTxBestChainlock(const CBlock& block, const CBlockIndex* pindex,
355
368
int curBlockCoinbaseCLHeight = pindex->nHeight - static_cast <int >(cbTx.bestCLHeightDiff ) - 1 ;
356
369
if (best_clsig.getHeight () == curBlockCoinbaseCLHeight && best_clsig.getSig () == cbTx.bestCLSignature ) {
357
370
// matches our best (but outdated) clsig, no need to verify it again
371
+ LOCK (cached_mutex);
372
+ cached_chainlock = std::make_pair (cbTx.bestCLSignature , cbTx.bestCLHeightDiff );
373
+ cached_pindex = pindex;
358
374
return true ;
359
375
}
360
376
uint256 curBlockCoinbaseCLBlockHash = pindex->GetAncestor (curBlockCoinbaseCLHeight)->GetBlockHash ();
361
377
if (chainlock_handler.VerifyChainLock (llmq::CChainLockSig (curBlockCoinbaseCLHeight, curBlockCoinbaseCLBlockHash, cbTx.bestCLSignature )) != llmq::VerifyRecSigStatus::Valid) {
362
378
return state.Invalid (BlockValidationResult::BLOCK_CONSENSUS, " bad-cbtx-invalid-clsig" );
363
379
}
380
+ LOCK (cached_mutex);
381
+ cached_chainlock = std::make_pair (cbTx.bestCLSignature , cbTx.bestCLHeightDiff );
382
+ cached_pindex = pindex;
364
383
} else if (cbTx.bestCLHeightDiff != 0 ) {
365
384
// Null bestCLSignature is allowed only with bestCLHeightDiff = 0
366
385
return state.Invalid (BlockValidationResult::BLOCK_CONSENSUS, " bad-cbtx-cldiff" );
0 commit comments