-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Check artifact integrity before execution #8833
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
Changes from all commits
f1e4aab
dedc1db
b8bb9b9
5b0b8cf
e4afb12
f190420
b0c5b97
dd97469
16cd982
aa5421a
1ed46f5
0c6c56d
9afc8a0
b81d551
2bf8a2f
fd83516
ada5913
8e4b0c4
c2b7463
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,6 +39,7 @@ use nix::{ | |
| unistd::{ForkResult, Pid}, | ||
| }; | ||
| use polkadot_node_core_pvf_common::{ | ||
| compute_checksum, | ||
| error::InternalValidationError, | ||
| execute::{Handshake, JobError, JobResponse, JobResult, WorkerError, WorkerResponse}, | ||
| executor_interface::params_to_wasmtime_semantics, | ||
|
|
@@ -49,7 +50,7 @@ use polkadot_node_core_pvf_common::{ | |
| thread::{self, WaitOutcome}, | ||
| PipeFd, WorkerInfo, WorkerKind, | ||
| }, | ||
| worker_dir, | ||
| worker_dir, ArtifactChecksum, | ||
| }; | ||
| use polkadot_node_primitives::{BlockData, PoV, POV_BOMB_LIMIT}; | ||
| use polkadot_parachain_primitives::primitives::ValidationResult; | ||
|
|
@@ -87,7 +88,9 @@ fn recv_execute_handshake(stream: &mut UnixStream) -> io::Result<Handshake> { | |
| Ok(handshake) | ||
| } | ||
|
|
||
| fn recv_request(stream: &mut UnixStream) -> io::Result<(PersistedValidationData, PoV, Duration)> { | ||
| fn recv_request( | ||
| stream: &mut UnixStream, | ||
| ) -> io::Result<(PersistedValidationData, PoV, Duration, ArtifactChecksum)> { | ||
| let pvd = framed_recv_blocking(stream)?; | ||
| let pvd = PersistedValidationData::decode(&mut &pvd[..]).map_err(|_| { | ||
| io::Error::new( | ||
|
|
@@ -111,7 +114,17 @@ fn recv_request(stream: &mut UnixStream) -> io::Result<(PersistedValidationData, | |
| "execute pvf recv_request: failed to decode duration".to_string(), | ||
| ) | ||
| })?; | ||
| Ok((pvd, pov, execution_timeout)) | ||
|
|
||
| let artifact_checksum = framed_recv_blocking(stream)?; | ||
| let artifact_checksum = | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm NOT encouraging to change this right away, but...
Maybe a good candidate for a refactoring issue? I bet single
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's do it in another pr |
||
| ArtifactChecksum::decode(&mut &artifact_checksum[..]).map_err(|_| { | ||
| io::Error::new( | ||
| io::ErrorKind::Other, | ||
| "execute pvf recv_request: failed to decode artifact checksum".to_string(), | ||
| ) | ||
| })?; | ||
|
|
||
| Ok((pvd, pov, execution_timeout, artifact_checksum)) | ||
| } | ||
|
|
||
| /// Sends an error to the host and returns the original error wrapped in `io::Error`. | ||
|
|
@@ -166,14 +179,15 @@ pub fn worker_entrypoint( | |
| let execute_thread_stack_size = max_stack_size(&executor_params); | ||
|
|
||
| loop { | ||
| let (pvd, pov, execution_timeout) = recv_request(&mut stream).map_err(|e| { | ||
| map_and_send_err!( | ||
| e, | ||
| InternalValidationError::HostCommunication, | ||
| &mut stream, | ||
| worker_info | ||
| ) | ||
| })?; | ||
| let (pvd, pov, execution_timeout, artifact_checksum) = recv_request(&mut stream) | ||
| .map_err(|e| { | ||
| map_and_send_err!( | ||
| e, | ||
| InternalValidationError::HostCommunication, | ||
| &mut stream, | ||
| worker_info | ||
| ) | ||
| })?; | ||
| gum::debug!( | ||
| target: LOG_TARGET, | ||
| ?worker_info, | ||
|
|
@@ -192,6 +206,19 @@ pub fn worker_entrypoint( | |
| ) | ||
| })?; | ||
|
|
||
| if artifact_checksum != compute_checksum(&compiled_artifact_blob) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How much does this take for 10MiB, 100MiB ?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Blake3's throughput is ~3Gb/sec on what is close to our reference hw AFAIR
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to the crate's benchmark data, 10 MiB with Blake3 takes 1-2 ms. Twox should be at least 3x faster.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, so we are not worried about this eating up too much time. |
||
| send_result::<WorkerResponse, WorkerError>( | ||
| &mut stream, | ||
| Ok(WorkerResponse { | ||
| job_response: JobResponse::CorruptedArtifact, | ||
| duration: Duration::ZERO, | ||
| pov_size: 0, | ||
| }), | ||
| worker_info, | ||
| )?; | ||
| continue; | ||
| } | ||
|
|
||
| let (pipe_read_fd, pipe_write_fd) = pipe2_cloexec().map_err(|e| { | ||
| map_and_send_err!( | ||
| e, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,6 +26,7 @@ const LOG_TARGET: &str = "parachain::pvf-prepare-worker"; | |
| use crate::memory_stats::max_rss_stat::{extract_max_rss_stat, get_max_rss_thread}; | ||
| #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] | ||
| use crate::memory_stats::memory_tracker::{get_memory_tracker_loop_stats, memory_tracker_loop}; | ||
| use codec::{Decode, Encode}; | ||
| use nix::{ | ||
| errno::Errno, | ||
| sys::{ | ||
|
|
@@ -35,22 +36,17 @@ use nix::{ | |
| unistd::{ForkResult, Pid}, | ||
| }; | ||
| use polkadot_node_core_pvf_common::{ | ||
| executor_interface::{prepare, prevalidate}, | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks messy, but I just merged two imports of |
||
| worker::{pipe2_cloexec, PipeFd, WorkerInfo}, | ||
| }; | ||
|
|
||
| use codec::{Decode, Encode}; | ||
| use polkadot_node_core_pvf_common::{ | ||
| compute_checksum, | ||
| error::{PrepareError, PrepareWorkerResult}, | ||
| executor_interface::create_runtime_from_artifact_bytes, | ||
| executor_interface::{create_runtime_from_artifact_bytes, prepare, prevalidate}, | ||
| framed_recv_blocking, framed_send_blocking, | ||
| prepare::{MemoryStats, PrepareJobKind, PrepareStats, PrepareWorkerSuccess}, | ||
| pvf::PvfPrepData, | ||
| worker::{ | ||
| cpu_time_monitor_loop, get_total_cpu_usage, recv_child_response, run_worker, send_result, | ||
| stringify_errno, stringify_panic_payload, | ||
| cpu_time_monitor_loop, get_total_cpu_usage, pipe2_cloexec, recv_child_response, run_worker, | ||
| send_result, stringify_errno, stringify_panic_payload, | ||
| thread::{self, spawn_worker_thread, WaitOutcome}, | ||
| WorkerKind, | ||
| PipeFd, WorkerInfo, WorkerKind, | ||
| }, | ||
| worker_dir, ProcessTime, | ||
| }; | ||
|
|
@@ -718,7 +714,7 @@ fn handle_parent_process( | |
| return Err(PrepareError::IoErr(err.to_string())) | ||
| }; | ||
|
|
||
| let checksum = blake3::hash(&artifact.as_ref()).to_hex().to_string(); | ||
| let checksum = compute_checksum(&artifact.as_ref()); | ||
| Ok(PrepareWorkerSuccess { | ||
| checksum, | ||
| stats: PrepareStats { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.