Skip to content

Commit

Permalink
verify execution of proposal through qstash
Browse files Browse the repository at this point in the history
  • Loading branch information
ravi-sawlani-yral committed Dec 5, 2024
1 parent 109bdd9 commit 8b0f0e5
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 40 deletions.
43 changes: 9 additions & 34 deletions src/canister/upgrade_user_token_sns_canister.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ use candid::Principal;
use futures::{stream::FuturesUnordered, TryStreamExt};
use ic_agent::Agent;
use serde::{Deserialize, Serialize};
use std::{error::Error, sync::Arc, time::Duration, vec};
use std::{error::Error, sync::Arc, vec};
use yral_canisters_client::{
individual_user_template::{DeployedCdaoCanisters, IndividualUserTemplate, Ok},
individual_user_template::{DeployedCdaoCanisters, IndividualUserTemplate},
platform_orchestrator::PlatformOrchestrator,
sns_governance::{
self, Action, Command1, Configure, Follow, GetProposal, IncreaseDissolveDelay, ListNeurons,
Expand All @@ -21,6 +21,12 @@ use crate::{consts::PLATFORM_ORCHESTRATOR_ID, qstash::client::QStashClient};
use crate::app_state::AppState;
use crate::utils::api_response::ApiResponse;

#[derive(Serialize, Deserialize, Clone, Copy, Debug)]
pub struct VerifyUpgradeProposalRequest {
pub sns_canisters: SnsCanisters,
pub proposal_id: u64,
}

#[derive(Serialize, Deserialize, Clone, Copy, Debug)]
pub struct SnsCanisters {
pub governance: Principal,
Expand Down Expand Up @@ -191,31 +197,7 @@ async fn recharge_canister_using_platform_orchestrator(
Ok(())
}

async fn check_if_the_proposal_executed_successfully_with_retries(
sns_governance: &SnsGovernance<'_>,
proposal_id: u64,
max_retries: u64,
) -> Result<(), Box<dyn Error + Send + Sync>> {
let mut retry_attempt = 0_u64;

while retry_attempt < max_retries {
let res = check_if_the_proposal_executed_successfully(sns_governance, proposal_id).await;
if let Err(e) = res {
return Err(e);
} else if let Ok(executed) = res {
if executed {
return Ok(());
} else {
retry_attempt += 1;
tokio::time::sleep(Duration::from_secs(5)).await;
}
}
}

Err(format!("failed after retrying for {} times", max_retries).into())
}

async fn check_if_the_proposal_executed_successfully(
pub async fn check_if_the_proposal_executed_successfully(
sns_governance: &SnsGovernance<'_>,
proposal_id: u64,
) -> Result<bool, Box<dyn Error + Send + Sync>> {
Expand Down Expand Up @@ -321,13 +303,6 @@ pub async fn upgrade_user_token_sns_canister_impl(
if let Command1::MakeProposal(proposal_id) = proposal_id {
let proposal_id_u64 = proposal_id.proposal_id.ok_or("proposal id not found")?.id;

check_if_the_proposal_executed_successfully_with_retries(
&sns_governance,
proposal_id_u64,
3,
)
.await?;

Ok(proposal_id_u64)
} else {
Err(format!("{:?}", proposal_id).into())
Expand Down
27 changes: 26 additions & 1 deletion src/qstash/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use http::{
use reqwest::{Client, Url};
use yral_canisters_client::individual_user_template::DeployedCdaoCanisters;

use crate::{canister::upgrade_user_token_sns_canister::SnsCanisters, consts::OFF_CHAIN_AGENT_URL};
use crate::{
canister::upgrade_user_token_sns_canister::{SnsCanisters, VerifyUpgradeProposalRequest},
consts::OFF_CHAIN_AGENT_URL,
};

#[derive(Clone, Debug)]
pub struct QStashClient {
Expand Down Expand Up @@ -129,4 +132,26 @@ impl QStashClient {

Ok(())
}

pub async fn verify_sns_canister_upgrade_proposal(
&self,
verify_request: VerifyUpgradeProposalRequest,
) -> Result<(), anyhow::Error> {
let off_chain_ep = OFF_CHAIN_AGENT_URL
.join("qstash/verify_sns_canister_upgrade_proposal")
.unwrap();

let url = self.base_url.join(&format!("publish/{}", off_chain_ep))?;
let req = serde_json::json!(verify_request);

self.client
.post(url)
.json(&req)
.header(CONTENT_TYPE, "application/json")
.header("upstash-method", "POST")
.send()
.await?;

Ok(())
}
}
55 changes: 50 additions & 5 deletions src/qstash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use std::{str::FromStr, sync::Arc, time::Duration};

use axum::{
extract::State,
handler::Handler,
middleware::{self},
response::Response,
routing::post,
Expand All @@ -31,7 +30,8 @@ use yral_qstash_types::{ClaimTokensRequest, ParticipateInSwapRequest};
use crate::{
app_state::AppState,
canister::upgrade_user_token_sns_canister::{
upgrade_user_token_sns_canister_impl, SnsCanisters,
check_if_the_proposal_executed_successfully, upgrade_user_token_sns_canister_impl,
SnsCanisters, VerifyUpgradeProposalRequest,
},
consts::ICP_LEDGER_CANISTER_ID,
events::{
Expand Down Expand Up @@ -311,13 +311,18 @@ async fn upgrade_sns_creator_dao_canister(
) -> Result<Response, StatusCode> {
let governance_canister_id = req.governance.to_text();

let result = upgrade_user_token_sns_canister_impl(&state.agent, governance_canister_id).await;
let result =
upgrade_user_token_sns_canister_impl(&state.agent, governance_canister_id.clone()).await;

match result {
Ok(proposal_id) => {
let qstask_enqueue = state
let verify_request = VerifyUpgradeProposalRequest {
sns_canisters: req,
proposal_id,
};
state
.qstash_client
.upgrade_sns_creator_dao_canister(req)
.verify_sns_canister_upgrade_proposal(verify_request)
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

Expand All @@ -339,6 +344,42 @@ async fn upgrade_sns_creator_dao_canister(
}
}

async fn verify_sns_canister_upgrade_proposal(
State(state): State<Arc<AppState>>,
Json(verify_sns_canister_proposal_request): Json<VerifyUpgradeProposalRequest>,
) -> Result<Response, StatusCode> {
let governance_canister_principal = verify_sns_canister_proposal_request
.sns_canisters
.governance;

let sns_governance = SnsGovernance(governance_canister_principal, &state.agent);

let result = check_if_the_proposal_executed_successfully(
&sns_governance,
verify_sns_canister_proposal_request.proposal_id,
)
.await;

match result {
Ok(executed) if executed => {
state
.qstash_client
.upgrade_sns_creator_dao_canister(
verify_sns_canister_proposal_request.sns_canisters,
)
.await
.map_err(|_e| StatusCode::INTERNAL_SERVER_ERROR)?;

Ok(Response::builder()
.status(StatusCode::OK)
.body("Proposal executed successfully".into())
.unwrap())
}

_ => Err(StatusCode::BAD_REQUEST),
}
}

pub fn qstash_router<S>(app_state: Arc<AppState>) -> Router<S> {
Router::new()
.route("/claim_tokens", post(claim_tokens_from_first_neuron))
Expand All @@ -350,6 +391,10 @@ pub fn qstash_router<S>(app_state: Arc<AppState>) -> Router<S> {
.route("/upload_video_gcs", post(upload_video_gcs))
.route("/enqueue_video_frames", post(extract_frames_and_upload))
.route("/enqueue_video_nsfw_detection", post(nsfw_job))
.route(
"/verify_sns_canister_upgrade_proposal",
post(verify_sns_canister_upgrade_proposal),
)
.layer(ServiceBuilder::new().layer(middleware::from_fn_with_state(
app_state.qstash.clone(),
verify_qstash_message,
Expand Down

0 comments on commit 8b0f0e5

Please sign in to comment.