Skip to content

Commit 21fb876

Browse files
committed
refactor: Move block prevalidation logic to core
1 parent 969d40b commit 21fb876

File tree

5 files changed

+100
-87
lines changed

5 files changed

+100
-87
lines changed

core/src/block/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ pub use block_with_hash::{BlockHeaderWithHash, BlockWithHash};
44
mod applied_block;
55
pub use applied_block::AppliedBlock;
66

7+
pub mod prevalidate;
8+
79
pub mod genesis;
810

911
use std::sync::Arc;

core/src/block/prevalidate.rs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
use serde::{Deserialize, Serialize};
2+
3+
use crate::constants::PROTOCOL_VERSION;
4+
5+
use super::ArcBlockWithHash;
6+
7+
#[derive(Serialize, Deserialize, Debug, Clone)]
8+
pub enum BlockPrevalidationError {
9+
GenesisNotReady,
10+
ReceivedTooEarly {
11+
current_global_slot: u32,
12+
block_global_slot: u32,
13+
},
14+
ReceivedTooLate {
15+
current_global_slot: u32,
16+
block_global_slot: u32,
17+
delta: u32,
18+
},
19+
InvalidGenesisProtocolState,
20+
InvalidProtocolVersion,
21+
MismatchedProtocolVersion,
22+
ConsantsMismatch,
23+
InvalidDeltaBlockChainProof,
24+
}
25+
26+
pub fn prevalidate_block(
27+
block: &ArcBlockWithHash,
28+
genesis: &ArcBlockWithHash,
29+
cur_global_slot: u32,
30+
allow_block_too_late: bool,
31+
) -> Result<(), BlockPrevalidationError> {
32+
let block_global_slot = block.global_slot();
33+
34+
let delta = genesis.constants().delta.as_u32();
35+
if cur_global_slot < block_global_slot {
36+
// Too_early
37+
return Err(BlockPrevalidationError::ReceivedTooEarly {
38+
current_global_slot: cur_global_slot,
39+
block_global_slot,
40+
});
41+
} else if !allow_block_too_late && cur_global_slot.saturating_sub(block_global_slot) > delta {
42+
// Too_late
43+
return Err(BlockPrevalidationError::ReceivedTooLate {
44+
current_global_slot: cur_global_slot,
45+
block_global_slot,
46+
delta,
47+
});
48+
}
49+
50+
if block.header().genesis_state_hash() != genesis.hash() {
51+
return Err(BlockPrevalidationError::InvalidGenesisProtocolState);
52+
}
53+
54+
let (protocol_versions_are_valid, protocol_version_matches_daemon) = {
55+
let min_transaction_version = 1.into();
56+
let v = &block.header().current_protocol_version;
57+
let nv = block
58+
.header()
59+
.proposed_protocol_version_opt
60+
.as_ref()
61+
.unwrap_or(v);
62+
63+
// Our version values are unsigned, so there is no need to check that the
64+
// other parts are not negative.
65+
let valid =
66+
v.transaction >= min_transaction_version && nv.transaction >= min_transaction_version;
67+
let compatible =
68+
v.transaction == PROTOCOL_VERSION.transaction && v.network == PROTOCOL_VERSION.network;
69+
70+
(valid, compatible)
71+
};
72+
73+
if !protocol_versions_are_valid {
74+
return Err(BlockPrevalidationError::InvalidProtocolVersion);
75+
} else if !protocol_version_matches_daemon {
76+
return Err(BlockPrevalidationError::MismatchedProtocolVersion);
77+
}
78+
79+
// NOTE: currently these cannot change between blocks, but that
80+
// may not always be true?
81+
if block.constants() != genesis.constants() {
82+
return Err(BlockPrevalidationError::ConsantsMismatch);
83+
}
84+
85+
// TODO(tizoc): check for InvalidDeltaBlockChainProof
86+
// https://github.com/MinaProtocol/mina/blob/d800da86a764d8d37ffb8964dd8d54d9f522b358/src/lib/mina_block/validation.ml#L369
87+
// https://github.com/MinaProtocol/mina/blob/d800da86a764d8d37ffb8964dd8d54d9f522b358/src/lib/transition_chain_verifier/transition_chain_verifier.ml
88+
89+
Ok(())
90+
}

