Skip to content

Commit 3c66a28

Browse files
authored
Merge pull request #937 from openmina/feat/block-prevalidation-continued
feat(consensus): More permissive block receipt time check
2 parents ddc6414 + 4da0e6e commit 3c66a28

File tree

2 files changed

+40
-9
lines changed

2 files changed

+40
-9
lines changed

node/src/consensus/consensus_reducer.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ impl ConsensusState {
5555
hash: hash.clone(),
5656
block: block.clone(),
5757
};
58-
match state.prevalidate_block(&block) {
58+
let allow_block_too_late = allow_block_too_late(state, &block);
59+
60+
match state.prevalidate_block(&block, allow_block_too_late) {
5961
Ok(()) => {
6062
dispatcher.push(ConsensusAction::BlockPrevalidateSuccess { hash });
6163
}
@@ -334,3 +336,26 @@ impl ConsensusState {
334336
}
335337
}
336338
}
339+
340+
/// Decide if the time-reception check should be done for this block or not.
341+
///
342+
/// The check is skipped if the block's global_slot is greater than the
343+
/// current best tip and the difference greater than 2.
344+
///
345+
/// Ideally we would differentiate between requested blocks and blocks
346+
/// received from gossip, but this difference doesn't really exist
347+
/// in the WebRTC transport, hence this heuristic.
348+
fn allow_block_too_late(state: &crate::State, block: &ArcBlockWithHash) -> bool {
349+
let (has_greater_blobal_slot, diff_with_best_tip) = state
350+
.transition_frontier
351+
.best_tip()
352+
.map(|b| {
353+
(
354+
block.global_slot() > b.global_slot(),
355+
b.global_slot().abs_diff(block.global_slot()),
356+
)
357+
})
358+
.unwrap_or((false, 0));
359+
360+
has_greater_blobal_slot && diff_with_best_tip > 2
361+
}

node/src/state.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ impl State {
379379
pub fn prevalidate_block(
380380
&self,
381381
block: &ArcBlockWithHash,
382+
allow_block_too_late: bool,
382383
) -> Result<(), BlockPrevalidationError> {
383384
let Some((genesis, cur_global_slot)) =
384385
None.or_else(|| Some((self.genesis_block()?, self.cur_global_slot()?)))
@@ -403,7 +404,9 @@ impl State {
403404
current_global_slot: cur_global_slot,
404405
block_global_slot,
405406
});
406-
} else if cur_global_slot.saturating_sub(block_global_slot) > delta {
407+
} else if !allow_block_too_late
408+
&& cur_global_slot.saturating_sub(block_global_slot) > delta
409+
{
407410
// Too_late
408411
return Err(BlockPrevalidationError::ReceivedTooLate {
409412
current_global_slot: cur_global_slot,
@@ -513,7 +516,10 @@ impl P2p {
513516
P2pCallbacks {
514517
on_p2p_channels_transaction_libp2p_received: Some(redux::callback!(
515518
on_p2p_channels_transaction_libp2p_received(transaction: Box<MinaBaseUserCommandStableV2>) -> crate::Action{
516-
TransactionPoolAction::StartVerify { commands: std::iter::once(*transaction).collect(), from_rpc: None }
519+
TransactionPoolAction::StartVerify {
520+
commands: std::iter::once(*transaction).collect(),
521+
from_rpc: None
522+
}
517523
}
518524
)),
519525
on_p2p_channels_snark_job_commitment_received: Some(redux::callback!(
@@ -527,7 +533,7 @@ impl P2p {
527533
}
528534
)),
529535
on_p2p_channels_snark_libp2p_received: Some(redux::callback!(
530-
on_p2p_channels_snark_received((peer_id: PeerId, snark: Box<Snark>)) -> crate::Action{
536+
on_p2p_channels_snark_libp2p_received((peer_id: PeerId, snark: Box<Snark>)) -> crate::Action{
531537
SnarkPoolCandidateAction::WorkReceived { peer_id, work: *snark }
532538
}
533539
)),
@@ -573,12 +579,12 @@ impl P2p {
573579
)),
574580
on_p2p_peer_best_tip_update: Some(redux::callback!(
575581
on_p2p_peer_best_tip_update(best_tip: BlockWithHash<Arc<MinaBlockBlockStableV2>>) -> crate::Action{
576-
ConsensusAction::P2pBestTipUpdate{best_tip}
582+
ConsensusAction::P2pBestTipUpdate { best_tip }
577583
}
578584
)),
579585
on_p2p_channels_rpc_ready: Some(redux::callback!(
580586
on_p2p_channels_rpc_ready(peer_id: PeerId) -> crate::Action{
581-
P2pCallbacksAction::P2pChannelsRpcReady {peer_id}
587+
P2pCallbacksAction::P2pChannelsRpcReady { peer_id }
582588
}
583589
)),
584590
on_p2p_channels_rpc_timeout: Some(redux::callback!(
@@ -588,17 +594,17 @@ impl P2p {
588594
)),
589595
on_p2p_channels_rpc_response_received: Some(redux::callback!(
590596
on_p2p_channels_rpc_response_received((peer_id: PeerId, id: P2pRpcId, response: Option<Box<P2pRpcResponse>>)) -> crate::Action{
591-
P2pCallbacksAction::P2pChannelsRpcResponseReceived {peer_id, id, response}
597+
P2pCallbacksAction::P2pChannelsRpcResponseReceived { peer_id, id, response }
592598
}
593599
)),
594600
on_p2p_channels_rpc_request_received: Some(redux::callback!(
595601
on_p2p_channels_rpc_request_received((peer_id: PeerId, id: P2pRpcId, request: Box<P2pRpcRequest>)) -> crate::Action{
596-
P2pCallbacksAction::P2pChannelsRpcRequestReceived {peer_id, id, request}
602+
P2pCallbacksAction::P2pChannelsRpcRequestReceived { peer_id, id, request }
597603
}
598604
)),
599605
on_p2p_channels_streaming_rpc_response_received: Some(redux::callback!(
600606
on_p2p_channels_streaming_rpc_response_received((peer_id: PeerId, id: P2pRpcId, response: Option<P2pStreamingRpcResponseFull>)) -> crate::Action{
601-
P2pCallbacksAction::P2pChannelsStreamingRpcResponseReceived {peer_id, id, response}
607+
P2pCallbacksAction::P2pChannelsStreamingRpcResponseReceived { peer_id, id, response }
602608
}
603609
)),
604610
on_p2p_channels_streaming_rpc_timeout: Some(redux::callback!(

0 commit comments

Comments
 (0)