Skip to content

Commit db5b53a

Browse files
Merge dashpay#6434: fix: early EHF and buried EHF are indistinguish
4629bb9 fix: add missing cs_main annotation for ForceSignalDBUpdate (Konstantin Akimov) 05041a4 fix: force ehf signal db update (UdjinM6) 94d8032 fix: typo name of key (Konstantin Akimov) 9ceba88 style: clang suggestion (Konstantin Akimov) c6bb9a5 perf: re-use evo data about signals between v20 and mn_rr as non-corrupted (Konstantin Akimov) 7a7c9f1 fix: early EHF and buried EHF are indistinguish (Konstantin Akimov) Pull request description: ## Issue being fixed or feature implemented It seems as EHF signal will be mined before node is updated, this signal is lost and node can't activate hard-fork anymore. ## What was done? EHF signals doesn't expire anymore. To avoid full re-index key in database is changed. Client with enabled "pruned mode" will be required to do re-index. Alternate solution - revert this commit 4b046bb and introduce time-out for expiring EHF signals. ## How Has This Been Tested? Test on my local instance with testnet and mainnet. Testing on miner-1 on testnet is done. First start of miner took 50 seconds, 29 of them the node was re-scanning blockchain and looking for EHF transaction ## Breaking Changes It requires re-index for nodes with enabled pruning of blocks. ## Checklist: - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: PastaPastaPasta: utACK [4629bb9](dashpay@4629bb9) UdjinM6: utACK 4629bb9 Tree-SHA512: 189533da5726edbcf2d9cf0e9a3957a10ebc223c25fd88aec3aa9095ae2e7d955ea1f7a1384bc2c97a0cc06110c9e38845a8cafdbd56ff9637bb907ddc639850
1 parent a6ee725 commit db5b53a

File tree

3 files changed

+54
-18
lines changed

3 files changed

+54
-18
lines changed

src/evo/mnhftx.cpp

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
static const std::string MNEHF_REQUESTID_PREFIX = "mnhf";
2626
static const std::string DB_SIGNALS = "mnhf_s";
27+
static const std::string DB_SIGNALS_v2 = "mnhf_s2";
2728