node/src/p2p/callbacks/p2p_callbacks_reducer.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ use mina_p2p_messages::{
33
gossip::GossipNetMessageV2,
44
v2::{MinaLedgerSyncLedgerAnswerStableV2, StateHash},
55
};
6-
use openmina_core::{block::BlockWithHash, bug_condition, log, transaction::TransactionWithHash};
6+
use openmina_core::{
7+
block::{prevalidate::BlockPrevalidationError, BlockWithHash},
8+
bug_condition, log,
9+
transaction::TransactionWithHash,
10+
};
711
use p2p::{
812
channels::{
913
best_tip::P2pChannelsBestTipAction,
@@ -18,7 +22,6 @@ use redux::{ActionMeta, ActionWithMeta, Dispatcher};
1822
use crate::{
1923
p2p_ready,
2024
snark_pool::candidate::SnarkPoolCandidateAction,
21-
state::BlockPrevalidationError,
2225
transaction_pool::candidate::TransactionPoolCandidateAction,
2326
transition_frontier::candidate::{allow_block_too_late, TransitionFrontierCandidateAction},
2427
transition_frontier::sync::{

node/src/state.rs

Lines changed: 2 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::time::Duration;
33

44
use malloc_size_of_derive::MallocSizeOf;
55
use mina_p2p_messages::v2;
6-
use openmina_core::constants::PROTOCOL_VERSION;
6+
use openmina_core::block::prevalidate::{prevalidate_block, BlockPrevalidationError};
77
use openmina_core::transaction::{TransactionInfo, TransactionWithHash};
88
use p2p::P2pNetworkPubsubMessageCacheId;
99
use rand::prelude::*;
@@ -80,25 +80,6 @@ pub struct State {
8080
applied_actions_count: u64,
8181
}
8282

83-
#[derive(Serialize, Deserialize, Debug, Clone)]
84-
pub enum BlockPrevalidationError {
85-
GenesisNotReady,
86-
ReceivedTooEarly {
87-
current_global_slot: u32,
88-
block_global_slot: u32,
89-
},
90-
ReceivedTooLate {
91-
current_global_slot: u32,
92-
block_global_slot: u32,
93-
delta: u32,
94-
},
95-
InvalidGenesisProtocolState,
96-
InvalidProtocolVersion,
97-
MismatchedProtocolVersion,
98-
ConsantsMismatch,
99-
InvalidDeltaBlockChainProof,
100-
}
101-
10283
// Substate accessors that will be used in reducers
10384
use openmina_core::{bug_condition, impl_substate_access, SubstateAccess};
10485

@@ -408,70 +389,7 @@ impl State {
408389
return Err(BlockPrevalidationError::GenesisNotReady);
409390
};
410391

411-
// received_at_valid_time
412-
// https://github.com/minaprotocol/mina/blob/6af211ad58e9356f00ea4a636cea70aa8267c072/src/lib/consensus/proof_of_stake.ml#L2746
413-
{
414-
let block_global_slot = block.global_slot();
415-
416-
let delta = genesis.constants().delta.as_u32();
417-
if cur_global_slot < block_global_slot {
418-
// Too_early
419-
return Err(BlockPrevalidationError::ReceivedTooEarly {
420-
current_global_slot: cur_global_slot,
421-
block_global_slot,
422-
});
423-
} else if !allow_block_too_late
424-
&& cur_global_slot.saturating_sub(block_global_slot) > delta
425-
{
426-
// Too_late
427-
return Err(BlockPrevalidationError::ReceivedTooLate {
428-
current_global_slot: cur_global_slot,
429-
block_global_slot,
430-
delta,
431-
});
432-
}
433-
}
434-
435-
if block.header().genesis_state_hash() != genesis.hash() {
436-
return Err(BlockPrevalidationError::InvalidGenesisProtocolState);
437-
}
438-
439-
let (protocol_versions_are_valid, protocol_version_matches_daemon) = {
440-
let min_transaction_version = 1.into();
441-
let v = &block.header().current_protocol_version;
442-
let nv = block
443-
.header()
444-
.proposed_protocol_version_opt
445-
.as_ref()
446-
.unwrap_or(v);
447-
448-
// Our version values are unsigned, so there is no need to check that the
449-
// other parts are not negative.
450-
let valid = v.transaction >= min_transaction_version
451-
&& nv.transaction >= min_transaction_version;
452-
let compatible = v.transaction == PROTOCOL_VERSION.transaction
453-
&& v.network == PROTOCOL_VERSION.network;
454-
455-
(valid, compatible)
456-
};
457-
458-
if !protocol_versions_are_valid {
459-
return Err(BlockPrevalidationError::InvalidProtocolVersion);
460-
} else if !protocol_version_matches_daemon {
461-
return Err(BlockPrevalidationError::MismatchedProtocolVersion);
462-
}
463-
464-
// NOTE: currently these cannot change between blocks, but that
465-
// may not always be true?
466-
if block.constants() != genesis.constants() {
467-
return Err(BlockPrevalidationError::ConsantsMismatch);
468-
}
469-
470-
// TODO(tizoc): check for InvalidDeltaBlockChainProof
471-
// https://github.com/MinaProtocol/mina/blob/d800da86a764d8d37ffb8964dd8d54d9f522b358/src/lib/mina_block/validation.ml#L369
472-
// https://github.com/MinaProtocol/mina/blob/d800da86a764d8d37ffb8964dd8d54d9f522b358/src/lib/transition_chain_verifier/transition_chain_verifier.ml
473-
474-
Ok(())
392+
prevalidate_block(block, &genesis, cur_global_slot, allow_block_too_late)
475393
}
476394

477395
pub fn should_log_node_id(&self) -> bool {

node/src/transition_frontier/candidate/transition_frontier_candidate_actions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
use std::sync::Arc;
22

33
use mina_p2p_messages::v2::{MinaBlockBlockStableV2, StateHash};
4+
use openmina_core::block::prevalidate::BlockPrevalidationError;
45
use openmina_core::block::{ArcBlockWithHash, BlockWithHash};
56
use openmina_core::consensus::consensus_take;
67
use openmina_core::{action_event, ActionEvent};
78
use serde::{Deserialize, Serialize};
89
use snark::block_verify::SnarkBlockVerifyError;
910

1011
use crate::snark::block_verify::SnarkBlockVerifyId;
11-
use crate::state::BlockPrevalidationError;
1212

1313
use super::TransitionFrontierCandidateStatus;
1414

0 commit comments

Comments
 (0)