|
1 | 1 | use anyhow::anyhow; |
2 | 2 | use crossbeam_channel::{unbounded, Receiver}; |
3 | 3 | use indicatif::{HumanDuration, ProgressBar, ProgressStyle}; |
4 | | -use reqwest::Client; |
| 4 | +use reqwest::{Client, Response}; |
5 | 5 | use serde_json::json; |
| 6 | +use solana_client::rpc_client::RpcClient; |
6 | 7 | use solana_sdk::pubkey::Pubkey; |
7 | 8 | use std::thread; |
8 | 9 | use std::time::{Duration, Instant}; |
9 | 10 |
|
10 | 11 | use crate::api::models::{ |
11 | | - ErrorResponse, JobResponse, JobStatus, JobVerificationResponse, VerifyResponse, |
| 12 | + ErrorResponse, JobResponse, JobStatus, JobVerificationResponse, RemoteStatusResponseWrapper, |
| 13 | + VerifyResponse, |
12 | 14 | }; |
| 15 | +use crate::solana_program::get_program_pda; |
| 16 | +use crate::{get_genesis_hash, MAINNET_GENESIS_HASH}; |
13 | 17 |
|
14 | 18 | // URL for the remote server |
15 | 19 | pub const REMOTE_SERVER_URL: &str = "https://verify.osec.io"; |
@@ -108,10 +112,56 @@ pub async fn send_job_to_remote( |
108 | 112 | .send() |
109 | 113 | .await?; |
110 | 114 |
|
| 115 | + handle_submission_response(&client, response, program_id).await |
| 116 | +} |
| 117 | + |
| 118 | +pub async fn send_job_with_uploader_to_remote( |
| 119 | + connection: &RpcClient, |
| 120 | + program_id: &Pubkey, |
| 121 | + uploader: &Pubkey, |
| 122 | +) -> anyhow::Result<()> { |
| 123 | + // Check that PDA exists before sending job |
| 124 | + let genesis_hash = get_genesis_hash(connection)?; |
| 125 | + if genesis_hash != MAINNET_GENESIS_HASH { |
| 126 | + return Err(anyhow!("Remote verification only works with mainnet. Please omit the --remote flag to verify locally.")); |
| 127 | + } |
| 128 | + get_program_pda(connection, program_id, Some(uploader.to_string())).await?; |
| 129 | + |
| 130 | + let client = Client::builder() |
| 131 | + .timeout(Duration::from_secs(18000)) |
| 132 | + .build()?; |
| 133 | + |
| 134 | + // Send the POST request |
| 135 | + let response = client |
| 136 | + .post(format!("{}/verify-with-signer", REMOTE_SERVER_URL)) |
| 137 | + .json(&json!({ |
| 138 | + "program_id": program_id.to_string(), |
| 139 | + "signer": uploader.to_string(), |
| 140 | + "repository": "", |
| 141 | + "commit_hash": "", |
| 142 | + })) |
| 143 | + .send() |
| 144 | + .await?; |
| 145 | + |
| 146 | + handle_submission_response(&client, response, program_id).await |
| 147 | +} |
| 148 | + |
| 149 | +pub async fn handle_submission_response( |
| 150 | + client: &Client, |
| 151 | + response: Response, |
| 152 | + program_id: &Pubkey, |
| 153 | +) -> anyhow::Result<()> { |
111 | 154 | if response.status().is_success() { |
112 | | - let status_response: VerifyResponse = response.json().await?; |
| 155 | + // First get the raw text to preserve it in case of parsing failure |
| 156 | + let response_text = response.text().await?; |
| 157 | + let status_response = |
| 158 | + serde_json::from_str::<VerifyResponse>(&response_text).map_err(|e| { |
| 159 | + eprintln!("Failed to parse response as VerifyResponse: {}", e); |
| 160 | + eprintln!("Raw response: {}", response_text); |
| 161 | + anyhow!("Failed to parse server response") |
| 162 | + })?; |
113 | 163 | let request_id = status_response.request_id; |
114 | | - println!("Verification request sent. ✅"); |
| 164 | + println!("Verification request sent with request id: {}", request_id); |
115 | 165 | println!("Verification in progress... ⏳"); |
116 | 166 | // Span new thread for polling the server for status |
117 | 167 | // Create a channel for communication between threads |
@@ -228,3 +278,32 @@ async fn check_job_status(client: &Client, request_id: &str) -> anyhow::Result<J |
228 | 278 | ))? |
229 | 279 | } |
230 | 280 | } |
| 281 | + |
| 282 | +pub async fn get_remote_status(program_id: Pubkey) -> anyhow::Result<()> { |
| 283 | + let client = Client::builder() |
| 284 | + .timeout(Duration::from_secs(18000)) |
| 285 | + .build()?; |
| 286 | + |
| 287 | + let response = client |
| 288 | + .get(format!( |
| 289 | + "{}/status-all/{}", |
| 290 | + REMOTE_SERVER_URL, |
| 291 | + program_id.to_string() |
| 292 | + )) |
| 293 | + .send() |
| 294 | + .await?; |
| 295 | + |
| 296 | + let status: RemoteStatusResponseWrapper = response.json().await?; |
| 297 | + println!("{}", status); |
| 298 | + Ok(()) |
| 299 | +} |
| 300 | + |
| 301 | +pub async fn get_remote_job(job_id: &str) -> anyhow::Result<()> { |
| 302 | + let client = Client::builder() |
| 303 | + .timeout(Duration::from_secs(18000)) |
| 304 | + .build()?; |
| 305 | + |
| 306 | + let job = check_job_status(&client, job_id).await?; |
| 307 | + println!("{}", job); |
| 308 | + Ok(()) |
| 309 | +} |
0 commit comments