From 8609fc660bcdd215f79753cb64b02f8a4e708417 Mon Sep 17 00:00:00 2001 From: Akshay Date: Mon, 18 Nov 2024 10:19:47 +0000 Subject: [PATCH] Add Read Proof using indexer_url --- kalypso-cli/Cargo.toml | 1 + kalypso-cli/src/common_deps.rs | 4 ++ kalypso-cli/src/config.json | 13 +++- kalypso-cli/src/operations/mod.rs | 2 +- kalypso-cli/src/operations/read_proof.rs | 92 ++++++++++++++++++++---- kalypso-cli/src/prompts.rs | 1 + 6 files changed, 97 insertions(+), 16 deletions(-) diff --git a/kalypso-cli/Cargo.toml b/kalypso-cli/Cargo.toml index 540af37..d7a8d51 100644 --- a/kalypso-cli/Cargo.toml +++ b/kalypso-cli/Cargo.toml @@ -16,6 +16,7 @@ ethers = { version = "2", features = ["rustls"] } hex = "0.4.3" kalypso_helper = {path = "../helper", package = "helper"} log = "0.4" +matching_engine_helpers = { path = "../matching_engine", package = "matching_engine" } openssl = { version = "0.10.57", features = ["vendored"] } reqwest = { version = "0.11", features = ["stream"] } serde = { version = "1.0", features = ["derive"] } diff --git a/kalypso-cli/src/common_deps.rs b/kalypso-cli/src/common_deps.rs index 399e744..47659e6 100644 --- a/kalypso-cli/src/common_deps.rs +++ b/kalypso-cli/src/common_deps.rs @@ -840,8 +840,10 @@ impl CommonDeps { pub struct ReadProofInfo { pub proof_marketplace: bindings::proof_marketplace::ProofMarketplace>, + #[allow(unused)] pub provider_http: Provider, pub ask_id: U256, + pub indexer_url: String, } impl CommonDeps { @@ -851,6 +853,7 @@ impl CommonDeps { get_config_ref!(config, "rpc_url", rpc_url); get_config_ref!(config, "proof_marketplace", proof_marketplace_address); get_config_ref!(config, "ask_id", ask_id); + get_config_ref!(config, "indexer_url", indexer_url); let ask_id = U256::from_dec_str(&ask_id.as_str()).map_err(|e| format!("Invalid Ask Id: {}", e))?; @@ -862,6 +865,7 @@ impl CommonDeps { proof_marketplace, provider_http, ask_id, + indexer_url: indexer_url.to_string(), }) } } diff --git a/kalypso-cli/src/config.json b/kalypso-cli/src/config.json index 402cb79..14ddb1e 100644 --- a/kalypso-cli/src/config.json +++ b/kalypso-cli/src/config.json @@ -228,6 +228,12 @@ "prompt": "Address of the network to opt in", "secret": false, "env_var": "NETWORK_ADDRESS" + }, + { + "field": "indexer_url", + "prompt": "Enter the URL or kalypso indexer", + "secret": false, + "env_var": "INDEXER_URL" } ], "operations": [ @@ -434,13 +440,14 @@ ] }, { - "name": "Read Proof Bytes (beta)", - "description": "Read Proof Bytes (beta, operation development in progress).", + "name": "Read Proof Bytes", + "description": "Read Proof Bytes using kalypso data indexer", "required_prompts": [ "rpc_url", "chain_id", "proof_marketplace", - "ask_id" + "ask_id", + "indexer_url" ] }, { diff --git a/kalypso-cli/src/operations/mod.rs b/kalypso-cli/src/operations/mod.rs index 79541aa..5f9850d 100644 --- a/kalypso-cli/src/operations/mod.rs +++ b/kalypso-cli/src/operations/mod.rs @@ -72,7 +72,7 @@ pub fn get_operation(name: &str) -> Option> { "Whitelist IVS Image" => Some(Box::new(whitelist::WhitelistVerificationImage)), "Update Encryption Key" => Some(Box::new(update_encryption_key::UpdateEncryptionKey)), "Add IVS Key" => Some(Box::new(update_encryption_key::AddIvsKey)), - "Read Proof Bytes (beta)" => Some(Box::new(read_proof::ReadProof)), + "Read Proof Bytes" => Some(Box::new(read_proof::ReadProof)), "Request Symbiotic Stake" => Some(Box::new(symbiotic_opt_in::SymbioticOptIn)), _ => unimplemented!(), } diff --git a/kalypso-cli/src/operations/read_proof.rs b/kalypso-cli/src/operations/read_proof.rs index ae19fb5..e6dcc4d 100644 --- a/kalypso-cli/src/operations/read_proof.rs +++ b/kalypso-cli/src/operations/read_proof.rs @@ -1,7 +1,9 @@ use std::collections::HashMap; use async_trait::async_trait; -use ethers::providers::Middleware; +use ethers::types::U256; +use matching_engine_helpers::ask_lib::ask_status::AskState; +use serde::Deserialize; use crate::common_deps::CommonDeps; @@ -14,22 +16,88 @@ impl Operation for ReadProof { async fn execute(&self, config: HashMap) -> Result<(), String> { let read_proof_info = CommonDeps::read_proof_info(&config)?; - let filter = read_proof_info + let ask_state = read_proof_info .proof_marketplace - .proof_created_filter() - .filter - .topic0(read_proof_info.ask_id); - - let logs = read_proof_info - .provider_http - .get_logs(&filter) + .get_ask_state(read_proof_info.ask_id) + .call() .await - .map_err(|e| format!("Failed Reading Proof: {}", e))?; + .map_err(|e| format!("Unable to read proof marketplace contract: {}", e))?; + + let ask_state = matching_engine_helpers::ask_lib::ask_status::get_ask_state(ask_state); + + if ask_state == AskState::Complete { + println!("Request is complete"); + let proof = read_proof(&read_proof_info.ask_id, read_proof_info.indexer_url) + .await + .map_err(|e| format!("Unable to read proof from indexer: {}", e))?; + + println!("{}", proof); + + return Ok(()); + } - for log in logs { - println!("Log: {:?}", log); + if ask_state == AskState::Null { + return Err("Invalid Ask Request ID".to_string()); } Ok(()) } } + +use std::error::Error; +#[derive(Debug, Deserialize, Clone)] +struct Proof { + status: String, + proof: Vec, +} + +async fn read_proof(ask_id: &U256, indexer_url: String) -> Result> { + // Initialize the HTTP client with a timeout (optional but recommended) + let client = reqwest::Client::builder() + .timeout(std::time::Duration::from_secs(10)) + .build()?; + let full_url = format!("{}/stats/getProof", indexer_url); + + // Prepare the headers + let mut headers = reqwest::header::HeaderMap::new(); + headers.insert(reqwest::header::CONTENT_TYPE, "application/json".parse()?); + + // Prepare the JSON payload, converting U256 to a string + let payload = serde_json::json!({ + "ask_id": ask_id.to_string() + }); + + // Send the POST request + let response = client + .post(&full_url) + .headers(headers) + .json(&payload) + .send() + .await?; + + // Capture the HTTP status before moving the response + let status = response.status(); + + // Read the response body as text + let response_text = response.text().await?; + + // Attempt to parse the JSON response into the Proof struct + let proof_response: Proof = match serde_json::from_str(&response_text) { + Ok(proof) => proof, + Err(e) => { + return Err(format!( + "Failed to parse JSON response. HTTP Status: {}, Body: {}, Error: {}", + status, response_text, e + ) + .into()) + } + }; + + // Check the HTTP status and the JSON status + if !status.is_success() && proof_response.status.to_lowercase() != "Invalid Inputs Detected" { + return Ok("Prover Detected Invalid Inputs. An attestation was submitted to prove that inputs were invalid".into()); + } + + // Encode the proof bytes to a hex string and return + Ok(format!("0x{}", hex::encode(proof_response.proof))) +} diff --git a/kalypso-cli/src/prompts.rs b/kalypso-cli/src/prompts.rs index c9abe84..4a0d6ec 100644 --- a/kalypso-cli/src/prompts.rs +++ b/kalypso-cli/src/prompts.rs @@ -76,6 +76,7 @@ impl<'a> Prompter<'a> { validators.insert("network_opt_in_service".to_string(), validate_eth_address); validators.insert("vault_address".to_string(), validate_eth_address); validators.insert("network_address".to_string(), validate_eth_address); + validators.insert("indexer_url".to_string(), validate_rpc_url); validators.insert( "confirmation".to_string(),