You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Merge bitcoin/bitcoin#27720: index: prevent race by calling 'CustomInit' prior setting 'synced' flag
3126454 index: prevent race by calling 'CustomInit' prior setting 'synced' flag (furszy)
Pull request description:
Decoupled from #27607.
Fixed a potential race condition in master (not possible so far) that could become an actual issue soon.
Where the index's `CustomAppend` method could be called (from `BlockConnected`) before its
`CustomInit` method, causing the index to try to update itself before it is initialized.
This could happen because we set the index `m_synced` flag (which enables `BlockConnected` events)
before calling to the child class init function (`CustomInit`). So, for example, the block filter index could
process a block before initialize the next filter position field and end up overwriting the first stored filter.
This race was introduced in bitcoin/bitcoin@bef4e40 from bitcoin/bitcoin#25494.
ACKs for top commit:
achow101:
ACK 3126454
mzumsande:
Code review ACK 3126454
TheCharlatan:
Nice, ACK 3126454
Tree-SHA512: 7a53fed1d2035cb4c1f331d6ee9f92d499b6cbb618ea534c6440f5a45ff9b3ac4dcff5fb4b88937f45a0be249e3a9c6dc6c3ac77180f12ae25fc56856ba39735
// if the bestblock is not part of the mainchain, find the fork
125
122
// and make sure we have all data down to the fork
@@ -143,6 +140,16 @@ bool BaseIndex::Init()
143
140
returnInitError(strprintf(Untranslated("%s best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)"), GetName()));
144
141
}
145
142
}
143
+
144
+
// Child init
145
+
if (!CustomInit(start_block ? std::make_optional(interfaces::BlockKey{start_block->GetBlockHash(), start_block->nHeight}) : std::nullopt)) {
146
+
returnfalse;
147
+
}
148
+
149
+
// Note: this will latch to true immediately if the user starts up with an empty
150
+
// datadir and an index enabled. If this is the case, indexation will happen solely
151
+
// via `BlockConnected` signals until, possibly, the next restart.
152
+
m_synced = synced;
146
153
returntrue;
147
154
}
148
155
@@ -408,11 +415,6 @@ bool BaseIndex::Start()
408
415
RegisterValidationInterface(this);
409
416
if (!Init()) returnfalse;
410
417
411
-
const CBlockIndex* index = m_best_block_index.load();
412
-
if (!CustomInit(index ? std::make_optional(interfaces::BlockKey{index->GetBlockHash(), index->nHeight}) : std::nullopt)) {
0 commit comments