use super::RemoteClient;
use crate::{
job_handle::{new_subscriber_list, JobHandle, SubscriberList},
setup::SetupResult,
};
use std::path::PathBuf;
use std::time::Duration;
use zisk_coordinator_api::dto::{
DomainJobKind, DomainJobKindResponse, DomainSetupRequest, TerminalStatus,
};
use zisk_prover_backend::GuestProgram;
use crate::{Result, SdkError};
use zisk_rom_setup::{get_elf_bin_verkey_file_path_with_hash, get_output_path, HashMode};
impl RemoteClient {
pub(crate) fn do_setup(
&self,
program: &GuestProgram,
with_hints: bool,
emulator_only: bool,
timeout: Option<Duration>,
subs: SubscriberList,
) -> Result<JobHandle<SetupResult>> {
self.do_setup_by_id(
&program.program_id.hash_id,
&program.program_id.name,
with_hints,
emulator_only,
timeout,
subs,
)
}
pub(crate) fn do_setup_by_id(
&self,
hash_id: &str,
program_name: &str,
with_hints: bool,
emulator_only: bool,
timeout: Option<Duration>,
subs: SubscriberList,
) -> Result<JobHandle<SetupResult>> {
let job_kind = DomainJobKind::Setup(DomainSetupRequest {
hash_id: hash_id.to_string(),
program_name: program_name.to_string(),
with_hints,
emulator_only,
});
let remote_job = self.gw.submit_job(job_kind).map_err(SdkError::backend)?;
Ok(JobHandle::new_remote(remote_job, subs, timeout, None, None))
}
}
pub struct SetupByIdRequest<'a> {
client: &'a RemoteClient,
hash_id: String,
program_name: String,
with_hints: bool,
emulator_only: bool,
timeout: Option<Duration>,
output_dir: Option<PathBuf>,
}
impl<'a> SetupByIdRequest<'a> {
pub(crate) fn new(client: &'a RemoteClient, hash_id: String) -> Self {
Self {
client,
program_name: hash_id.clone(),
hash_id,
with_hints: false,
emulator_only: false,
timeout: None,
output_dir: None,
}
}
#[must_use]
pub fn with_hints(mut self) -> Self {
self.with_hints = true;
self
}
#[must_use]
pub fn emulator_only(mut self) -> Self {
self.emulator_only = true;
self
}
#[must_use]
pub fn timeout(mut self, duration: Duration) -> Self {
self.timeout = Some(duration);
self
}
#[must_use]
pub fn output_dir(mut self, dir: PathBuf) -> Self {
self.output_dir = Some(dir);
self
}
pub fn run(self) -> Result<JobHandle<SetupResult>> {
let subs = new_subscriber_list();
let mut handle = self.client.do_setup_by_id(
&self.hash_id,
&self.program_name,
self.with_hints,
self.emulator_only,
self.timeout,
subs,
)?;
let hash_id = self.hash_id.clone();
let output_dir = self.output_dir.clone();
handle.set_pre_process(move |status: &TerminalStatus| {
if let TerminalStatus::Completed(DomainJobKindResponse::Setup { vk, hash_mode }) =
status
{
let hash_mode = hash_mode.parse::<HashMode>().map_err(SdkError::backend)?;
let output_path = get_output_path(&output_dir).map_err(SdkError::backend)?;
let path =
get_elf_bin_verkey_file_path_with_hash(&hash_id, &output_path, hash_mode)
.map_err(SdkError::backend)?;
std::fs::write(&path, vk).map_err(SdkError::backend)?;
}
Ok(())
});
Ok(handle)
}
}