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

auction: pd service rpc #4233

Merged
merged 11 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from 9 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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/core/component/auction/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ tendermint = {workspace = true, default-features = true}
tokio = {workspace = true, features = ["full", "tracing"], optional = true}
tonic = {workspace = true, optional = true}
tracing = {workspace = true}
pbjson-types = "0.6.0"

[dev-dependencies]
ed25519-consensus = {workspace = true}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use anyhow::Result;
use async_trait::async_trait;
use cnidarium::StateRead;
use pbjson_types::Any;
use penumbra_proto::core::component::auction::v1alpha1 as pb;
use penumbra_proto::DomainType;
use penumbra_proto::Name;
use penumbra_proto::StateReadProto;
use prost_types::Any;

use crate::{
auction::{dutch::DutchAuction, id::AuctionId},
Expand Down
50 changes: 47 additions & 3 deletions crates/core/component/auction/src/component/rpc.rs
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
#![allow(unused)] // TODO: remove this when filling in the RPCs

use penumbra_proto::{
core::component::auction::v1alpha1::query_service_server::QueryService, DomainType,
core::component::auction::v1alpha1::{
query_service_server::QueryService, AuctionStateByIdRequest, AuctionStateByIdResponse,
AuctionStateByIdsRequest, AuctionStateByIdsResponse, DutchAuctionState,
},
DomainType,
};

use async_stream::try_stream;
use cnidarium::Storage;
use futures::{StreamExt, TryStreamExt};
use penumbra_proto::Message;
use std::pin::Pin;
use tonic::Status;
use tracing::instrument;

use super::AuctionStoreRead;
use cnidarium::Storage;

pub struct Server {
storage: Storage,
}
Expand All @@ -22,4 +29,41 @@ impl Server {
}

#[tonic::async_trait]
impl QueryService for Server {}
impl QueryService for Server {
#[instrument(skip(self, request))]
async fn auction_state_by_id(
&self,
request: tonic::Request<AuctionStateByIdRequest>,
) -> Result<tonic::Response<AuctionStateByIdResponse>, Status> {
let state = self.storage.latest_snapshot();
let request = request.into_inner();

let id = request
.id
.ok_or_else(|| Status::invalid_argument("missing auction id"))?
.try_into()
.map_err(|_| Status::invalid_argument("invalid auction id"))?;

let auction_data = state
.get_raw_auction(id)
.await
.ok_or_else(|| tonic::Status::not_found("auction data not found for specified id"))?;

Ok(tonic::Response::new(AuctionStateByIdResponse {
auction: Some(auction_data),
positions: Vec::new(),
}))
}

type AuctionStateByIdsStream = Pin<
Box<dyn futures::Stream<Item = Result<AuctionStateByIdsResponse, tonic::Status>> + Send>,
>;

#[instrument(skip(self, request))]
async fn auction_state_by_ids(
&self,
request: tonic::Request<AuctionStateByIdsRequest>,
) -> Result<tonic::Response<Self::AuctionStateByIdsStream>, Status> {
todo!()
erwanor marked this conversation as resolved.
Show resolved Hide resolved
}
}
266 changes: 263 additions & 3 deletions crates/proto/src/gen/penumbra.core.component.auction.v1alpha1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,82 @@ impl ::prost::Name for GenesisContent {
)
}
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AuctionStateByIdRequest {
#[prost(message, optional, tag = "1")]
pub id: ::core::option::Option<AuctionId>,
}
impl ::prost::Name for AuctionStateByIdRequest {
const NAME: &'static str = "AuctionStateByIdRequest";
const PACKAGE: &'static str = "penumbra.core.component.auction.v1alpha1";
fn full_name() -> ::prost::alloc::string::String {
::prost::alloc::format!(
"penumbra.core.component.auction.v1alpha1.{}", Self::NAME
)
}
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AuctionStateByIdResponse {
/// If present, the state of the auction. If not present, no such auction is known.
#[prost(message, optional, tag = "2")]
pub auction: ::core::option::Option<::pbjson_types::Any>,
/// The state of any DEX positions relevant to the returned auction.
///
/// Could be empty, depending on the auction state.
#[prost(message, repeated, tag = "3")]
pub positions: ::prost::alloc::vec::Vec<super::super::dex::v1::Position>,
}
impl ::prost::Name for AuctionStateByIdResponse {
const NAME: &'static str = "AuctionStateByIdResponse";
const PACKAGE: &'static str = "penumbra.core.component.auction.v1alpha1";
fn full_name() -> ::prost::alloc::string::String {
::prost::alloc::format!(
"penumbra.core.component.auction.v1alpha1.{}", Self::NAME
)
}
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AuctionStateByIdsRequest {
/// The auction IDs to request. Only known IDs will be returned in the response.
#[prost(message, repeated, tag = "1")]
pub id: ::prost::alloc::vec::Vec<AuctionId>,
}
impl ::prost::Name for AuctionStateByIdsRequest {
const NAME: &'static str = "AuctionStateByIdsRequest";
const PACKAGE: &'static str = "penumbra.core.component.auction.v1alpha1";
fn full_name() -> ::prost::alloc::string::String {
::prost::alloc::format!(
"penumbra.core.component.auction.v1alpha1.{}", Self::NAME
)
}
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AuctionStateByIdsResponse {
/// The auction ID of the returned auction.
#[prost(message, optional, tag = "1")]
pub id: ::core::option::Option<AuctionId>,
/// The state of the returned auction.
#[prost(message, optional, tag = "2")]
pub auction: ::core::option::Option<DutchAuctionState>,
/// The state of any DEX positions relevant to the returned auction.
///
/// Could be empty, depending on the auction state.
#[prost(message, repeated, tag = "3")]
pub positions: ::prost::alloc::vec::Vec<super::super::dex::v1::Position>,
}
impl ::prost::Name for AuctionStateByIdsResponse {
const NAME: &'static str = "AuctionStateByIdsResponse";
const PACKAGE: &'static str = "penumbra.core.component.auction.v1alpha1";
fn full_name() -> ::prost::alloc::string::String {
::prost::alloc::format!(
"penumbra.core.component.auction.v1alpha1.{}", Self::NAME
)
}
}
/// A unique identifier for an auction, obtained from hashing a domain separator
/// along with the immutable part of an auction description.
#[allow(clippy::derive_partial_eq_without_eq)]
Expand Down Expand Up @@ -281,7 +357,7 @@ pub mod query_service_client {
#![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
use tonic::codegen::*;
use tonic::codegen::http::Uri;
/// Query operations for the Auction component.
/// Query operations for the auction component.
#[derive(Debug, Clone)]
pub struct QueryServiceClient<T> {
inner: tonic::client::Grpc<T>,
Expand Down Expand Up @@ -362,6 +438,68 @@ pub mod query_service_client {
self.inner = self.inner.max_encoding_message_size(limit);
self
}
/// Get the current state of an auction by ID.
pub async fn auction_state_by_id(
&mut self,
request: impl tonic::IntoRequest<super::AuctionStateByIdRequest>,
) -> std::result::Result<
tonic::Response<super::AuctionStateByIdResponse>,
tonic::Status,
> {
self.inner
.ready()
.await
.map_err(|e| {
tonic::Status::new(
tonic::Code::Unknown,
format!("Service was not ready: {}", e.into()),
)
})?;
let codec = tonic::codec::ProstCodec::default();
let path = http::uri::PathAndQuery::from_static(
"/penumbra.core.component.auction.v1alpha1.QueryService/AuctionStateById",
);
let mut req = request.into_request();
req.extensions_mut()
.insert(
GrpcMethod::new(
"penumbra.core.component.auction.v1alpha1.QueryService",
"AuctionStateById",
),
);
self.inner.unary(req, path, codec).await
}
/// Get the current state of a group of auctions by ID.
pub async fn auction_state_by_ids(
&mut self,
request: impl tonic::IntoRequest<super::AuctionStateByIdsRequest>,
) -> std::result::Result<
tonic::Response<tonic::codec::Streaming<super::AuctionStateByIdsResponse>>,
tonic::Status,
> {
self.inner
.ready()
.await
.map_err(|e| {
tonic::Status::new(
tonic::Code::Unknown,
format!("Service was not ready: {}", e.into()),
)
})?;
let codec = tonic::codec::ProstCodec::default();
let path = http::uri::PathAndQuery::from_static(
"/penumbra.core.component.auction.v1alpha1.QueryService/AuctionStateByIds",
);
let mut req = request.into_request();
req.extensions_mut()
.insert(
GrpcMethod::new(
"penumbra.core.component.auction.v1alpha1.QueryService",
"AuctionStateByIds",
),
);
self.inner.server_streaming(req, path, codec).await
}
}
}
/// Generated server implementations.
Expand All @@ -371,8 +509,34 @@ pub mod query_service_server {
use tonic::codegen::*;
/// Generated trait containing gRPC methods that should be implemented for use with QueryServiceServer.
#[async_trait]
pub trait QueryService: Send + Sync + 'static {}
/// Query operations for the Auction component.
pub trait QueryService: Send + Sync + 'static {
/// Get the current state of an auction by ID.
async fn auction_state_by_id(
&self,
request: tonic::Request<super::AuctionStateByIdRequest>,
) -> std::result::Result<
tonic::Response<super::AuctionStateByIdResponse>,
tonic::Status,
>;
/// Server streaming response type for the AuctionStateByIds method.
type AuctionStateByIdsStream: tonic::codegen::tokio_stream::Stream<
Item = std::result::Result<
super::AuctionStateByIdsResponse,
tonic::Status,
>,
>
+ Send
+ 'static;
/// Get the current state of a group of auctions by ID.
async fn auction_state_by_ids(
&self,
request: tonic::Request<super::AuctionStateByIdsRequest>,
) -> std::result::Result<
tonic::Response<Self::AuctionStateByIdsStream>,
tonic::Status,
>;
}
/// Query operations for the auction component.
#[derive(Debug)]
pub struct QueryServiceServer<T: QueryService> {
inner: _Inner<T>,
Expand Down Expand Up @@ -452,6 +616,102 @@ pub mod query_service_server {
fn call(&mut self, req: http::Request<B>) -> Self::Future {
let inner = self.inner.clone();
match req.uri().path() {
"/penumbra.core.component.auction.v1alpha1.QueryService/AuctionStateById" => {
#[allow(non_camel_case_types)]
struct AuctionStateByIdSvc<T: QueryService>(pub Arc<T>);
impl<
T: QueryService,
> tonic::server::UnaryService<super::AuctionStateByIdRequest>
for AuctionStateByIdSvc<T> {
type Response = super::AuctionStateByIdResponse;
type Future = BoxFuture<
tonic::Response<Self::Response>,
tonic::Status,
>;
fn call(
&mut self,
request: tonic::Request<super::AuctionStateByIdRequest>,
) -> Self::Future {
let inner = Arc::clone(&self.0);
let fut = async move {
<T as QueryService>::auction_state_by_id(&inner, request)
.await
};
Box::pin(fut)
}
}
let accept_compression_encodings = self.accept_compression_encodings;
let send_compression_encodings = self.send_compression_encodings;
let max_decoding_message_size = self.max_decoding_message_size;
let max_encoding_message_size = self.max_encoding_message_size;
let inner = self.inner.clone();
let fut = async move {
let inner = inner.0;
let method = AuctionStateByIdSvc(inner);
let codec = tonic::codec::ProstCodec::default();
let mut grpc = tonic::server::Grpc::new(codec)
.apply_compression_config(
accept_compression_encodings,
send_compression_encodings,
)
.apply_max_message_size_config(
max_decoding_message_size,
max_encoding_message_size,
);
let res = grpc.unary(method, req).await;
Ok(res)
};
Box::pin(fut)
}
"/penumbra.core.component.auction.v1alpha1.QueryService/AuctionStateByIds" => {
#[allow(non_camel_case_types)]
struct AuctionStateByIdsSvc<T: QueryService>(pub Arc<T>);
impl<
T: QueryService,
> tonic::server::ServerStreamingService<
super::AuctionStateByIdsRequest,
> for AuctionStateByIdsSvc<T> {
type Response = super::AuctionStateByIdsResponse;
type ResponseStream = T::AuctionStateByIdsStream;
type Future = BoxFuture<
tonic::Response<Self::ResponseStream>,
tonic::Status,
>;
fn call(
&mut self,
request: tonic::Request<super::AuctionStateByIdsRequest>,
) -> Self::Future {
let inner = Arc::clone(&self.0);
let fut = async move {
<T as QueryService>::auction_state_by_ids(&inner, request)
.await
};
Box::pin(fut)
}
}
let accept_compression_encodings = self.accept_compression_encodings;
let send_compression_encodings = self.send_compression_encodings;
let max_decoding_message_size = self.max_decoding_message_size;
let max_encoding_message_size = self.max_encoding_message_size;
let inner = self.inner.clone();
let fut = async move {
let inner = inner.0;
let method = AuctionStateByIdsSvc(inner);
let codec = tonic::codec::ProstCodec::default();
let mut grpc = tonic::server::Grpc::new(codec)
.apply_compression_config(
accept_compression_encodings,
send_compression_encodings,
)
.apply_max_message_size_config(
max_decoding_message_size,
max_encoding_message_size,
);
let res = grpc.server_streaming(method, req).await;
Ok(res)
};
Box::pin(fut)
}
_ => {
Box::pin(async move {
Ok(
Expand Down
Loading