From 0b1445cd6c6adc5c0fdf6ef61b94265449337115 Mon Sep 17 00:00:00 2001 From: Keefer Taylor | Tessellated Date: Thu, 25 Jul 2024 13:31:52 -0700 Subject: [PATCH 1/2] Refactor `votes` route to return 400 when a voter has not cast a vote (#3) --- src/main.rs | 141 ++++++++++++++++++++++++++++------------------------ 1 file changed, 77 insertions(+), 64 deletions(-) diff --git a/src/main.rs b/src/main.rs index 88f033d..ba4ef69 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,8 @@ extern crate rocket; use penumbra_proto::util::tendermint_proxy::v1::SyncInfo; -use rocket::serde::json::{json, Value}; +use rocket::response::status; +use rocket::serde::json::{Json, json, Value}; use rocket::State; use clap::Parser; use futures::TryStreamExt; @@ -422,73 +423,85 @@ async fn proposals(args: &State) -> Value { }) } -#[get("/cosmos/gov/v1beta1/proposals//votes/")] -async fn proposal_vote(proposal_id: u64, voter: &str, args: &State) -> Value { - let channel = Channel::from_shared(args.node.to_string()) - .unwrap() - .tls_config(ClientTlsConfig::new()) - .unwrap() - .connect() - .await - .unwrap(); - let mut client = GovernanceQueryServiceClient::new(channel.clone()); - let votes_data: Vec = client - .validator_votes(ValidatorVotesRequest { proposal_id: proposal_id }) - .await - .unwrap() - .into_inner() - .try_collect::>() - .await - .unwrap(); +async fn get_vote(voter: &str, proposal_id: u64, args: &State) -> status::Custom> { + let channel = Channel::from_shared(args.node.to_string()) + .unwrap() + .tls_config(ClientTlsConfig::new()) + .unwrap() + .connect() + .await + .unwrap(); + + let mut client = GovernanceQueryServiceClient::new(channel.clone()); + let votes_data: Vec = client + .validator_votes(ValidatorVotesRequest { proposal_id: proposal_id }) + .await + .unwrap() + .into_inner() + .try_collect::>() + .await + .unwrap(); + + let validator_vote = votes_data + .iter() + .find(|&vote| { + let identity: IdentityKey = vote.clone().identity_key.unwrap().try_into().unwrap(); + identity.to_string() == voter + }); + + let response = match validator_vote { + None => { + status::Custom(rocket::http::Status::BadRequest, Json(json!({ + "code": 3, + "message": format!("voter: {} not found for proposal: {}", voter, proposal_id), + "details": [] + }))) + }, + Some(vote) => { + match &vote.vote { + None => { + status::Custom(rocket::http::Status::BadRequest, Json(json!({ + "code": 3, + "message": format!("voter: {} not found for proposal: {}", voter, proposal_id), + "details": [] + }))) + }, + Some(option) => { + let vote = match option.vote { + 3 => "VOTE_OPTION_NO", + 2 => "VOTE_OPTION_YES", + 1 => "VOTE_OPTION_ABSTAIN", + _ => "VOTE_OPTION_UNSPECIFIED" + }; + + status::Custom(rocket::http::Status::Ok, Json(json!({ + "vote": { + "proposal_id": proposal_id.to_string(), + "voter": voter, + "option": vote, + "options": [ + { + "option": vote, + "weight": "1.000000000000000000" + } + ] + } + }))) + } + } + } + }; + + response +} - let validator_vote = votes_data - .iter() - .find(|&vote| { - let identity: IdentityKey = vote.clone().identity_key.unwrap().try_into().unwrap(); - identity.to_string() == voter - }); - - match validator_vote { - None => json!({ - "code": 3, - "message": format!("voter: {} not found for proposal: {}", voter, proposal_id), - "details": [] - }), - Some(vote) => { - match &vote.vote { - None => json!({ - "code": 3, - "message": format!("voter: {} not found for proposal: {}", voter, proposal_id), - "details": [] - }), - Some(option) => { - let vote = match option.vote { - 3 => "VOTE_OPTION_NO", - 2 => "VOTE_OPTION_YES", - 1 => "VOTE_OPTION_YES", - _ => "VOTE_OPTION_UNSPECIFIED" - }; - - json!({ - "vote": { - "proposal_id": proposal_id.to_string(), - "voter": voter, - "option": vote, - "options": [ - { - "option": vote, - "weight": "1.000000000000000000" - } - ] - } - }) - } - } - } - } +#[get("/cosmos/gov/v1beta1/proposals//votes/")] +async fn proposal_vote(proposal_id: u64, voter: &str, args: &State) -> status::Custom> { + get_vote(voter, proposal_id, args).await } + #[launch] fn rocket() -> _ { let args = Args::parse(); From f178a0e46e0b4fc7ce82960bda06ca08d7cffec2 Mon Sep 17 00:00:00 2001 From: Keefer Taylor | Tessellated Date: Thu, 25 Jul 2024 15:04:42 -0700 Subject: [PATCH 2/2] Add CI for Penumbra LCD (#5) * Migrate to stable toolchain * Allow a configurable bind address * Return 404s when voter has not yet voted (#2) * wip: try to return 404 * rework code * fix route * one more route correction * return 400 * add CI * fix job name * enable caching * small change to test caching on ci * revert main.rs to origin/main * revert incorrect changes to main --- .github/workflows/ci.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..53dd348 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,28 @@ +name: Penumbra LCD CI + +on: + pull_request: + branches: [ main ] + push: + branches: [ main ] + +jobs: + penumbra-ci: + runs-on: ubuntu-latest + steps: + - name: Check Out Repository + uses: actions/checkout@v4 + + # See: https://github.com/actions/cache/blob/main/examples.md#rust---cargo + - uses: actions/cache@v3 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + + - name: Build Penumbra LCD + run: cargo build --release