light_client/
local_test_validator.rs

1use std::process::{Command, Stdio};
2
3use light_prover_client::helpers::get_project_root;
4
5#[derive(Debug)]
6pub struct LightValidatorConfig {
7    pub enable_indexer: bool,
8    pub enable_prover: bool,
9    pub wait_time: u64,
10    /// Non-upgradeable programs: (program_id, program_path)
11    pub sbf_programs: Vec<(String, String)>,
12    /// Upgradeable programs: (program_id, program_path, upgrade_authority)
13    /// Use this when the program needs a valid upgrade authority (e.g., for compression config)
14    pub upgradeable_programs: Vec<(String, String, String)>,
15    pub limit_ledger_size: Option<u64>,
16}
17
18impl Default for LightValidatorConfig {
19    fn default() -> Self {
20        Self {
21            enable_indexer: false,
22            enable_prover: false,
23            wait_time: 35,
24            sbf_programs: vec![],
25            upgradeable_programs: vec![],
26            limit_ledger_size: None,
27        }
28    }
29}
30
31pub async fn spawn_validator(config: LightValidatorConfig) {
32    if let Some(project_root) = get_project_root() {
33        let path = "cli/test_bin/run test-validator";
34        let mut path = format!("{}/{}", project_root.trim(), path);
35        if !config.enable_indexer {
36            path.push_str(" --skip-indexer");
37        }
38
39        if let Some(limit_ledger_size) = config.limit_ledger_size {
40            path.push_str(&format!(" --limit-ledger-size {}", limit_ledger_size));
41        }
42
43        for sbf_program in config.sbf_programs.iter() {
44            path.push_str(&format!(
45                " --sbf-program {} {}",
46                sbf_program.0, sbf_program.1
47            ));
48        }
49
50        for upgradeable_program in config.upgradeable_programs.iter() {
51            path.push_str(&format!(
52                " --upgradeable-program {} {} {}",
53                upgradeable_program.0, upgradeable_program.1, upgradeable_program.2
54            ));
55        }
56
57        if !config.enable_prover {
58            path.push_str(" --skip-prover");
59        }
60
61        println!("Starting validator with command: {}", path);
62
63        let child = Command::new("sh")
64            .arg("-c")
65            .arg(path)
66            .stdin(Stdio::null()) // Detach from stdin
67            .stdout(Stdio::null()) // Detach from stdout
68            .stderr(Stdio::null()) // Detach from stderr
69            .spawn()
70            .expect("Failed to start server process");
71
72        // Explicitly `drop` the process to ensure we don't wait on it
73        std::mem::drop(child);
74
75        tokio::time::sleep(tokio::time::Duration::from_secs(config.wait_time)).await;
76    }
77}