Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 42eb3ce

Browse files
authored
Forwardport: Validation: don't detect STDIN closing when running in process (#1695) (#1703)
* Initial commit Forked at: d04e449 Parent branch: origin/master * Validation: don't detect STDIN closing when running in process (#1695)
1 parent d04e449 commit 42eb3ce

File tree

5 files changed

+137
-124
lines changed

5 files changed

+137
-124
lines changed

node/core/candidate-validation/src/lib.rs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use polkadot_primitives::v1::{
3737
};
3838
use polkadot_parachain::wasm_executor::{
3939
self, ValidationPool, ExecutionMode, ValidationError,
40-
InvalidCandidate as WasmInvalidCandidate, ValidationExecutionMode,
40+
InvalidCandidate as WasmInvalidCandidate,
4141
};
4242
use polkadot_parachain::primitives::{ValidationResult as WasmValidationResult, ValidationParams};
4343

@@ -130,7 +130,7 @@ async fn run(
130130
)
131131
-> SubsystemResult<()>
132132
{
133-
let pool = ValidationPool::new(ValidationExecutionMode::ExternalProcessSelfHost);
133+
let execution_mode = ExecutionMode::ExternalProcessSelfHost(ValidationPool::new());
134134

135135
loop {
136136
match ctx.recv().await? {
@@ -145,7 +145,7 @@ async fn run(
145145
) => {
146146
let res = spawn_validate_from_chain_state(
147147
&mut ctx,
148-
Some(pool.clone()),
148+
execution_mode.clone(),
149149
descriptor,
150150
pov,
151151
spawn.clone(),
@@ -169,7 +169,7 @@ async fn run(
169169
) => {
170170
let res = spawn_validate_exhaustive(
171171
&mut ctx,
172-
Some(pool.clone()),
172+
execution_mode.clone(),
173173
persisted_validation_data,
174174
transient_validation_data,
175175
validation_code,
@@ -271,7 +271,7 @@ async fn check_assumption_validation_data(
271271

272272
async fn spawn_validate_from_chain_state(
273273
ctx: &mut impl SubsystemContext<Message = CandidateValidationMessage>,
274-
validation_pool: Option<ValidationPool>,
274+
execution_mode: ExecutionMode,
275275
descriptor: CandidateDescriptor,
276276
pov: Arc<PoV>,
277277
spawn: impl SpawnNamed + 'static,
@@ -288,7 +288,7 @@ async fn spawn_validate_from_chain_state(
288288
AssumptionCheckOutcome::Matches(validation_data, validation_code) => {
289289
return spawn_validate_exhaustive(
290290
ctx,
291-
validation_pool,
291+
execution_mode,
292292
validation_data.persisted,
293293
Some(validation_data.transient),
294294
validation_code,
@@ -309,7 +309,7 @@ async fn spawn_validate_from_chain_state(
309309
AssumptionCheckOutcome::Matches(validation_data, validation_code) => {
310310
return spawn_validate_exhaustive(
311311
ctx,
312-
validation_pool,
312+
execution_mode,
313313
validation_data.persisted,
314314
Some(validation_data.transient),
315315
validation_code,
@@ -330,7 +330,7 @@ async fn spawn_validate_from_chain_state(
330330

331331
async fn spawn_validate_exhaustive(
332332
ctx: &mut impl SubsystemContext<Message = CandidateValidationMessage>,
333-
validation_pool: Option<ValidationPool>,
333+
execution_mode: ExecutionMode,
334334
persisted_validation_data: PersistedValidationData,
335335
transient_validation_data: Option<TransientValidationData>,
336336
validation_code: ValidationCode,
@@ -341,7 +341,7 @@ async fn spawn_validate_exhaustive(
341341
let (tx, rx) = oneshot::channel();
342342
let fut = async move {
343343
let res = validate_candidate_exhaustive::<RealValidationBackend, _>(
344-
validation_pool,
344+
execution_mode,
345345
persisted_validation_data,
346346
transient_validation_data,
347347
validation_code,
@@ -422,22 +422,18 @@ trait ValidationBackend {
422422
struct RealValidationBackend;
423423

424424
impl ValidationBackend for RealValidationBackend {
425-
type Arg = Option<ValidationPool>;
425+
type Arg = ExecutionMode;
426426

427427
fn validate<S: SpawnNamed + 'static>(
428-
pool: Option<ValidationPool>,
428+
execution_mode: ExecutionMode,
429429
validation_code: &ValidationCode,
430430
params: ValidationParams,
431431
spawn: S,
432432
) -> Result<WasmValidationResult, ValidationError> {
433-
let execution_mode = pool.as_ref()
434-
.map(ExecutionMode::Remote)
435-
.unwrap_or(ExecutionMode::Local);
436-
437433
wasm_executor::validate_candidate(
438434
&validation_code.0,
439435
params,
440-
execution_mode,
436+
&execution_mode,
441437
spawn,
442438
)
443439
}

parachain/src/wasm_executor/mod.rs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@
2020
//! Assuming the parameters are correct, this module provides a wrapper around
2121
//! a WASM VM for re-execution of a parachain candidate.
2222
23-
use std::any::{TypeId, Any};
23+
use std::{any::{TypeId, Any}, path::PathBuf};
2424
use crate::primitives::{ValidationParams, ValidationResult};
2525
use codec::{Decode, Encode};
2626
use sp_core::{storage::{ChildInfo, TrackedStorageKey}, traits::{CallInWasm, SpawnNamed}};
2727
use sp_externalities::Extensions;
2828
use sp_wasm_interface::HostFunctions as _;
2929

3030
#[cfg(not(any(target_os = "android", target_os = "unknown")))]
31-
pub use validation_host::{run_worker, ValidationPool, EXECUTION_TIMEOUT_SEC, ValidationExecutionMode};
31+
pub use validation_host::{run_worker, ValidationPool, EXECUTION_TIMEOUT_SEC, WORKER_ARGS};
3232

3333
mod validation_host;
3434

@@ -58,16 +58,29 @@ pub fn run_worker(_: &str) -> Result<(), String> {
5858
Err("Cannot run validation worker on this platform".to_string())
5959
}
6060

61-
/// WASM code execution mode.
62-
///
63-
/// > Note: When compiling for WASM, the `Remote` variants are not available.
64-
pub enum ExecutionMode<'a> {
65-
/// Execute in-process. The execution can not be interrupted or aborted.
66-
Local,
67-
/// Remote execution in a spawned process.
68-
Remote(&'a ValidationPool),
61+
/// The execution mode for the `ValidationPool`.
62+
#[derive(Clone)]
63+
#[cfg_attr(not(any(target_os = "android", target_os = "unknown")), derive(Debug))]
64+
pub enum ExecutionMode {
65+
/// The validation worker is ran in a thread inside the same process.
66+
InProcess,
67+
/// The validation worker is ran using the process' executable and the subcommand `validation-worker` is passed
68+
/// following by the address of the shared memory.
69+
ExternalProcessSelfHost(ValidationPool),
70+
/// The validation worker is ran using the command provided and the argument provided. The address of the shared
71+
/// memory is added at the end of the arguments.
72+
ExternalProcessCustomHost {
73+
/// Validation pool.
74+
pool: ValidationPool,
75+
/// Path to the validation worker. The file must exists and be executable.
76+
binary: PathBuf,
77+
/// List of arguments passed to the validation worker. The address of the shared memory will be automatically
78+
/// added after the arguments.
79+
args: Vec<String>,
80+
},
6981
}
7082

83+
7184
#[derive(Debug, derive_more::Display, derive_more::From)]
7285
/// Candidate validation error.
7386
pub enum ValidationError {
@@ -132,19 +145,24 @@ impl std::error::Error for ValidationError {
132145
pub fn validate_candidate(
133146
validation_code: &[u8],
134147
params: ValidationParams,
135-
options: ExecutionMode<'_>,
148+
execution_mode: &ExecutionMode,
136149
spawner: impl SpawnNamed + 'static,
137150
) -> Result<ValidationResult, ValidationError> {
138-
match options {
139-
ExecutionMode::Local => {
151+
match execution_mode {
152+
ExecutionMode::InProcess => {
140153
validate_candidate_internal(validation_code, &params.encode(), spawner)
141154
},
142155
#[cfg(not(any(target_os = "android", target_os = "unknown")))]
143-
ExecutionMode::Remote(pool) => {
156+
ExecutionMode::ExternalProcessSelfHost(pool) => {
144157
pool.validate_candidate(validation_code, params)
145158
},
159+
#[cfg(not(any(target_os = "android", target_os = "unknown")))]
160+
ExecutionMode::ExternalProcessCustomHost { pool, binary, args } => {
161+
let args: Vec<&str> = args.iter().map(|x| x.as_str()).collect();
162+
pool.validate_candidate_custom(validation_code, params, binary, &args)
163+
},
146164
#[cfg(any(target_os = "android", target_os = "unknown"))]
147-
ExecutionMode::Remote(_pool) =>
165+
ExecutionMode::ExternalProcessSelfHost(_) | ExecutionMode::ExternalProcessCustomHost { .. } =>
148166
Err(ValidationError::Internal(InternalError::System(
149167
Box::<dyn std::error::Error + Send + Sync>::from(
150168
"Remote validator not available".to_string()

0 commit comments

Comments
 (0)