2829
uint256 MNHFTxPayload::GetRequestId() const
2930
{
@@ -57,34 +58,33 @@ CMNHFManager::Signals CMNHFManager::GetSignalsStage(const CBlockIndex* const pin
5758
{
5859
if (!DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) return {};
5960

60-
Signals signals = GetForBlock(pindexPrev);
61+
Signals signals_tmp = GetForBlock(pindexPrev);
62+
6163
if (pindexPrev == nullptr) return {};
6264
const int height = pindexPrev->nHeight + 1;
63-
for (auto it = signals.begin(); it != signals.end(); ) {
64-
bool found{false};
65-
const auto signal_pindex = pindexPrev->GetAncestor(it->second);
65+
66+
Signals signals_ret;
67+
68+
for (auto signal : signals_tmp) {
69+
bool expired{false};
70+
const auto signal_pindex = pindexPrev->GetAncestor(signal.second);
6671
assert(signal_pindex != nullptr);
6772
const int64_t signal_time = signal_pindex->GetMedianTimePast();
6873
for (int index = 0; index < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++index) {
6974
const auto& deployment = Params().GetConsensus().vDeployments[index];
70-
if (deployment.bit != it->first) continue;
75+
if (deployment.bit != signal.first) continue;
7176
if (signal_time < deployment.nStartTime) {
7277
// new deployment is using the same bit as the old one
73-
LogPrintf("CMNHFManager::GetSignalsStage: mnhf signal bit=%d height:%d is expired at height=%d\n", it->first, it->second, height);
74-
it = signals.erase(it);
75-
} else {
76-
++it;
78+
LogPrintf("CMNHFManager::GetSignalsStage: mnhf signal bit=%d height:%d is expired at height=%d\n",
79+
signal.first, signal.second, height);
80+
expired = true;
7781
}
78-
found = true;
79-
break;
8082
}
81-
if (!found) {
82-
// no deployment means we buried it and aren't using the same bit (yet)
83-
LogPrintf("CMNHFManager::GetSignalsStage: mnhf signal bit=%d height:%d is not known at height=%d\n", it->first, it->second, height);
84-
it = signals.erase(it);
83+
if (!expired) {
84+
signals_ret.insert(signal);
8585
}
8686
}
87-
return signals;
87+
return signals_ret;
8888
}
8989

9090
bool MNHFTx::Verify(const llmq::CQuorumManager& qman, const uint256& quorumHash, const uint256& requestId, const uint256& msgHash, TxValidationState& state) const
@@ -287,6 +287,9 @@ CMNHFManager::Signals CMNHFManager::GetForBlock(const CBlockIndex* pindex)
287287
const Consensus::Params& consensusParams{Params().GetConsensus()};
288288
while (!to_calculate.empty()) {
289289
const CBlockIndex* pindex_top{to_calculate.top()};
290+
if (pindex_top->nHeight % 1000 == 0) {
291+
LogPrintf("re-index EHF signals at block %d\n", pindex_top->nHeight);
292+
}
290293
CBlock block;
291294
if (!ReadBlockFromDisk(block, pindex_top, consensusParams)) {
292295
throw std::runtime_error("failed-getehfforblock-read");
@@ -328,11 +331,19 @@ std::optional<CMNHFManager::Signals> CMNHFManager::GetFromCache(const CBlockInde
328331
return signals;
329332
}
330333
}
331-
if (m_evoDb.Read(std::make_pair(DB_SIGNALS, blockHash), signals)) {
334+
if (m_evoDb.Read(std::make_pair(DB_SIGNALS_v2, blockHash), signals)) {
332335
LOCK(cs_cache);
333336
mnhfCache.insert(blockHash, signals);
334337
return signals;
335338
}
339+
if (!DeploymentActiveAt(*pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_MN_RR)) {
340+
// before mn_rr activation we are safe
341+
if (m_evoDb.Read(std::make_pair(DB_SIGNALS, blockHash), signals)) {
342+
LOCK(cs_cache);
343+
mnhfCache.insert(blockHash, signals);
344+
return signals;
345+
}
346+
}
336347
return std::nullopt;
337348
}
338349

@@ -346,7 +357,7 @@ void CMNHFManager::AddToCache(const Signals& signals, const CBlockIndex* const p
346357
}
347358
if (!DeploymentActiveAt(*pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) return;
348359

349-
m_evoDb.Write(std::make_pair(DB_SIGNALS, blockHash), signals);
360+
m_evoDb.Write(std::make_pair(DB_SIGNALS_v2, blockHash), signals);
350361
}
351362

352363
void CMNHFManager::AddSignal(const CBlockIndex* const pindex, int bit)
@@ -364,6 +375,25 @@ void CMNHFManager::ConnectManagers(gsl::not_null<ChainstateManager*> chainman, g
364375
m_qman = qman;
365376
}
366377

378+
bool CMNHFManager::ForceSignalDBUpdate()
379+
{
380+
// force ehf signals db update
381+
auto dbTx = m_evoDb.BeginTransaction();
382+
383+
const bool last_legacy = bls::bls_legacy_scheme.load();
384+
bls::bls_legacy_scheme.store(false);
385+
GetSignalsStage(m_chainman->ActiveChainstate().m_chain.Tip());
386+
bls::bls_legacy_scheme.store(last_legacy);
387+
388+
dbTx->Commit();
389+
// flush it to disk
390+
if (!m_evoDb.CommitRootTransaction()) {
391+
LogPrintf("CMNHFManager::%s -- failed to commit to evoDB\n", __func__);
392+
return false;
393+
}
394+
return true;
395+
}
396+
367397
std::string MNHFTx::ToString() const
368398
{
369399
return strprintf("MNHFTx(versionBit=%d, quorumHash=%s, sig=%s)",

src/evo/mnhftx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ class CMNHFManager : public AbstractEHFManager
155155
*/
156156
void DisconnectManagers() { m_chainman = nullptr; m_qman = nullptr; };
157157

158+
bool ForceSignalDBUpdate() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
159+
158160
private:
159161
void AddToCache(const Signals& signals, const CBlockIndex* const pindex);
160162

src/init.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2064,6 +2064,10 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
20642064
strLoadError = _("Error upgrading evo database");
20652065
break;
20662066
}
2067+
if (!node.mnhf_manager->ForceSignalDBUpdate()) {
2068+
strLoadError = _("Error upgrading evo database for EHF");
2069+
break;
2070+
}
20672071

20682072
for (CChainState* chainstate : chainman.GetAll()) {
20692073
if (!is_coinsview_empty(chainstate)) {

0 commit comments

Comments
 (0)