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

Build workers for testing on demand #2018

Merged
merged 6 commits into from
Nov 1, 2023
Merged
Changes from 3 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
63 changes: 53 additions & 10 deletions polkadot/node/core/pvf/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,34 @@ pub fn validate_candidate(
pub fn get_and_check_worker_paths() -> (PathBuf, PathBuf) {
mrcnski marked this conversation as resolved.
Show resolved Hide resolved
// Only needs to be called once for the current process.
static WORKER_PATHS: OnceLock<Mutex<(PathBuf, PathBuf)>> = OnceLock::new();

fn maybe_build_workers(build_prep: bool, build_exec: bool) {
let mut build_args = vec!["build"];
if build_prep {
build_args.push("--bin=polkadot-prepare-worker");
}
if build_exec {
build_args.push("--bin=polkadot-execute-worker");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to simplify this and always build both workers, getting rid of the build_* arguments? I think it'd be rather rare for one to be up-to-date, but not the other. Plus, if something is already built, cargo will skip building it again.

Maybe we could always try to build the workers. That would also satisfy my request here and it's simpler than doing a version check. The version check with the commit hash would only work if you've made a commit since the last build. But if you've changed code without committing, the version check would still pass without a rebuild being requested.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I was also thinking about the same. However, then we should probably entirely drop any checking of versions or whatever and just build them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me test it out.


if build_prep || build_exec {
eprintln!("Building workers...");

// ensure the build targets are available
let mut dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
if !dir.ends_with("polkadot-sdk") {
dir.pop();
}
mrcnski marked this conversation as resolved.
Show resolved Hide resolved

std::process::Command::new("cargo")
mrcnski marked this conversation as resolved.
Show resolved Hide resolved
.args(build_args)
.stdout(std::process::Stdio::piped())
.current_dir(dir)
.status()
.expect("Failed to run the build program");
mrcnski marked this conversation as resolved.
Show resolved Hide resolved
}
}

let mutex = WORKER_PATHS.get_or_init(|| {
let mut workers_path = std::env::current_exe().unwrap();
workers_path.pop();
Expand All @@ -71,22 +99,37 @@ pub fn get_and_check_worker_paths() -> (PathBuf, PathBuf) {
let mut execute_worker_path = workers_path.clone();
execute_worker_path.push(EXECUTE_BINARY_NAME);

let mut build_prep = false;
let mut build_exec = false;

// Check that the workers are valid.
if !prepare_worker_path.is_executable() || !execute_worker_path.is_executable() {
panic!("ERROR: Workers do not exist or are not executable. Workers directory: {:?}", workers_path);

if !prepare_worker_path.is_executable() {
eprintln!("Prepare worker does not exist or is not executable. Workers directory: {:?}", workers_path);
build_prep = true;
}

if !execute_worker_path.is_executable() {
eprintln!("Execute worker does not exist or is not executable. Workers directory: {:?}", workers_path);
build_exec = true;
}

let worker_version =
get_worker_version(&prepare_worker_path).expect("checked for worker existence");
if worker_version != NODE_VERSION {
panic!("ERROR: Prepare worker version {worker_version} does not match node version {NODE_VERSION}; worker path: {prepare_worker_path:?}");
if let Ok(ver) = get_worker_version(&prepare_worker_path) {
if ver != NODE_VERSION {
eprintln!("Prepare worker version {ver} does not match node version {NODE_VERSION}; worker path: {prepare_worker_path:?}");
build_prep = true;
}
}
let worker_version =
get_worker_version(&execute_worker_path).expect("checked for worker existence");
if worker_version != NODE_VERSION {
panic!("ERROR: Execute worker version {worker_version} does not match node version {NODE_VERSION}; worker path: {execute_worker_path:?}");

if let Ok(ver) = get_worker_version(&execute_worker_path) {
if ver != NODE_VERSION {
eprintln!("Execute worker version {ver} does not match node version {NODE_VERSION}; worker path: {execute_worker_path:?}");
build_exec = true;
}
}

maybe_build_workers(build_prep, build_exec);

// We don't want to check against the commit hash because we'd have to always rebuild
// the calling crate on every commit.
eprintln!("WARNING: Workers match the node version, but may have changed in recent commits. Please rebuild them if anything funny happens. Workers path: {workers_path:?}");
Expand Down