Skip to content

Commit 9bba09e

Browse files
authored
Merge pull request #915 from openmina/fix/add-bug-conditions
fix(transition-frontier): Skip verification of completed works in locally produced blocks
2 parents 1b831f4 + 0f5da4f commit 9bba09e

File tree

3 files changed

+57
-14
lines changed

3 files changed

+57
-14
lines changed

node/src/block_producer/block_producer_reducer.rs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ impl BlockProducerEnabled {
134134
won_slot, chain, ..
135135
} = &mut state.current
136136
else {
137+
bug_condition!("Invalid state for `BlockProducerAction::WonSlotTransactionsGet` expected: `BlockProducerCurrentState::WonSlotProduceInit`, found: {:?}", state.current);
137138
return;
138139
};
139140

@@ -153,6 +154,7 @@ impl BlockProducerEnabled {
153154
won_slot, chain, ..
154155
} = &mut state.current
155156
else {
157+
bug_condition!("Invalid state for `BlockProducerAction::WonSlotTransactionsSuccess` expected: `BlockProducerCurrentState::WonSlotTransactionsGet`, found: {:?}", state.current);
156158
return;
157159
};
158160

@@ -178,6 +180,7 @@ impl BlockProducerEnabled {
178180
..
179181
} = &mut state.current
180182
else {
183+
bug_condition!("Invalid state for `BlockProducerAction::StagedLedgerDiffCreatePending` expected: `BlockProducerCurrentState::WonSlotTransactionsSuccess`, found: {:?}", state.current);
181184
return;
182185
};
183186
state.current = BlockProducerCurrentState::StagedLedgerDiffCreatePending {
@@ -194,6 +197,7 @@ impl BlockProducerEnabled {
194197
..
195198
} = &mut state.current
196199
else {
200+
bug_condition!("Invalid state for `BlockProducerAction::StagedLedgerDiffCreateSuccess` expected: `BlockProducerCurrentState::StagedLedgerDiffCreatePending`, found: {:?}", state.current);
197201
return;
198202
};
199203
state.current = BlockProducerCurrentState::StagedLedgerDiffCreateSuccess {
@@ -223,6 +227,8 @@ impl BlockProducerEnabled {
223227
dispatcher.push(BlockProducerEffectfulAction::BlockProveInit);
224228
}
225229
BlockProducerAction::BlockProvePending => {
230+
let current_state = std::mem::take(&mut state.current);
231+
226232
if let BlockProducerCurrentState::BlockUnprovenBuilt {
227233
won_slot,
228234
chain,
@@ -233,7 +239,7 @@ impl BlockProducerEnabled {
233239
block,
234240
block_hash,
235241
..
236-
} = std::mem::take(&mut state.current)
242+
} = current_state
237243
{
238244
state.current = BlockProducerCurrentState::BlockProvePending {
239245
time: meta.time(),
@@ -246,16 +252,20 @@ impl BlockProducerEnabled {
246252
block,
247253
block_hash,
248254
};
255+
} else {
256+
bug_condition!("Invalid state for `BlockProducerAction::BlockProvePending` expected: `BlockProducerCurrentState::BlockUnprovenBuilt`, found: {:?}", current_state);
249257
}
250258
}
251259
BlockProducerAction::BlockProveSuccess { proof } => {
260+
let current_state = std::mem::take(&mut state.current);
261+
252262
if let BlockProducerCurrentState::BlockProvePending {
253263
won_slot,
254264
chain,
255265
block,
256266
block_hash,
257267
..
258-
} = std::mem::take(&mut state.current)
268+
} = current_state
259269
{
260270
state.current = BlockProducerCurrentState::BlockProveSuccess {
261271
time: meta.time(),
@@ -265,27 +275,33 @@ impl BlockProducerEnabled {
265275
block_hash,
266276
proof: proof.clone(),
267277
};
278+
} else {
279+
bug_condition!("Invalid state for `BlockProducerAction::BlockProveSuccess` expected: `BlockProducerCurrentState::BlockProvePending`, found: {:?}", current_state);
268280
}
269281

270282
let dispatcher = state_context.into_dispatcher();
271283
dispatcher.push(BlockProducerEffectfulAction::BlockProveSuccess);
272284
}
273285
BlockProducerAction::BlockProduced => {
286+
let current_state = std::mem::take(&mut state.current);
287+
274288
if let BlockProducerCurrentState::BlockProveSuccess {
275289
won_slot,
276290
chain,
277291
block,
278292
block_hash,
279293
proof,
280294
..
281-
} = std::mem::take(&mut state.current)
295+
} = current_state
282296
{
283297
state.current = BlockProducerCurrentState::Produced {
284298
time: meta.time(),
285299
won_slot,
286300
chain,
287301
block: block.with_hash_and_proof(block_hash, *proof),
288302
};
303+
} else {
304+
bug_condition!("Invalid state for `BlockProducerAction::BlockProduced` expected: `BlockProducerCurrentState::BlockProveSuccess`, found: {:?}", current_state);
289305
}
290306

291307
let dispatcher = state_context.into_dispatcher();
@@ -301,6 +317,7 @@ impl BlockProducerEnabled {
301317
let blocks_inbetween = iter.map(|b| b.hash().clone()).collect();
302318
Some((best_tip.clone(), root_block.clone(), blocks_inbetween))
303319
}) else {
320+
bug_condition!("Invalid state for `BlockProducerAction::BlockInject`: did not find best_tip/root_block in block producer");
304321
return;
305322
};
306323

@@ -336,6 +353,8 @@ impl BlockProducerEnabled {
336353
chain: std::mem::take(chain),
337354
block: block.clone(),
338355
};
356+
} else {
357+
bug_condition!("Invalid state for `BlockProducerAction::BlockInjected` expected: `BlockProducerCurrentState::Produced`, found: {:?}", state.current);
339358
}
340359

341360
let dispatcher = state_context.into_dispatcher();
@@ -349,6 +368,8 @@ impl BlockProducerEnabled {
349368
consensus_constants: &ConsensusConstants,
350369
time: Timestamp,
351370
) {
371+
let current_state = std::mem::take(&mut self.current);
372+
352373
let BlockProducerCurrentState::StagedLedgerDiffCreateSuccess {
353374
won_slot,
354375
chain,
@@ -360,11 +381,13 @@ impl BlockProducerEnabled {
360381
pending_coinbase_witness,
361382
stake_proof_sparse_ledger,
362383
..
363-
} = std::mem::take(&mut self.current)
384+
} = current_state
364385
else {
386+
bug_condition!("Invalid state for `BlockProducerAction::BlockUnprovenBuild` expected: `BlockProducerCurrentState::StagedLedgerDiffCreateSuccess`, found: {:?}", current_state);
365387
return;
366388
};
367389
let Some(pred_block) = chain.last() else {
390+
bug_condition!("Invalid state for `BlockProducerAction::BlockUnprovenBuild`: did not find predecessor block");
368391
return;
369392
};
370393

node/src/stats/stats_block_producer.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -261,12 +261,7 @@ impl BlockProducerStats {
261261
}
262262

263263
pub fn block_apply_start(&mut self, time: redux::Timestamp, hash: &BlockHash) {
264-
let is_our_block = self
265-
.attempts
266-
.back()
267-
.and_then(|v| v.block.as_ref())
268-
.map_or(false, |b| &b.hash == hash);
269-
if !is_our_block {
264+
if !self.is_our_just_produced_block(hash) {
270265
return;
271266
}
272267

@@ -319,6 +314,22 @@ impl BlockProducerStats {
319314
true
320315
});
321316
}
317+
318+
/// Returns `true` if this is a block we just produced
319+
pub fn is_our_just_produced_block(&self, hash: &BlockHash) -> bool {
320+
// For the block to be ours:
321+
// - we must have an attempt to produce a block
322+
// - we must have just produced the proof for that block
323+
// - the hash must match
324+
if let Some(attempt) = self.attempts.back() {
325+
match (&attempt.status, attempt.block.as_ref()) {
326+
(BlockProductionStatus::ProofCreateSuccess, Some(block)) => &block.hash == hash,
327+
_ => false,
328+
}
329+
} else {
330+
false
331+
}
332+
}
322333
}
323334

324335
impl From<&BlockProducerWonSlot> for BlockProductionAttemptWonSlot {

node/src/transition_frontier/sync/transition_frontier_sync_effects.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,15 +247,24 @@ impl TransitionFrontierSyncAction {
247247
};
248248
let hash = block.hash.clone();
249249

250-
// During catchup, we skip the verificationf of completed work and zkApp txn proofs
251-
// until get closer to the best tip, at which point full verification is enabled.
252-
let skip_verification = super::CATCHUP_BLOCK_VERIFY_TAIL_LENGTH
253-
< store.state().transition_frontier.sync.pending_count();
250+
let is_our_block;
254251

255252
if let Some(stats) = store.service.stats() {
256253
stats.block_producer().block_apply_start(meta.time(), &hash);
254+
// TODO(tizoc): try a better approach that doesn't need
255+
// to make use of the collected stats.
256+
is_our_block = stats.block_producer().is_our_just_produced_block(&hash);
257+
} else {
258+
is_our_block = false;
257259
}
258260

261+
// During catchup, we skip the verificationf of completed work and zkApp txn proofs
262+
// until get closer to the best tip, at which point full verification is enabled.
263+
// We also skip verification of completed works if we produced this block.
264+
let skip_verification = is_our_block
265+
|| super::CATCHUP_BLOCK_VERIFY_TAIL_LENGTH
266+
< store.state().transition_frontier.sync.pending_count();
267+
259268
store.dispatch(LedgerWriteAction::Init {
260269
request: LedgerWriteRequest::BlockApply {
261270
block,

0 commit comments

Comments
 (0)