Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: all proposals endpoint #72

Merged
merged 1 commit into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion swagger-codegen.config → swagger-codegen.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"npmName": "@anomaorg/namada-indexer-client",
"npmVersion": "0.0.16"
"npmVersion": "0.0.17"
}

30 changes: 30 additions & 0 deletions swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,36 @@ paths:
$ref: '#/components/schemas/Proposal'
pagination:
$ref: '#/components/schemas/Pagination'
/api/v1/gov/proposal/all:
get:
summary: Get a list of all governance proposals
parameters:
- in: query
name: status
schema:
type: string
enum: [pending, votingPeriod, passed, rejected]
description: The status of the proposal
- in: query
name: kind
schema:
type: string
enum: [default, defaultWithWasm, pgfSteward, pgfFunding]
description: The status of the proposal
- in: query
name: pattern
schema:
type: string
description: The status of the proposal
responses:
'200':
description: A list of governance proposals.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Proposal'
/api/v1/gov/proposal/{id}:
get:
summary: Get a governance proposal by proposal id
Expand Down
4 changes: 4 additions & 0 deletions webserver/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ impl ApplicationServer {
"/gov/proposal",
get(gov_handlers::get_governance_proposals),
)
.route(
"/gov/proposal/all",
get(gov_handlers::get_governance_proposals),
)
.route(
"/gov/proposal/:id",
get(gov_handlers::get_governance_proposal_by_id),
Expand Down
14 changes: 14 additions & 0 deletions webserver/src/handler/governance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ pub async fn get_governance_proposals(
Ok(Json(response))
}

#[debug_handler]
pub async fn get_all_governance_proposals(
_headers: HeaderMap,
Query(query): Query<ProposalQueryParams>,
State(state): State<CommonState>,
) -> Result<Json<Vec<Proposal>>, ApiError> {
let proposals = state
.gov_service
.find_all_governance_proposals(query.status, query.kind, query.pattern)
.await?;

Ok(Json(proposals))
}

#[debug_handler]
pub async fn get_governance_proposal_by_id(
_headers: HeaderMap,
Expand Down
75 changes: 58 additions & 17 deletions webserver/src/repository/governance.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use axum::async_trait;
use diesel::dsl::IntoBoxed;
use diesel::pg::Pg;
use diesel::{
BoolExpressionMethods, ExpressionMethods, PgTextExpressionMethods,
QueryDsl, RunQueryDsl, SelectableHelper,
Expand All @@ -23,12 +25,19 @@ pub trait GovernanceRepoTrait {

async fn find_governance_proposals(
&self,
status: Vec<GovernanceProposalResultDb>,
status: Option<GovernanceProposalResultDb>,
kind: Option<GovernanceProposalKindDb>,
pattern: Option<String>,
page: i64,
) -> Result<PaginatedResponseDb<GovernanceProposalDb>, String>;

async fn find_all_governance_proposals(
&self,
status: Option<GovernanceProposalResultDb>,
kind: Option<GovernanceProposalKindDb>,
pattern: Option<String>,
) -> Result<Vec<GovernanceProposalDb>, String>;

async fn find_governance_proposals_by_id(
&self,
proposal_id: i32,
Expand Down Expand Up @@ -60,29 +69,15 @@ impl GovernanceRepoTrait for GovernanceRepo {

async fn find_governance_proposals(
&self,
status: Vec<GovernanceProposalResultDb>,
status: Option<GovernanceProposalResultDb>,
kind: Option<GovernanceProposalKindDb>,
pattern: Option<String>,
page: i64,
) -> Result<PaginatedResponseDb<GovernanceProposalDb>, String> {
let conn = self.app_state.get_db_connection().await;
let query = self.governance_proposals(status, kind, pattern);

conn.interact(move |conn| {
let mut query = governance_proposals::table.into_boxed().filter(
governance_proposals::dsl::result.eq_any(status.clone()),
);

if let Some(kind) = kind {
query = query.filter(governance_proposals::dsl::kind.eq(kind));
}

if let Some(pattern) = pattern {
query = query.filter(
governance_proposals::dsl::content
.ilike(format!("%{}%", pattern)),
);
}

query
.select(GovernanceProposalDb::as_select())
.paginate(page)
Expand All @@ -93,6 +88,23 @@ impl GovernanceRepoTrait for GovernanceRepo {
.map_err(|e| e.to_string())
}

async fn find_all_governance_proposals(
&self,
status: Option<GovernanceProposalResultDb>,
kind: Option<GovernanceProposalKindDb>,
pattern: Option<String>,
) -> Result<Vec<GovernanceProposalDb>, String> {
let conn = self.app_state.get_db_connection().await;
let query = self.governance_proposals(status, kind, pattern);

conn.interact(move |conn| {
query.select(GovernanceProposalDb::as_select()).load(conn)
})
.await
.map_err(|e| e.to_string())?
.map_err(|e| e.to_string())
}

async fn find_governance_proposals_by_id(
&self,
proposal_id: i32,
Expand Down Expand Up @@ -166,3 +178,32 @@ impl GovernanceRepoTrait for GovernanceRepo {
.map_err(|e| e.to_string())
}
}

impl<'a> GovernanceRepo {
fn governance_proposals(
&self,
status: Option<GovernanceProposalResultDb>,
kind: Option<GovernanceProposalKindDb>,
pattern: Option<String>,
) -> IntoBoxed<'a, governance_proposals::table, Pg> {
let mut query = governance_proposals::table.into_boxed();

if let Some(status) = status {
query = query
.filter(governance_proposals::dsl::result.eq(status.clone()))
}

if let Some(kind) = kind {
query = query.filter(governance_proposals::dsl::kind.eq(kind));
}

if let Some(pattern) = pattern {
query = query.filter(
governance_proposals::dsl::content
.ilike(format!("%{}%", pattern)),
);
}

query
}
}
102 changes: 70 additions & 32 deletions webserver/src/service/governance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,38 +30,8 @@ impl GovernanceService {
pattern: Option<String>,
page: u64,
) -> Result<(Vec<Proposal>, u64, u64), GovernanceError> {
let status = status
.map(|s| match s {
ProposalStatus::Pending => {
vec![GovernanceProposalResultDb::Pending]
}
ProposalStatus::VotingPeriod => {
vec![GovernanceProposalResultDb::VotingPeriod]
}
ProposalStatus::Passed => {
vec![GovernanceProposalResultDb::Passed]
}
ProposalStatus::Rejected => {
vec![GovernanceProposalResultDb::Rejected]
}
})
.unwrap_or_else(|| {
vec![
GovernanceProposalResultDb::Pending,
GovernanceProposalResultDb::VotingPeriod,
GovernanceProposalResultDb::Passed,
GovernanceProposalResultDb::Rejected,
]
});

let kind = kind.map(|t| match t {
ProposalKind::Default => GovernanceProposalKindDb::Default,
ProposalKind::DefaultWithWasm => {
GovernanceProposalKindDb::DefaultWithWasm
}
ProposalKind::PgfSteward => GovernanceProposalKindDb::PgfSteward,
ProposalKind::PgfFunding => GovernanceProposalKindDb::PgfFunding,
});
let kind = self.map_kind(kind);
let status = self.map_status(status);

let (db_proposals, total_pages, total_items) = self
.governance_repo
Expand Down Expand Up @@ -98,6 +68,46 @@ impl GovernanceService {
))
}

pub async fn find_all_governance_proposals(
&self,
status: Option<ProposalStatus>,
kind: Option<ProposalKind>,
pattern: Option<String>,
) -> Result<Vec<Proposal>, GovernanceError> {
let kind = self.map_kind(kind);
let status = self.map_status(status);

let db_proposals = self
.governance_repo
.find_all_governance_proposals(status, kind, pattern)
.await
.map_err(GovernanceError::Database)?;

let chain_state = self
.chain_repo
.get_chain_state()
.await
.map_err(GovernanceError::Database)?;

let parameters = self
.chain_repo
.find_chain_parameters()
.await
.map_err(GovernanceError::Database)?;

Ok(db_proposals
.into_iter()
.map(|p| {
Proposal::from_proposal_db(
p,
&chain_state,
parameters.min_num_of_blocks,
parameters.min_duration,
)
})
.collect())
}

pub async fn find_governance_proposal_by_id(
&self,
proposal_id: u64,
Expand Down Expand Up @@ -206,4 +216,32 @@ impl GovernanceService {
.map(ProposalVote::from)
.collect())
}

fn map_status(
&self,
status: Option<ProposalStatus>,
) -> Option<GovernanceProposalResultDb> {
status.map(|s| match s {
ProposalStatus::Pending => GovernanceProposalResultDb::Pending,
ProposalStatus::VotingPeriod => {
GovernanceProposalResultDb::VotingPeriod
}
ProposalStatus::Passed => GovernanceProposalResultDb::Passed,
ProposalStatus::Rejected => GovernanceProposalResultDb::Rejected,
})
}

fn map_kind(
&self,
kind: Option<ProposalKind>,
) -> Option<GovernanceProposalKindDb> {
kind.map(|t| match t {
ProposalKind::Default => GovernanceProposalKindDb::Default,
ProposalKind::DefaultWithWasm => {
GovernanceProposalKindDb::DefaultWithWasm
}
ProposalKind::PgfSteward => GovernanceProposalKindDb::PgfSteward,
ProposalKind::PgfFunding => GovernanceProposalKindDb::PgfFunding,
})
}
}
Loading