From 8d1cb4ceacadf9756842f37419ebef47d5d1dba6 Mon Sep 17 00:00:00 2001 From: t00ts Date: Wed, 15 Apr 2026 12:00:58 +0400 Subject: [PATCH 1/7] feat(validator): introduce `pathfinder-validator` crate --- crates/validator/Cargo.toml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 crates/validator/Cargo.toml diff --git a/crates/validator/Cargo.toml b/crates/validator/Cargo.toml new file mode 100644 index 0000000000..69e43d5727 --- /dev/null +++ b/crates/validator/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "pathfinder-validator" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +license = { workspace = true } +rust-version = { workspace = true } + +[dependencies] +anyhow = { workspace = true } +p2p = { path = "../p2p" } +p2p_proto = { path = "../p2p_proto" } +pathfinder-block-commitments = { path = "../block-commitments" } +pathfinder-class-hash = { path = "../class-hash" } +pathfinder-common = { path = "../common" } +pathfinder-compiler = { path = "../compiler" } +pathfinder-executor = { path = "../executor" } +pathfinder-gas-price = { path = "../gas-price" } +pathfinder-rpc = { path = "../rpc" } +pathfinder-storage = { path = "../storage" } +rayon = { workspace = true } +serde_json = { workspace = true } +starknet_api = { workspace = true } +thiserror = { workspace = true } +tracing = { workspace = true } + +[dev-dependencies] +assert_matches = { workspace = true } +pathfinder-common = { path = "../common", features = ["full-serde"] } +pathfinder-crypto = { path = "../crypto" } +pathfinder-executor = { path = "../executor" } +pathfinder-storage = { path = "../storage", features = ["small_aggregate_filters"] } +rstest = { workspace = true } +tokio = { workspace = true, features = ["test-util"] } From 2edccaffdf4bd6b37cfd5999d1159b209cf94648 Mon Sep 17 00:00:00 2001 From: t00ts Date: Wed, 15 Apr 2026 12:01:53 +0400 Subject: [PATCH 2/7] refactor(validator): move validator out of pathfinder crate --- crates/{pathfinder/src/consensus => validator/src}/error.rs | 0 crates/{pathfinder/src/validator.rs => validator/src/lib.rs} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename crates/{pathfinder/src/consensus => validator/src}/error.rs (100%) rename crates/{pathfinder/src/validator.rs => validator/src/lib.rs} (100%) diff --git a/crates/pathfinder/src/consensus/error.rs b/crates/validator/src/error.rs similarity index 100% rename from crates/pathfinder/src/consensus/error.rs rename to crates/validator/src/error.rs diff --git a/crates/pathfinder/src/validator.rs b/crates/validator/src/lib.rs similarity index 100% rename from crates/pathfinder/src/validator.rs rename to crates/validator/src/lib.rs From 7400a7a4620a77dcde19f71bd7f873e356d75b46 Mon Sep 17 00:00:00 2001 From: t00ts Date: Wed, 15 Apr 2026 12:06:02 +0400 Subject: [PATCH 3/7] refactor(validator): fix imports --- crates/validator/src/error.rs | 2 +- crates/validator/src/lib.rs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/validator/src/error.rs b/crates/validator/src/error.rs index 485215695c..8258811804 100644 --- a/crates/validator/src/error.rs +++ b/crates/validator/src/error.rs @@ -2,7 +2,7 @@ use pathfinder_storage::StorageError; -use crate::validator::WrongValidatorStageError; +use crate::WrongValidatorStageError; /// Errors that can occur when handling incoming proposal parts. /// diff --git a/crates/validator/src/lib.rs b/crates/validator/src/lib.rs index f92ccdc15c..4f9d383532 100644 --- a/crates/validator/src/lib.rs +++ b/crates/validator/src/lib.rs @@ -73,7 +73,9 @@ use pathfinder_gas_price::{ L2GasPriceValidationResult, }; -use crate::consensus::ProposalHandlingError; +pub mod error; + +use crate::error::ProposalHandlingError; /// TODO: Use this type as validation result. pub enum ValidationResult { @@ -1194,7 +1196,7 @@ mod tests { use rstest::rstest; use super::*; - use crate::consensus::ProposalError; + use crate::error::ProposalError; /// Creates a worker pool for tests. fn create_test_worker_pool() -> ValidatorWorkerPool { From 966c91f9042a93175ba8e4a96809657856c30741 Mon Sep 17 00:00:00 2001 From: t00ts Date: Wed, 15 Apr 2026 14:32:59 +0400 Subject: [PATCH 4/7] refactor(pathfinder): wire new validator crate --- Cargo.lock | 27 ++++++++++++++++++ Cargo.toml | 1 + crates/pathfinder/Cargo.toml | 3 +- crates/pathfinder/src/consensus.rs | 5 +--- .../src/consensus/inner/batch_execution.rs | 7 ++--- .../src/consensus/inner/dummy_proposal.rs | 2 +- .../src/consensus/inner/p2p_task.rs | 28 +++++++++---------- .../inner/p2p_task/p2p_task_tests.rs | 2 +- .../src/consensus/inner/proposal_validator.rs | 3 +- crates/pathfinder/src/devnet.rs | 12 ++++---- crates/pathfinder/src/lib.rs | 4 +-- crates/validator/src/lib.rs | 2 +- 12 files changed, 58 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 180fea022d..f6a717ceb5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8455,6 +8455,7 @@ dependencies = [ "pathfinder-rpc", "pathfinder-serde", "pathfinder-storage", + "pathfinder-validator", "pathfinder-version", "pretty_assertions_sorted", "primitive-types", @@ -8871,6 +8872,32 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "pathfinder-validator" +version = "0.22.2" +dependencies = [ + "anyhow", + "assert_matches", + "p2p", + "p2p_proto", + "pathfinder-block-commitments", + "pathfinder-class-hash", + "pathfinder-common", + "pathfinder-compiler", + "pathfinder-crypto", + "pathfinder-executor", + "pathfinder-gas-price", + "pathfinder-rpc", + "pathfinder-storage", + "rayon", + "rstest", + "serde_json", + "starknet_api", + "thiserror 2.0.18", + "tokio", + "tracing", +] + [[package]] name = "pathfinder-version" version = "0.22.2" diff --git a/Cargo.toml b/Cargo.toml index bf23b42ecc..136d73992f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ members = [ "crates/tagged", "crates/tagged-debug-derive", "crates/util", + "crates/validator", "crates/version", ] exclude = ["crates/load-test", "utils/pathfinder-probe"] diff --git a/crates/pathfinder/Cargo.toml b/crates/pathfinder/Cargo.toml index 4b83ea6e45..002a2711b2 100644 --- a/crates/pathfinder/Cargo.toml +++ b/crates/pathfinder/Cargo.toml @@ -14,7 +14,7 @@ path = "src/lib.rs" cairo-native = ["pathfinder-executor/cairo-native"] consensus-integration-tests = [] tokio-console = ["console-subscriber", "tokio/tracing"] -p2p = ["pathfinder-consensus"] +p2p = ["pathfinder-consensus", "pathfinder-validator/p2p"] [dependencies] anyhow = { workspace = true } @@ -55,6 +55,7 @@ pathfinder-retry = { path = "../retry" } pathfinder-rpc = { path = "../rpc" } pathfinder-serde = { path = "../serde" } pathfinder-storage = { path = "../storage" } +pathfinder-validator = { path = "../validator" } pathfinder-version = { path = "../version" } primitive-types = { workspace = true } rand = { workspace = true } diff --git a/crates/pathfinder/src/consensus.rs b/crates/pathfinder/src/consensus.rs index 390df7b4c0..0332167894 100644 --- a/crates/pathfinder/src/consensus.rs +++ b/crates/pathfinder/src/consensus.rs @@ -4,16 +4,13 @@ use p2p::consensus::Event; use pathfinder_common::{consensus_info, ChainId}; use pathfinder_gas_price::L1GasPriceProvider; use pathfinder_storage::Storage; +use pathfinder_validator::ValidatorWorkerPool; use tokio::sync::{mpsc, watch}; use crate::config::integration_testing::InjectFailureConfig; use crate::config::ConsensusConfig; -use crate::validator::ValidatorWorkerPool; use crate::SyncMessageToConsensus; -mod error; -pub use error::{ProposalError, ProposalHandlingError}; - #[cfg(feature = "p2p")] mod inner; diff --git a/crates/pathfinder/src/consensus/inner/batch_execution.rs b/crates/pathfinder/src/consensus/inner/batch_execution.rs index 796283e56c..8d4524ec8b 100644 --- a/crates/pathfinder/src/consensus/inner/batch_execution.rs +++ b/crates/pathfinder/src/consensus/inner/batch_execution.rs @@ -13,9 +13,8 @@ use p2p_proto::consensus as proto_consensus; use pathfinder_common::DecidedBlocks; use pathfinder_gas_price::{L1GasPriceProvider, L2GasPriceProvider}; use pathfinder_storage::Storage; - -use crate::consensus::ProposalHandlingError; -use crate::validator::{ +use pathfinder_validator::error::ProposalHandlingError; +use pathfinder_validator::{ should_defer_validation, TransactionExt, ValidatorStage, @@ -379,13 +378,13 @@ mod tests { use pathfinder_crypto::Felt; use pathfinder_executor::{ConcurrentStateReader, ExecutorWorkerPool}; use pathfinder_storage::StorageBuilder; + use pathfinder_validator::{ProdTransactionMapper, ValidatorBlockInfoStage}; use super::*; use crate::consensus::inner::dummy_proposal::{ create_test_proposal_init, create_transaction_batch, }; - use crate::validator::{ProdTransactionMapper, ValidatorBlockInfoStage}; /// Creates a worker pool for tests. fn create_test_worker_pool() -> ValidatorWorkerPool { diff --git a/crates/pathfinder/src/consensus/inner/dummy_proposal.rs b/crates/pathfinder/src/consensus/inner/dummy_proposal.rs index df743d3409..2fdc3892a2 100644 --- a/crates/pathfinder/src/consensus/inner/dummy_proposal.rs +++ b/crates/pathfinder/src/consensus/inner/dummy_proposal.rs @@ -22,11 +22,11 @@ use pathfinder_consensus::Round; use pathfinder_crypto::Felt; use pathfinder_executor::{ConcurrentStateReader, ExecutorWorkerPool}; use pathfinder_storage::Storage; +use pathfinder_validator::{ProdTransactionMapper, ValidatorBlockInfoStage}; use rand::seq::SliceRandom; use rand::{thread_rng, Rng, SeedableRng}; use crate::devnet::{self, strictly_increasing_timestamp, Account}; -use crate::validator::{ProdTransactionMapper, ValidatorBlockInfoStage}; // TODO consider waiting for the parent block to land in the decided blocks /// Blocks consensus tasks's processing loop until the parent block of height is diff --git a/crates/pathfinder/src/consensus/inner/p2p_task.rs b/crates/pathfinder/src/consensus/inner/p2p_task.rs index 785db06ded..d47db1678e 100644 --- a/crates/pathfinder/src/consensus/inner/p2p_task.rs +++ b/crates/pathfinder/src/consensus/inner/p2p_task.rs @@ -42,6 +42,15 @@ use pathfinder_consensus::{ use pathfinder_executor::{ConcurrentStateReader, ExecutorWorkerPool}; use pathfinder_gas_price::{L1GasPriceProvider, L2GasPriceConstants, L2GasPriceProvider}; use pathfinder_storage::{Storage, Transaction, TransactionBehavior}; +use pathfinder_validator::error::{ProposalError, ProposalHandlingError}; +use pathfinder_validator::{ + should_defer_validation, + ProdTransactionMapper, + TransactionExt, + ValidatorBlockInfoStage, + ValidatorStage, + ValidatorWorkerPool, +}; use tokio::sync::{mpsc, watch}; use super::gossip_retry::{GossipHandler, GossipRetryConfig}; @@ -54,15 +63,6 @@ use crate::consensus::inner::batch_execution::{ ProposalCommitmentWithOrigin, }; use crate::consensus::inner::create_empty_block; -use crate::consensus::{ProposalError, ProposalHandlingError}; -use crate::validator::{ - should_defer_validation, - ProdTransactionMapper, - TransactionExt, - ValidatorBlockInfoStage, - ValidatorStage, - ValidatorWorkerPool, -}; use crate::SyncMessageToConsensus; #[cfg(test)] @@ -427,8 +427,6 @@ pub fn spawn( use pathfinder_common::StateCommitment; use pathfinder_merkle_tree::starknet_state::update_starknet_state; - use crate::validator; - let starknet_version = block.header.starknet_version; let state_commitment = update_starknet_state( &main_db_tx, @@ -451,12 +449,12 @@ pub fn spawn( let resp = match state_commitment { Ok(state_commitment) => { if state_commitment == block.header.state_commitment { - validator::ValidationResult::Valid + pathfinder_validator::ValidationResult::Valid } else { - validator::ValidationResult::Invalid + pathfinder_validator::ValidationResult::Invalid } } - Err(e) => validator::ValidationResult::Error(e), + Err(e) => pathfinder_validator::ValidationResult::Error(e), }; reply @@ -1593,13 +1591,13 @@ mod tests { use pathfinder_crypto::Felt; use pathfinder_executor::{ConcurrentStateReader, ExecutorWorkerPool}; use pathfinder_storage::StorageBuilder; + use pathfinder_validator::ValidatorWorkerPool; use super::*; use crate::consensus::inner::dummy_proposal::{ create_with_invalid_l1_handler_transactions, ProposalCreationConfig, }; - use crate::validator::ValidatorWorkerPool; /// Creates a worker pool for tests. fn create_test_worker_pool() -> ValidatorWorkerPool { diff --git a/crates/pathfinder/src/consensus/inner/p2p_task/p2p_task_tests.rs b/crates/pathfinder/src/consensus/inner/p2p_task/p2p_task_tests.rs index 4ed523031c..7481d78e7e 100644 --- a/crates/pathfinder/src/consensus/inner/p2p_task/p2p_task_tests.rs +++ b/crates/pathfinder/src/consensus/inner/p2p_task/p2p_task_tests.rs @@ -26,6 +26,7 @@ use pathfinder_common::{ use pathfinder_consensus::ConsensusCommand; use pathfinder_crypto::Felt; use pathfinder_storage::{Storage, StorageBuilder}; +use pathfinder_validator::ValidatorWorkerPool; use tokio::sync::{mpsc, watch}; use tokio::time::error::Elapsed; use tokio::time::timeout; @@ -41,7 +42,6 @@ use crate::consensus::inner::{ P2PTaskConfig, P2PTaskEvent, }; -use crate::validator::ValidatorWorkerPool; use crate::SyncMessageToConsensus; /// Helper struct to setup and manage the test environment (databases, diff --git a/crates/pathfinder/src/consensus/inner/proposal_validator.rs b/crates/pathfinder/src/consensus/inner/proposal_validator.rs index 222ce0478e..067dc7fa1e 100644 --- a/crates/pathfinder/src/consensus/inner/proposal_validator.rs +++ b/crates/pathfinder/src/consensus/inner/proposal_validator.rs @@ -1,8 +1,7 @@ use p2p::consensus::HeightAndRound; use p2p_proto::consensus::{ProposalInit, ProposalPart}; use pathfinder_common::ContractAddress; - -use crate::consensus::{ProposalError, ProposalHandlingError}; +use pathfinder_validator::error::{ProposalError, ProposalHandlingError}; /// Validates the structure of incoming proposal parts and stores them. /// diff --git a/crates/pathfinder/src/devnet.rs b/crates/pathfinder/src/devnet.rs index 7aed0ee571..f15db4fbff 100644 --- a/crates/pathfinder/src/devnet.rs +++ b/crates/pathfinder/src/devnet.rs @@ -47,17 +47,17 @@ use pathfinder_executor::{ConcurrentStateReader, ExecutorWorkerPool}; use pathfinder_merkle_tree::starknet_state::update_starknet_state; use pathfinder_storage::pruning::BlockchainHistoryMode; use pathfinder_storage::{Storage, StorageBuilder, TriePruneMode}; - -pub use crate::devnet::account::Account; -use crate::devnet::class::{preprocess_sierra, PrepocessedSierra}; -use crate::devnet::fixtures::RESOURCE_BOUNDS; -use crate::validator::{ +use pathfinder_validator::{ ProdTransactionMapper, ValidatorBlockInfoStage, ValidatorTransactionBatchStage, ValidatorWorkerPool, }; +pub use crate::devnet::account::Account; +use crate::devnet::class::{preprocess_sierra, PrepocessedSierra}; +use crate::devnet::fixtures::RESOURCE_BOUNDS; + mod account; mod class; mod contract; @@ -440,11 +440,11 @@ pub mod tests { use pathfinder_executor::{ConcurrentStateReader, ExecutorWorkerPool}; use pathfinder_merkle_tree::starknet_state::update_starknet_state; use pathfinder_storage::{Storage, StorageBuilder}; + use pathfinder_validator::{ProdTransactionMapper, ValidatorWorkerPool}; use tempfile::TempDir; use crate::devnet::account::Account; use crate::devnet::{fixtures, init_db, init_proposal_and_validator, BootDb}; - use crate::validator::{ProdTransactionMapper, ValidatorWorkerPool}; #[test_log::test] fn init_declare_deploy_invoke_hello_abi() { diff --git a/crates/pathfinder/src/lib.rs b/crates/pathfinder/src/lib.rs index e0059ac4fd..a0a6a18542 100644 --- a/crates/pathfinder/src/lib.rs +++ b/crates/pathfinder/src/lib.rs @@ -7,8 +7,6 @@ pub mod monitoring; pub mod p2p_network; pub mod state; pub mod sync; -pub mod validator; - pub enum SyncMessageToConsensus { /// Ask consensus for the finalized and **decided upon** block with given /// number. The only difference from a committed block is that the state @@ -37,4 +35,4 @@ pub enum SyncMessageToConsensus { pub type ConsensusFinalizedBlockReply = tokio::sync::oneshot::Sender>>; -pub type ValidateBlockReply = tokio::sync::oneshot::Sender; +pub type ValidateBlockReply = tokio::sync::oneshot::Sender; diff --git a/crates/validator/src/lib.rs b/crates/validator/src/lib.rs index 4f9d383532..ef7e3972a9 100644 --- a/crates/validator/src/lib.rs +++ b/crates/validator/src/lib.rs @@ -277,7 +277,7 @@ impl ValidatorBlockInfoStage { /// /// Used only for testing and dummy proposal creation. #[cfg(any(test, feature = "p2p"))] - pub(crate) fn skip_validation( + pub fn skip_validation( self, block_info: BlockInfo, main_storage: Storage, From 8ac82504037bb8594a3ba34225ca24d9b9245037 Mon Sep 17 00:00:00 2001 From: t00ts Date: Wed, 15 Apr 2026 14:42:52 +0400 Subject: [PATCH 5/7] refactor(validator): p2p gate is unnecessary --- crates/pathfinder/Cargo.toml | 2 +- crates/validator/src/lib.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/pathfinder/Cargo.toml b/crates/pathfinder/Cargo.toml index 002a2711b2..37c76391b2 100644 --- a/crates/pathfinder/Cargo.toml +++ b/crates/pathfinder/Cargo.toml @@ -14,7 +14,7 @@ path = "src/lib.rs" cairo-native = ["pathfinder-executor/cairo-native"] consensus-integration-tests = [] tokio-console = ["console-subscriber", "tokio/tracing"] -p2p = ["pathfinder-consensus", "pathfinder-validator/p2p"] +p2p = ["pathfinder-consensus"] [dependencies] anyhow = { workspace = true } diff --git a/crates/validator/src/lib.rs b/crates/validator/src/lib.rs index ef7e3972a9..ce43da65e9 100644 --- a/crates/validator/src/lib.rs +++ b/crates/validator/src/lib.rs @@ -276,7 +276,6 @@ impl ValidatorBlockInfoStage { /// [ValidatorTransactionBatchStage]. /// /// Used only for testing and dummy proposal creation. - #[cfg(any(test, feature = "p2p"))] pub fn skip_validation( self, block_info: BlockInfo, From 77e6398d3db92f33187cacc6e9d3ba197c3a44a1 Mon Sep 17 00:00:00 2001 From: t00ts Date: Wed, 15 Apr 2026 16:42:29 +0400 Subject: [PATCH 6/7] fix(validator): tests not skipping proposal commitment validation --- crates/pathfinder/Cargo.toml | 1 + crates/validator/Cargo.toml | 3 +++ crates/validator/src/lib.rs | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/pathfinder/Cargo.toml b/crates/pathfinder/Cargo.toml index 37c76391b2..b3c4cf2895 100644 --- a/crates/pathfinder/Cargo.toml +++ b/crates/pathfinder/Cargo.toml @@ -92,6 +92,7 @@ pathfinder-compiler = { path = "../compiler" } pathfinder-executor = { path = "../executor" } pathfinder-rpc = { path = "../rpc" } pathfinder-storage = { path = "../storage", features = ["small_aggregate_filters"] } +pathfinder-validator = { path = "../validator", features = ["skip-commitment-validation"] } pretty_assertions_sorted = { workspace = true } proptest = { workspace = true } rstest = { workspace = true } diff --git a/crates/validator/Cargo.toml b/crates/validator/Cargo.toml index 69e43d5727..c790fbc25f 100644 --- a/crates/validator/Cargo.toml +++ b/crates/validator/Cargo.toml @@ -6,6 +6,9 @@ edition = { workspace = true } license = { workspace = true } rust-version = { workspace = true } +[features] +skip-commitment-validation = [] + [dependencies] anyhow = { workspace = true } p2p = { path = "../p2p" } diff --git a/crates/validator/src/lib.rs b/crates/validator/src/lib.rs index ce43da65e9..d253df99fe 100644 --- a/crates/validator/src/lib.rs +++ b/crates/validator/src/lib.rs @@ -768,7 +768,7 @@ impl ValidatorTransactionBatchStage { // Skip commitment validation in tests when using dummy commitment (ZERO) // This allows e2e tests to focus on batch execution logic without commitment // complexity - #[cfg(test)] + #[cfg(any(test, feature = "skip-commitment-validation"))] if expected_proposal_commitment.0.is_zero() { return Ok(block); } From 1af075c728da638055f70227e037a88148b174d7 Mon Sep 17 00:00:00 2001 From: t00ts Date: Thu, 16 Apr 2026 10:34:15 +0400 Subject: [PATCH 7/7] feat(validator): bring back `skip_validation()` guard behind `p2p` flag --- crates/pathfinder/Cargo.toml | 2 +- crates/validator/Cargo.toml | 1 + crates/validator/src/lib.rs | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/pathfinder/Cargo.toml b/crates/pathfinder/Cargo.toml index b3c4cf2895..08a2a5334b 100644 --- a/crates/pathfinder/Cargo.toml +++ b/crates/pathfinder/Cargo.toml @@ -14,7 +14,7 @@ path = "src/lib.rs" cairo-native = ["pathfinder-executor/cairo-native"] consensus-integration-tests = [] tokio-console = ["console-subscriber", "tokio/tracing"] -p2p = ["pathfinder-consensus"] +p2p = ["pathfinder-consensus", "pathfinder-validator/p2p"] [dependencies] anyhow = { workspace = true } diff --git a/crates/validator/Cargo.toml b/crates/validator/Cargo.toml index c790fbc25f..ee56e9b9ba 100644 --- a/crates/validator/Cargo.toml +++ b/crates/validator/Cargo.toml @@ -7,6 +7,7 @@ license = { workspace = true } rust-version = { workspace = true } [features] +p2p = [] skip-commitment-validation = [] [dependencies] diff --git a/crates/validator/src/lib.rs b/crates/validator/src/lib.rs index d253df99fe..6084e14466 100644 --- a/crates/validator/src/lib.rs +++ b/crates/validator/src/lib.rs @@ -276,6 +276,7 @@ impl ValidatorBlockInfoStage { /// [ValidatorTransactionBatchStage]. /// /// Used only for testing and dummy proposal creation. + #[cfg(any(test, feature = "p2p"))] pub fn skip_validation( self, block_info: BlockInfo,