Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: generalize ehf activation #5824

Merged
merged 2 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 37 additions & 26 deletions src/llmq/ehf_signals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 = 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)
Expand Down Expand Up @@ -110,33 +117,37 @@ void CEHFSignalsHandler::HandleNewRecoveredSig(const CRecoveredSig& recoveredSig
return;
}

const auto ehfSignals = chainstate.GetMNHFSignalsStage(WITH_LOCK(cs_main, return 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() != expectedId) {
// wrong deployment! Check the next one
panleone marked this conversation as resolved.
Show resolved Hide resolved
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);
const MempoolAcceptResult result = AcceptToMemoryPool(chainstate, mempool, tx_to_sent, /* bypass_limits */ false);
if (result.m_result_type == MempoolAcceptResult::ResultType::VALID) {
connman.RelayTransaction(*tx_to_sent);
} else {
LogPrintf("CEHFSignalsHandler::HandleNewRecoveredSig -- AcceptToMemoryPool failed: %s\n", result.m_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);
const MempoolAcceptResult result = AcceptToMemoryPool(chainstate, mempool, tx_to_sent, /* bypass_limits */ false);
if (result.m_result_type == MempoolAcceptResult::ResultType::VALID) {
connman.RelayTransaction(*tx_to_sent);
} else {
LogPrintf("CEHFSignalsHandler::HandleNewRecoveredSig -- AcceptToMemoryPool failed: %s\n", result.m_state.ToString());
}
}
break;
}
}
} // namespace llmq
14 changes: 9 additions & 5 deletions test/functional/test_framework/test_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -1139,19 +1139,23 @@ def activate_v19(self, expected_activation_height=None):
def activate_v20(self, expected_activation_height=None):
self.activate_by_name('v20', expected_activation_height)

def activate_mn_rr(self, expected_activation_height=None):
def activate_ehf_by_name(self, name, expected_activation_height=None):
self.nodes[0].sporkupdate("SPORK_24_TEST_EHF", 0)
self.wait_for_sporks_same()
mn_rr_height = 0
while mn_rr_height == 0:
assert get_bip9_details(self.nodes[0], name)['ehf']
ehf_height = 0
while ehf_height == 0:
time.sleep(1)
try:
mn_rr_height = get_bip9_details(self.nodes[0], 'mn_rr')['ehf_height']
ehf_height = get_bip9_details(self.nodes[0], name)['ehf_height']
except KeyError:
pass
self.nodes[0].generate(1)
self.sync_all()
self.activate_by_name('mn_rr', expected_activation_height)
self.activate_by_name(name, expected_activation_height)

def activate_mn_rr(self, expected_activation_height=None):
self.activate_ehf_by_name('mn_rr', expected_activation_height)

def set_dash_llmq_test_params(self, llmq_size, llmq_threshold):
self.llmq_size = llmq_size
Expand Down
Loading