mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-15 19:41:05 +00:00
PVF: more filesystem sandboxing (#1373)
This commit is contained in:
@@ -100,7 +100,7 @@ async fn execute_bad_block_on_parent() {
|
||||
|
||||
let host = TestHost::new();
|
||||
|
||||
let _ret = host
|
||||
let _err = host
|
||||
.validate_candidate(
|
||||
adder::wasm_binary_unwrap(),
|
||||
ValidationParams {
|
||||
@@ -145,3 +145,37 @@ async fn stress_spawn() {
|
||||
|
||||
futures::future::join_all((0..100).map(|_| execute(host.clone()))).await;
|
||||
}
|
||||
|
||||
// With one worker, run multiple execution jobs serially. They should not conflict.
|
||||
#[tokio::test]
|
||||
async fn execute_can_run_serially() {
|
||||
let host = std::sync::Arc::new(TestHost::new_with_config(|cfg| {
|
||||
cfg.execute_workers_max_num = 1;
|
||||
}));
|
||||
|
||||
async fn execute(host: std::sync::Arc<TestHost>) {
|
||||
let parent_head = HeadData { number: 0, parent_hash: [0; 32], post_state: hash_state(0) };
|
||||
let block_data = BlockData { state: 0, add: 512 };
|
||||
let ret = host
|
||||
.validate_candidate(
|
||||
adder::wasm_binary_unwrap(),
|
||||
ValidationParams {
|
||||
parent_head: GenericHeadData(parent_head.encode()),
|
||||
block_data: GenericBlockData(block_data.encode()),
|
||||
relay_parent_number: 1,
|
||||
relay_parent_storage_root: Default::default(),
|
||||
},
|
||||
Default::default(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let new_head = HeadData::decode(&mut &ret.head_data.0[..]).unwrap();
|
||||
|
||||
assert_eq!(new_head.number, 1);
|
||||
assert_eq!(new_head.parent_hash, parent_head.hash());
|
||||
assert_eq!(new_head.post_state, hash_state(512));
|
||||
}
|
||||
|
||||
futures::future::join_all((0..5).map(|_| execute(host.clone()))).await;
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
use assert_matches::assert_matches;
|
||||
use parity_scale_codec::Encode as _;
|
||||
use polkadot_node_core_pvf::{
|
||||
start, Config, InvalidCandidate, Metrics, PrepareJobKind, PvfPrepData, ValidationError,
|
||||
ValidationHost, JOB_TIMEOUT_WALL_CLOCK_FACTOR,
|
||||
start, Config, InvalidCandidate, Metrics, PrepareError, PrepareJobKind, PrepareStats,
|
||||
PvfPrepData, ValidationError, ValidationHost, JOB_TIMEOUT_WALL_CLOCK_FACTOR,
|
||||
};
|
||||
use polkadot_parachain_primitives::primitives::{BlockData, ValidationParams, ValidationResult};
|
||||
use polkadot_primitives::ExecutorParams;
|
||||
@@ -70,6 +70,33 @@ impl TestHost {
|
||||
Self { cache_dir, host: Mutex::new(host) }
|
||||
}
|
||||
|
||||
async fn precheck_pvf(
|
||||
&self,
|
||||
code: &[u8],
|
||||
executor_params: ExecutorParams,
|
||||
) -> Result<PrepareStats, PrepareError> {
|
||||
let (result_tx, result_rx) = futures::channel::oneshot::channel();
|
||||
|
||||
let code = sp_maybe_compressed_blob::decompress(code, 16 * 1024 * 1024)
|
||||
.expect("Compression works");
|
||||
|
||||
self.host
|
||||
.lock()
|
||||
.await
|
||||
.precheck_pvf(
|
||||
PvfPrepData::from_code(
|
||||
code.into(),
|
||||
executor_params,
|
||||
TEST_PREPARATION_TIMEOUT,
|
||||
PrepareJobKind::Prechecking,
|
||||
),
|
||||
result_tx,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
result_rx.await.unwrap()
|
||||
}
|
||||
|
||||
async fn validate_candidate(
|
||||
&self,
|
||||
code: &[u8],
|
||||
@@ -291,8 +318,12 @@ async fn deleting_prepared_artifact_does_not_dispute() {
|
||||
{
|
||||
// Get the artifact path (asserting it exists).
|
||||
let mut cache_dir: Vec<_> = std::fs::read_dir(cache_dir).unwrap().collect();
|
||||
assert_eq!(cache_dir.len(), 1);
|
||||
let artifact_path = cache_dir.pop().unwrap().unwrap();
|
||||
// Should contain the artifact and the worker dir.
|
||||
assert_eq!(cache_dir.len(), 2);
|
||||
let mut artifact_path = cache_dir.pop().unwrap().unwrap();
|
||||
if artifact_path.path().is_dir() {
|
||||
artifact_path = cache_dir.pop().unwrap().unwrap();
|
||||
}
|
||||
|
||||
// Delete the artifact.
|
||||
std::fs::remove_file(artifact_path.path()).unwrap();
|
||||
@@ -317,3 +348,19 @@ async fn deleting_prepared_artifact_does_not_dispute() {
|
||||
r => panic!("{:?}", r),
|
||||
}
|
||||
}
|
||||
|
||||
// With one worker, run multiple preparation jobs serially. They should not conflict.
|
||||
#[tokio::test]
|
||||
async fn prepare_can_run_serially() {
|
||||
let host = TestHost::new_with_config(|cfg| {
|
||||
cfg.prepare_workers_hard_max_num = 1;
|
||||
});
|
||||
|
||||
let _stats = host
|
||||
.precheck_pvf(::adder::wasm_binary_unwrap(), Default::default())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Prepare a different wasm blob to prevent skipping work.
|
||||
let _stats = host.precheck_pvf(halt::wasm_binary_unwrap(), Default::default()).await.unwrap();
|
||||
}
|
||||
|
||||
@@ -14,8 +14,11 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use polkadot_node_core_pvf::testing::{spawn_with_program_path, SpawnErr};
|
||||
use std::time::Duration;
|
||||
use polkadot_node_core_pvf::{
|
||||
testing::{spawn_with_program_path, SpawnErr},
|
||||
SecurityStatus,
|
||||
};
|
||||
use std::{env, time::Duration};
|
||||
|
||||
fn worker_path(name: &str) -> std::path::PathBuf {
|
||||
let mut worker_path = std::env::current_exe().unwrap();
|
||||
@@ -33,8 +36,10 @@ async fn spawn_immediate_exit() {
|
||||
let result = spawn_with_program_path(
|
||||
"integration-test",
|
||||
worker_path("polkadot-prepare-worker"),
|
||||
&env::temp_dir(),
|
||||
&["exit"],
|
||||
Duration::from_secs(2),
|
||||
SecurityStatus::default(),
|
||||
)
|
||||
.await;
|
||||
assert!(matches!(result, Err(SpawnErr::AcceptTimeout)));
|
||||
@@ -45,8 +50,10 @@ async fn spawn_timeout() {
|
||||
let result = spawn_with_program_path(
|
||||
"integration-test",
|
||||
worker_path("polkadot-execute-worker"),
|
||||
&env::temp_dir(),
|
||||
&["test-sleep"],
|
||||
Duration::from_secs(2),
|
||||
SecurityStatus::default(),
|
||||
)
|
||||
.await;
|
||||
assert!(matches!(result, Err(SpawnErr::AcceptTimeout)));
|
||||
@@ -57,8 +64,10 @@ async fn should_connect() {
|
||||
let _ = spawn_with_program_path(
|
||||
"integration-test",
|
||||
worker_path("polkadot-prepare-worker"),
|
||||
&env::temp_dir(),
|
||||
&["prepare-worker"],
|
||||
Duration::from_secs(2),
|
||||
SecurityStatus::default(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
Reference in New Issue
Block a user