diff --git a/runtime/parachains/src/paras/mod.rs b/runtime/parachains/src/paras/mod.rs index f10c642a6dcb..538a0fe2d060 100644 --- a/runtime/parachains/src/paras/mod.rs +++ b/runtime/parachains/src/paras/mod.rs @@ -512,6 +512,9 @@ pub mod pallet { PvfCheckDoubleVote, /// The given PVF does not exist at the moment of process a vote. PvfCheckSubjectInvalid, + /// The PVF pre-checking statement cannot be included since the PVF pre-checking mechanism + /// is disabled. + PvfCheckDisabled, } /// All currently active PVF pre-checking votes. @@ -875,6 +878,13 @@ pub mod pallet { signature: ValidatorSignature, ) -> DispatchResult { ensure_none(origin)?; + + // Make sure that PVF pre-checking is enabled. + ensure!( + configuration::Pallet::::config().pvf_checking_enabled, + Error::::PvfCheckDisabled, + ); + let validators = shared::Pallet::::active_validator_keys(); let current_session = shared::Pallet::::session_index(); if stmt.session_index < current_session { @@ -957,6 +967,10 @@ pub mod pallet { _ => return InvalidTransaction::Call.into(), }; + if !configuration::Pallet::::config().pvf_checking_enabled { + return InvalidTransaction::Custom(INVALID_TX_PVF_CHECK_DISABLED).into() + } + let current_session = shared::Pallet::::session_index(); if stmt.session_index < current_session { return InvalidTransaction::Stale.into() @@ -1017,6 +1031,7 @@ pub mod pallet { const INVALID_TX_BAD_VALIDATOR_IDX: u8 = 1; const INVALID_TX_BAD_SUBJECT: u8 = 2; const INVALID_TX_DOUBLE_VOTE: u8 = 3; +const INVALID_TX_PVF_CHECK_DISABLED: u8 = 4; impl Pallet { /// Called by the initializer to initialize the paras pallet. diff --git a/runtime/parachains/src/paras/tests.rs b/runtime/parachains/src/paras/tests.rs index e7972c067e3a..eb0bd6008399 100644 --- a/runtime/parachains/src/paras/tests.rs +++ b/runtime/parachains/src/paras/tests.rs @@ -1214,6 +1214,47 @@ fn pvf_check_upgrade_reject() { }); } +#[test] +fn pvf_check_submit_vote_while_disabled() { + let genesis_config = MockGenesisConfig { + configuration: crate::configuration::GenesisConfig { + config: HostConfiguration { pvf_checking_enabled: false, ..Default::default() }, + ..Default::default() + }, + ..Default::default() + }; + + new_test_ext(genesis_config).execute_with(|| { + // This will set the session index to 1 and seed the validators. + run_to_block(1, Some(vec![1])); + + let stmt = PvfCheckStatement { + accept: false, + subject: ValidationCode(vec![1, 2, 3]).hash(), + session_index: 1, + validator_index: 1.into(), + }; + + let signature: ValidatorSignature = + Sr25519Keyring::Alice.sign(&stmt.signing_payload()).into(); + + let call = + Call::include_pvf_check_statement { stmt: stmt.clone(), signature: signature.clone() }; + + let validate_unsigned = + ::validate_unsigned(TransactionSource::InBlock, &call); + assert_eq!( + validate_unsigned, + InvalidTransaction::Custom(INVALID_TX_PVF_CHECK_DISABLED).into() + ); + + assert_err!( + Paras::include_pvf_check_statement(None.into(), stmt.clone(), signature.clone()), + Error::::PvfCheckDisabled + ); + }); +} + #[test] fn pvf_check_submit_vote() { let code_a: ValidationCode = vec![3, 2, 1].into();