From 5f12f6dcf9ab462ef14cf4faebc88bea6ee0265b Mon Sep 17 00:00:00 2001 From: Alessandro Rezzi Date: Sun, 14 Jan 2024 11:39:59 +0100 Subject: [PATCH] feat(consensus): Generalize ehf activation Try to sign any ehf deployment that can be activated and that hasn't been mined on chain yet. Also when receiving a new recovered signature try to match it with any ehf deployment which hasn't been mined on chain yet --- src/llmq/ehf_signals.cpp | 67 ++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/src/llmq/ehf_signals.cpp b/src/llmq/ehf_signals.cpp index 697b6a9d07535f..4edb1ca32d61a0 100644 --- a/src/llmq/ehf_signals.cpp +++ b/src/llmq/ehf_signals.cpp @@ -54,8 +54,15 @@ void CEHFSignalsHandler::UpdatedBlockTip(const CBlockIndex* const pindexNew) // TODO: v20 will never attempt to create EHF messages on main net; if this is needed it will be done by v20.1 or v21 nodes return; } - // TODO: should do this for all not-yet-signied bits - trySignEHFSignal(Params().GetConsensus().vDeployments[Consensus::DEPLOYMENT_MN_RR].bit, pindexNew); + const auto ehfSignals = WITH_LOCK(cs_main, return chainstate.GetMNHFSignalsStage(pindexNew)); + for (const auto& deployment : Params().GetConsensus().vDeployments) { + // Skip deployments that do not use dip0023 + if (!deployment.useEHF) continue; + // Try to sign only activable deployments that haven't been mined yet + if (ehfSignals.find(deployment.bit) == ehfSignals.end() && Params().IsValidMNActivation(deployment.bit, pindexNew->GetMedianTimePast())) { + trySignEHFSignal(deployment.bit, pindexNew); + } + } } void CEHFSignalsHandler::trySignEHFSignal(int bit, const CBlockIndex* const pindex) @@ -110,33 +117,41 @@ void CEHFSignalsHandler::HandleNewRecoveredSig(const CRecoveredSig& recoveredSig return; } + const auto ehfSignals = WITH_LOCK(cs_main, return chainstate.GetMNHFSignalsStage(chainstate.m_chain.Tip())); MNHFTxPayload mnhfPayload; - // TODO: should do this for all not-yet-signied bits - mnhfPayload.signal.versionBit = Params().GetConsensus().vDeployments[Consensus::DEPLOYMENT_MN_RR].bit; - - const uint256 expectedId = mnhfPayload.GetRequestId(); - LogPrint(BCLog::EHF, "CEHFSignalsHandler::HandleNewRecoveredSig expecting ID=%s received=%s\n", expectedId.ToString(), recoveredSig.getId().ToString()); - if (recoveredSig.getId() != mnhfPayload.GetRequestId()) { - // there's nothing interesting for CEHFSignalsHandler - LogPrint(BCLog::EHF, "CEHFSignalsHandler::HandleNewRecoveredSig id is known but it's not MN_RR, expected: %s\n", mnhfPayload.GetRequestId().ToString()); - return; - } - - mnhfPayload.signal.quorumHash = recoveredSig.getQuorumHash(); - mnhfPayload.signal.sig = recoveredSig.sig.Get(); - - CMutableTransaction tx = mnhfPayload.PrepareTx(); + for (const auto& deployment : Params().GetConsensus().vDeployments) { + // skip deployments that do not use dip0023 or that have already been mined + if (!deployment.useEHF || ehfSignals.find(deployment.bit) != ehfSignals.end()) continue; + + mnhfPayload.signal.versionBit = deployment.bit; + const uint256 expectedId = mnhfPayload.GetRequestId(); + LogPrint(BCLog::EHF, "CEHFSignalsHandler::HandleNewRecoveredSig expecting ID=%s received=%s\n", + expectedId.ToString(), recoveredSig.getId().ToString()); + if (recoveredSig.getId() != mnhfPayload.GetRequestId()) { + // wrong deployment! Check the next one + continue; + } - { - CTransactionRef tx_to_sent = MakeTransactionRef(std::move(tx)); - LogPrintf("CEHFSignalsHandler::HandleNewRecoveredSig Special EHF TX is created hash=%s\n", tx_to_sent->GetHash().ToString()); - LOCK(cs_main); - TxValidationState state; - if (AcceptToMemoryPool(chainstate, mempool, state, tx_to_sent, /* bypass_limits=*/ false, /* nAbsurdFee=*/ 0)) { - connman.RelayTransaction(*tx_to_sent); - } else { - LogPrintf("CEHFSignalsHandler::HandleNewRecoveredSig -- AcceptToMemoryPool failed: %s\n", state.ToString()); + mnhfPayload.signal.quorumHash = recoveredSig.getQuorumHash(); + mnhfPayload.signal.sig = recoveredSig.sig.Get(); + + CMutableTransaction tx = mnhfPayload.PrepareTx(); + + { + CTransactionRef tx_to_sent = MakeTransactionRef(std::move(tx)); + LogPrintf("CEHFSignalsHandler::HandleNewRecoveredSig Special EHF TX is created hash=%s\n", + tx_to_sent->GetHash().ToString()); + LOCK(cs_main); + TxValidationState state; + if (AcceptToMemoryPool(chainstate, mempool, state, tx_to_sent, /* bypass_limits=*/false, /* nAbsurdFee=*/ + 0)) { + connman.RelayTransaction(*tx_to_sent); + } else { + LogPrintf("CEHFSignalsHandler::HandleNewRecoveredSig -- AcceptToMemoryPool failed: %s\n", + state.ToString()); + } } + break; } } } // namespace llmq