-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
♻️ move core logic into
service_provider
and customer
instead of …
…in the main
- Loading branch information
1 parent
f73a51a
commit fade137
Showing
14 changed files
with
511 additions
and
231 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,137 +1,28 @@ | ||
use askeladd::config::Settings; | ||
use askeladd::db::{Database, RequestStatus}; | ||
use askeladd::prover_service::ProverService; | ||
use askeladd::types::{FibonnacciProvingRequest, FibonnacciProvingResponse}; | ||
use askeladd::dvm::service_provider::ServiceProvider; | ||
use dotenv::dotenv; | ||
use nostr_sdk::prelude::*; | ||
|
||
#[macro_use] | ||
extern crate log; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<()> { | ||
// Initialize logger and set default level to info | ||
async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
// ****************************************************** | ||
// ****************** SETUP ***************************** | ||
// ****************************************************** | ||
pretty_env_logger::formatted_builder() | ||
.filter_level(log::LevelFilter::Info) | ||
.init(); | ||
|
||
// Load configuration from .env filed | ||
dotenv().ok(); | ||
let settings = Settings::new().expect("Failed to load settings"); | ||
|
||
let user_secret_key = SecretKey::from_bech32(&settings.user_bech32_sk)?; | ||
let user_keys = Keys::new(user_secret_key); | ||
let user_public_key = user_keys.public_key(); | ||
|
||
let prover_agent_keys = Keys::new(SecretKey::from_bech32(&settings.prover_agent_sk).unwrap()); | ||
|
||
let opts = Options::new().wait_for_send(false); | ||
let client = Client::with_opts(&prover_agent_keys, opts); | ||
|
||
for relay in settings.subscribed_relays { | ||
client.add_relay(&relay).await?; | ||
} | ||
|
||
client.connect().await; | ||
debug!("Nostr client connected to relays."); | ||
|
||
let proving_req_sub_id = SubscriptionId::new(settings.proving_req_sub_id); | ||
let filter = Filter::new().kind(Kind::TextNote).author(user_public_key); | ||
|
||
client | ||
.subscribe_with_id(proving_req_sub_id.clone(), vec![filter], None) | ||
.await | ||
.expect("Failed to subscribe to proving requests"); | ||
|
||
let db = | ||
Database::new(settings.db_path.to_str().unwrap()).expect("Failed to initialize database"); | ||
|
||
let proving_service: ProverService = Default::default(); | ||
|
||
info!("Subscribed to proving requests, waiting for requests..."); | ||
client | ||
.handle_notifications(|notification| async { | ||
if let RelayPoolNotification::Event { | ||
subscription_id, | ||
event, | ||
.. | ||
} = notification | ||
{ | ||
if subscription_id == proving_req_sub_id { | ||
info!("Proving request received [{}]", event.id.to_string()); | ||
|
||
// Deserialize the request | ||
if let Ok(request) = | ||
serde_json::from_str::<FibonnacciProvingRequest>(&event.content) | ||
{ | ||
// Check if request has already been processed | ||
if let Ok(Some(status)) = db.get_request_status(&request.request_id) { | ||
match status { | ||
RequestStatus::Completed => { | ||
info!( | ||
"Request {} already processed, skipping", | ||
request.request_id | ||
); | ||
return Ok(false); | ||
} | ||
RequestStatus::Failed => { | ||
info!("Request {} failed before, retrying", request.request_id); | ||
} | ||
RequestStatus::Pending => { | ||
info!( | ||
"Request {} is already pending, skipping", | ||
request.request_id | ||
); | ||
return Ok(false); | ||
} | ||
} | ||
} else { | ||
// New request, insert into database | ||
if let Err(e) = db.insert_request(&request) { | ||
error!("Failed to insert request into database: {}", e); | ||
return Ok(false); | ||
} | ||
} | ||
|
||
// Generate the proof | ||
match proving_service.generate_proof(request.clone()) { | ||
Ok(response) => { | ||
// Serialize the response to JSON | ||
let response_json = serde_json::to_string(&response)?; | ||
|
||
// Publish the proving response | ||
let tags = vec![]; | ||
let event_id = | ||
client.publish_text_note(response_json, tags).await?; | ||
info!("Proving response published [{}]", event_id.to_string()); | ||
// ****************************************************** | ||
// ****************** INIT SERVICE PROVIDER ************* | ||
// ****************************************************** | ||
let mut service_provider = ServiceProvider::new(settings)?; | ||
service_provider.init().await?; | ||
|
||
// Update database | ||
if let Err(e) = db.update_request( | ||
&response.request_id, | ||
&response, | ||
RequestStatus::Completed, | ||
) { | ||
error!("Failed to update request in database: {}", e); | ||
} | ||
} | ||
Err(e) => { | ||
error!("Proof generation failed: {}", e); | ||
// Update database with failed status | ||
if let Err(db_err) = db.update_request( | ||
&request.request_id, | ||
&FibonnacciProvingResponse::default(), | ||
RequestStatus::Failed, | ||
) { | ||
error!("Failed to update request in database: {}", db_err); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
Ok(false) | ||
}) | ||
.await?; | ||
// ****************************************************** | ||
// ****************** RUN SERVICE PROVIDER ************** | ||
// ****************************************************** | ||
service_provider.run().await?; | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,106 +1,60 @@ | ||
use askeladd::config::Settings; | ||
use askeladd::types::{FibonnacciProvingRequest, FibonnacciProvingResponse}; | ||
use askeladd::verifier_service::VerifierService; | ||
use askeladd::dvm::customer::Customer; | ||
use askeladd::dvm::types::GenerateZKPJobRequest; | ||
use askeladd::types::FibonnacciProvingRequest; | ||
use dotenv::dotenv; | ||
use nostr_sdk::prelude::*; | ||
use tokio::time::{sleep, Duration}; | ||
use uuid::Uuid; | ||
#[macro_use] | ||
extern crate log; | ||
use log::info; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<()> { | ||
// Initialize logger and set default level to info | ||
async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
// ****************************************************** | ||
// ****************** SETUP ***************************** | ||
// ****************************************************** | ||
pretty_env_logger::formatted_builder() | ||
.filter_level(log::LevelFilter::Info) | ||
.init(); | ||
|
||
info!("User agent starting..."); | ||
info!("Waiting 5 seconds before submitting proving request..."); | ||
// Add a delay before connecting | ||
sleep(Duration::from_secs(5)).await; | ||
|
||
// Load configuration from .env file | ||
dotenv().ok(); | ||
let settings = Settings::new().expect("Failed to load settings"); | ||
|
||
let prover_agent_secret_key = SecretKey::from_bech32(&settings.prover_agent_sk)?; | ||
let prover_agent_keys = Keys::new(prover_agent_secret_key); | ||
let prover_agent_public_key = prover_agent_keys.public_key(); | ||
let user_keys = Keys::new(SecretKey::from_bech32(&settings.user_bech32_sk).unwrap()); | ||
|
||
let opts = Options::new().wait_for_send(false); | ||
let client = Client::with_opts(&user_keys, opts); | ||
|
||
for relay in settings.subscribed_relays { | ||
client.add_relay(&relay).await?; | ||
} | ||
|
||
client.connect().await; | ||
debug!("Nostr client connected to relays."); | ||
|
||
// Generate a unique request ID | ||
let request_id = Uuid::new_v4().to_string(); | ||
|
||
// Create a proving request | ||
let proving_request = FibonnacciProvingRequest { | ||
request_id: request_id.clone(), | ||
log_size: 5, | ||
claim: 443693538, | ||
// ****************************************************** | ||
// ****************** INIT CUSTOMER ********************* | ||
// ****************************************************** | ||
let mut customer = Customer::new(settings)?; | ||
customer.init().await?; | ||
|
||
// ****************************************************** | ||
// ****************** PREPARE JOB *********************** | ||
// ****************************************************** | ||
let job_id = GenerateZKPJobRequest::new_job_id(); | ||
|
||
let job_request = GenerateZKPJobRequest { | ||
job_id, | ||
request: FibonnacciProvingRequest { | ||
log_size: 5, | ||
claim: 443693538, | ||
}, | ||
}; | ||
|
||
// Serialize the request to JSON | ||
let request_json = serde_json::to_string(&proving_request)?; | ||
|
||
// Publish the proving request | ||
debug!("Publishing proving request..."); | ||
let event_id = client.publish_text_note(request_json, []).await?; | ||
|
||
info!("Proving request published [{}]", event_id.to_string()); | ||
|
||
// Subscribe to proving responses | ||
let proving_resp_sub_id = SubscriptionId::new(settings.proving_resp_sub_id); | ||
let filter = Filter::new() | ||
.kind(Kind::TextNote) | ||
.author(prover_agent_public_key) | ||
.since(Timestamp::now()); | ||
|
||
client | ||
.subscribe_with_id(proving_resp_sub_id.clone(), vec![filter], None) | ||
.await | ||
.expect("Failed to subscribe to proving responses"); | ||
|
||
// Handle subscription notifications | ||
client | ||
.handle_notifications(|notification| async { | ||
if let RelayPoolNotification::Event { | ||
subscription_id, | ||
event, | ||
.. | ||
} = notification | ||
{ | ||
if subscription_id == proving_resp_sub_id { | ||
info!("Proving response received [{}]", event.id.to_string()); | ||
|
||
// Deserialize the response | ||
if let Ok(response) = | ||
serde_json::from_str::<FibonnacciProvingResponse>(&event.content) | ||
{ | ||
// Verify the proof | ||
let verifier_service: VerifierService = Default::default(); | ||
info!("Verifying proof..."); | ||
match verifier_service.verify_proof(response) { | ||
Ok(_) => info!("Proof successfully verified"), | ||
Err(e) => error!("Proof verification failed: {}", e), | ||
} | ||
// Stop listening after receiving and verifying the response | ||
return Ok(true); | ||
} | ||
} | ||
} | ||
Ok(false) | ||
}) | ||
// ****************************************************** | ||
// ****************** SUBMIT JOB ************************ | ||
// ****************************************************** | ||
info!("Submitting job with id: {}", job_request.job_id); | ||
customer.submit_job(job_request.clone()).await?; | ||
|
||
// ****************************************************** | ||
// ****************** WAIT FOR JOB RESULT *************** | ||
// ****************************************************** | ||
info!("Waiting for job result with id: {}", job_request.job_id); | ||
let job_result = customer | ||
.wait_for_job_result(&job_request.job_id, 60) | ||
.await?; | ||
|
||
// ****************************************************** | ||
// ****************** VERIFY PROOF ********************** | ||
// ****************************************************** | ||
info!("Verifying proof with id: {}", job_request.job_id); | ||
let is_valid = customer.verify_proof(&job_result)?; | ||
info!("Proof is valid: {}", is_valid); | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.