diff --git a/src/evo/cbtx.cpp b/src/evo/cbtx.cpp index 66ff72683ff93..b17eeb3909fca 100644 --- a/src/evo/cbtx.cpp +++ b/src/evo/cbtx.cpp @@ -321,7 +321,7 @@ bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPre return true; } -bool CheckCbTxBestChainlock(const CBlock& block, const CBlockIndex* pindex, const llmq::CChainLocksHandler& chainlock_handler, BlockValidationState& state) +bool CheckCbTxBestChainlock(const CBlock& block, const CBlockIndex* pindex, llmq::CChainLocksHandler& chainlock_handler, BlockValidationState& state) { if (block.vtx[0]->nType != TRANSACTION_COINBASE) { return true; @@ -365,9 +365,11 @@ bool CheckCbTxBestChainlock(const CBlock& block, const CBlockIndex* pindex, cons return true; } uint256 curBlockCoinbaseCLBlockHash = pindex->GetAncestor(curBlockCoinbaseCLHeight)->GetBlockHash(); - if (!chainlock_handler.VerifyChainLock(llmq::CChainLockSig(curBlockCoinbaseCLHeight, curBlockCoinbaseCLBlockHash, cbTx.bestCLSignature))) { + llmq::CChainLockSig cbtxcl = llmq::CChainLockSig(curBlockCoinbaseCLHeight, curBlockCoinbaseCLBlockHash, cbTx.bestCLSignature); + if (!chainlock_handler.VerifyChainLock(cbtxcl)) { return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cbtx-invalid-clsig"); } + chainlock_handler.ProcessNewChainLock(-1, cbtxcl, ::SerializeHash(cbtxcl)); } else if (cbTx.bestCLHeightDiff != 0) { // Null bestCLSignature is allowed only with bestCLHeightDiff = 0 return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cbtx-cldiff"); diff --git a/src/evo/cbtx.h b/src/evo/cbtx.h index b537c385a6a69..8c9aa1b6d19d5 100644 --- a/src/evo/cbtx.h +++ b/src/evo/cbtx.h @@ -89,7 +89,7 @@ bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex, const bool CalcCbTxMerkleRootMNList(const CBlock& block, const CBlockIndex* pindexPrev, uint256& merkleRootRet, BlockValidationState& state, const CCoinsViewCache& view); bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPrev, const llmq::CQuorumBlockProcessor& quorum_block_processor, uint256& merkleRootRet, BlockValidationState& state); -bool CheckCbTxBestChainlock(const CBlock& block, const CBlockIndex* pindexPrev, const llmq::CChainLocksHandler& chainlock_handler, BlockValidationState& state); +bool CheckCbTxBestChainlock(const CBlock& block, const CBlockIndex* pindexPrev, llmq::CChainLocksHandler& chainlock_handler, BlockValidationState& state); bool CalcCbTxBestChainlock(const llmq::CChainLocksHandler& chainlock_handler, const CBlockIndex* pindexPrev, uint32_t& bestCLHeightDiff, CBLSSignature& bestCLSignature); std::optional GetCoinbaseTx(const CBlockIndex* pindex); diff --git a/src/evo/specialtxman.cpp b/src/evo/specialtxman.cpp index 0108cc131bb6c..93006dfcecea3 100644 --- a/src/evo/specialtxman.cpp +++ b/src/evo/specialtxman.cpp @@ -131,7 +131,7 @@ static bool UndoSpecialTx(const CTransaction& tx, const CBlockIndex* pindex) } bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CMNHFManager& mnhfManager, - llmq::CQuorumBlockProcessor& quorum_block_processor, const llmq::CChainLocksHandler& chainlock_handler, + llmq::CQuorumBlockProcessor& quorum_block_processor, llmq::CChainLocksHandler& chainlock_handler, const Consensus::Params& consensusParams, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots, BlockValidationState& state, std::optional& updatesRet) { diff --git a/src/evo/specialtxman.h b/src/evo/specialtxman.h index 18a20381dcf15..b8a7c6c937c5e 100644 --- a/src/evo/specialtxman.h +++ b/src/evo/specialtxman.h @@ -31,7 +31,7 @@ extern RecursiveMutex cs_main; bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, const CCoinsViewCache& view, bool check_sigs, TxValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main); bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CMNHFManager& mnhfManager, - llmq::CQuorumBlockProcessor& quorum_block_processor, const llmq::CChainLocksHandler& chainlock_handler, + llmq::CQuorumBlockProcessor& quorum_block_processor, llmq::CChainLocksHandler& chainlock_handler, const Consensus::Params& consensusParams, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots, BlockValidationState& state, std::optional& updatesRet) EXCLUSIVE_LOCKS_REQUIRED(cs_main); bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CMNHFManager& mnhfManager, diff --git a/src/llmq/chainlocks.cpp b/src/llmq/chainlocks.cpp index ae1be6f172678..889237e294fa1 100644 --- a/src/llmq/chainlocks.cpp +++ b/src/llmq/chainlocks.cpp @@ -107,6 +107,11 @@ void CChainLocksHandler::ProcessMessage(const CNode& pfrom, const std::string& m void CChainLocksHandler::ProcessNewChainLock(const NodeId from, const llmq::CChainLockSig& clsig, const uint256& hash) { + if (!m_mn_sync.IsBlockchainSynced()) { + // too early to do anything + return; + } + CheckActiveState(); CInv clsigInv(MSG_CLSIG, hash); diff --git a/test/functional/feature_llmq_chainlocks.py b/test/functional/feature_llmq_chainlocks.py index 147b04d3a8d68..6428f72226c68 100755 --- a/test/functional/feature_llmq_chainlocks.py +++ b/test/functional/feature_llmq_chainlocks.py @@ -156,6 +156,7 @@ def run_test(self): self.log.info("Restart it so that it forgets all the chainlock messages from the past") self.restart_node(0) self.connect_nodes(0, 1) + force_finish_mnsync(self.nodes[0]) assert self.nodes[0].getbestblockhash() == good_tip self.nodes[0].invalidateblock(good_tip) self.log.info("Now try to reorg the chain")