Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PVF: include host architecture in artifact filenames #2871

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions polkadot/node/core/candidate-validation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ pub struct Config {
pub node_version: Option<String>,
/// Whether the node is attempting to run as a secure validator.
pub secure_validator_mode: bool,
/// The architecture of the current host.
pub architecture: String,
/// Path to the preparation worker binary
pub prep_worker_path: PathBuf,
/// Path to the execution worker binary
Expand Down Expand Up @@ -139,6 +141,7 @@ async fn run<Context>(
artifacts_cache_path,
node_version,
secure_validator_mode,
architecture,
prep_worker_path,
exec_worker_path,
}: Config,
Expand All @@ -148,6 +151,7 @@ async fn run<Context>(
artifacts_cache_path,
node_version,
secure_validator_mode,
architecture.clone(),
prep_worker_path,
exec_worker_path,
),
Expand All @@ -157,6 +161,7 @@ async fn run<Context>(
ctx.spawn_blocking("pvf-validation-host", task.boxed())?;

loop {
let architecture = architecture.clone();
match ctx.recv().await? {
FromOrchestra::Signal(OverseerSignal::ActiveLeaves(_)) => {},
FromOrchestra::Signal(OverseerSignal::BlockFinalized(..)) => {},
Expand Down Expand Up @@ -184,6 +189,7 @@ async fn run<Context>(
pov,
executor_params,
exec_kind,
architecture,
&metrics,
)
.await;
Expand Down Expand Up @@ -219,6 +225,7 @@ async fn run<Context>(
pov,
executor_params,
exec_kind,
architecture,
&metrics,
)
.await;
Expand Down Expand Up @@ -246,6 +253,7 @@ async fn run<Context>(
validation_host,
relay_parent,
validation_code_hash,
architecture,
)
.await;

Expand Down Expand Up @@ -319,6 +327,7 @@ async fn precheck_pvf<Sender>(
mut validation_backend: impl ValidationBackend,
relay_parent: Hash,
validation_code_hash: ValidationCodeHash,
architecture: String,
) -> PreCheckOutcome
where
Sender: SubsystemSender<RuntimeApiMessage>,
Expand Down Expand Up @@ -366,11 +375,12 @@ where
&validation_code.0,
VALIDATION_CODE_BOMB_LIMIT,
) {
Ok(code) => PvfPrepData::from_code(
Ok(code) => PvfPrepData::new(
code.into_owned(),
executor_params,
timeout,
PrepareJobKind::Prechecking,
architecture,
),
Err(e) => {
gum::debug!(target: LOG_TARGET, err=?e, "precheck: cannot decompress validation code");
Expand Down Expand Up @@ -505,6 +515,7 @@ async fn validate_from_chain_state<Sender>(
pov: Arc<PoV>,
executor_params: ExecutorParams,
exec_kind: PvfExecKind,
architecture: String,
metrics: &Metrics,
) -> Result<ValidationResult, ValidationFailed>
where
Expand All @@ -525,6 +536,7 @@ where
pov,
executor_params,
exec_kind,
architecture,
metrics,
)
.await;
Expand Down Expand Up @@ -561,6 +573,7 @@ async fn validate_candidate_exhaustive(
pov: Arc<PoV>,
executor_params: ExecutorParams,
exec_kind: PvfExecKind,
architecture: String,
metrics: &Metrics,
) -> Result<ValidationResult, ValidationFailed> {
let _timer = metrics.time_validate_candidate_exhaustive();
Expand Down Expand Up @@ -625,11 +638,12 @@ async fn validate_candidate_exhaustive(
PvfExecKind::Backing => {
let prep_timeout = pvf_prep_timeout(&executor_params, PvfPrepKind::Prepare);
let exec_timeout = pvf_exec_timeout(&executor_params, exec_kind);
let pvf = PvfPrepData::from_code(
let pvf = PvfPrepData::new(
raw_validation_code.to_vec(),
executor_params,
prep_timeout,
PrepareJobKind::Compilation,
architecture,
);

validation_backend.validate_candidate(pvf, exec_timeout, params.encode()).await
Expand All @@ -641,6 +655,7 @@ async fn validate_candidate_exhaustive(
pvf_exec_timeout(&executor_params, exec_kind),
params,
executor_params,
architecture,
PVF_APPROVAL_EXECUTION_RETRY_DELAY,
)
.await,
Expand Down Expand Up @@ -735,15 +750,17 @@ trait ValidationBackend {
exec_timeout: Duration,
params: ValidationParams,
executor_params: ExecutorParams,
architecture: String,
retry_delay: Duration,
) -> Result<WasmValidationResult, ValidationError> {
let prep_timeout = pvf_prep_timeout(&executor_params, PvfPrepKind::Prepare);
// Construct the PVF a single time, since it is an expensive operation. Cloning it is cheap.
let pvf = PvfPrepData::from_code(
let pvf = PvfPrepData::new(
raw_validation_code,
executor_params,
prep_timeout,
PrepareJobKind::Compilation,
architecture,
);
// We keep track of the total time that has passed and stop retrying if we are taking too
// long.
Expand Down
14 changes: 14 additions & 0 deletions polkadot/node/core/pvf/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,17 @@ pub fn framed_recv_blocking(r: &mut (impl Read + Unpin)) -> io::Result<Vec<u8>>
r.read_exact(&mut buf)?;
Ok(buf)
}

/// Calls `uname` to get the host architecture. Example output: "Linux-x86_64".
#[cfg(feature = "test-utils")]
pub fn test_get_host_architecture() -> String {
let uname = std::process::Command::new("uname")
.arg("-ms")
.output()
.expect("uname should not fail in tests")
.stdout;
std::str::from_utf8(&uname)
.expect("uname output is printed as an ASCII string; qed")
.trim()
.replace(" ", "-")
}
15 changes: 12 additions & 3 deletions polkadot/node/core/pvf/common/src/pvf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,23 @@ pub struct PvfPrepData {
prep_timeout: Duration,
/// The kind of preparation job.
prep_kind: PrepareJobKind,
/// The host architecture.
architecture: String,
}

impl PvfPrepData {
/// Returns an instance of the PVF out of the given PVF code and executor params.
pub fn from_code(
pub fn new(
code: Vec<u8>,
executor_params: ExecutorParams,
prep_timeout: Duration,
prep_kind: PrepareJobKind,
architecture: String,
) -> Self {
let code = Arc::new(code);
let code_hash = blake2_256(&code).into();
let executor_params = Arc::new(executor_params);
Self { code, code_hash, executor_params, prep_timeout, prep_kind }
Self { code, code_hash, executor_params, prep_timeout, prep_kind, architecture }
}

/// Returns validation code hash for the PVF
Expand Down Expand Up @@ -83,15 +86,21 @@ impl PvfPrepData {
self.prep_kind
}

/// Returns host architecture.
pub fn architecture(&self) -> &str {
&self.architecture
}

/// Creates a structure for tests.
#[cfg(feature = "test-utils")]
pub fn from_discriminator_and_timeout(num: u32, timeout: Duration) -> Self {
let descriminator_buf = num.to_le_bytes().to_vec();
Self::from_code(
Self::new(
descriminator_buf,
ExecutorParams::default(),
timeout,
PrepareJobKind::Compilation,
crate::test_get_host_architecture(),
)
}

Expand Down
Loading
Loading