From 2418bba8174d08c8a04df723871f83176e72c70c Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Mon, 22 Apr 2024 05:56:31 -0700 Subject: [PATCH] view server auction stubs --- crates/bin/pcli/src/command/query.rs | 35 ++++++++----- crates/bin/pcli/src/command/query/auction.rs | 52 ++++++++++++++++++++ crates/view/src/client.rs | 34 ++++++++++++- crates/view/src/service.rs | 17 ++++++- crates/view/src/storage.rs | 9 ++++ 5 files changed, 133 insertions(+), 14 deletions(-) create mode 100644 crates/bin/pcli/src/command/query/auction.rs diff --git a/crates/bin/pcli/src/command/query.rs b/crates/bin/pcli/src/command/query.rs index a096c9239a..d8d05c41ba 100644 --- a/crates/bin/pcli/src/command/query.rs +++ b/crates/bin/pcli/src/command/query.rs @@ -1,22 +1,25 @@ use anyhow::{anyhow, Context, Result}; +mod auction; +mod chain; +mod community_pool; +mod dex; +mod governance; +mod ibc_query; mod shielded_pool; -use colored_json::ToColoredJson; -use shielded_pool::ShieldedPool; mod tx; -use tx::Tx; -mod chain; +mod validator; + +use auction::AuctionCmd; use chain::ChainCmd; -mod dex; +use colored_json::ToColoredJson; +use community_pool::CommunityPoolCmd; use dex::DexCmd; -mod governance; use governance::GovernanceCmd; -mod community_pool; -use community_pool::CommunityPoolCmd; -mod validator; -pub(super) use validator::ValidatorCmd; -mod ibc_query; use ibc_query::IbcCmd; +use shielded_pool::ShieldedPool; +use tx::Tx; +pub(super) use validator::ValidatorCmd; use crate::App; @@ -75,6 +78,9 @@ pub enum QueryCmd { #[clap(long, default_value = "")] nv_key_regex: String, }, + /// Queries information about a Dutch auction. + #[clap(subcommand)] + Auction(AuctionCmd), } impl QueryCmd { @@ -116,6 +122,10 @@ impl QueryCmd { return ibc.exec(app).await; } + if let QueryCmd::Auction(AuctionCmd::Dutch(auction)) = self { + return auction.exec(app).await; + } + // TODO: this is a hack; we should replace all raw state key uses with RPC methods. if let QueryCmd::ShieldedPool(ShieldedPool::CompactBlock { height }) = self { use penumbra_proto::core::component::compact_block::v1::{ @@ -143,6 +153,7 @@ impl QueryCmd { | QueryCmd::Governance(_) | QueryCmd::CommunityPool(_) | QueryCmd::Watch { .. } + | QueryCmd::Auction { .. } | QueryCmd::Ibc(_) => { unreachable!("query handled in guard"); } @@ -181,6 +192,7 @@ impl QueryCmd { | QueryCmd::Governance { .. } | QueryCmd::Key { .. } | QueryCmd::Watch { .. } + | QueryCmd::Auction { .. } | QueryCmd::Ibc(_) => true, } } @@ -198,6 +210,7 @@ impl QueryCmd { | QueryCmd::Governance { .. } | QueryCmd::CommunityPool { .. } | QueryCmd::Watch { .. } + | QueryCmd::Auction { .. } | QueryCmd::Ibc(_) => { unreachable!("query is special cased") } diff --git a/crates/bin/pcli/src/command/query/auction.rs b/crates/bin/pcli/src/command/query/auction.rs new file mode 100644 index 0000000000..db8ab9478b --- /dev/null +++ b/crates/bin/pcli/src/command/query/auction.rs @@ -0,0 +1,52 @@ +use crate::App; +use anyhow::Context; +use clap::Subcommand; +use penumbra_asset::{asset, Value}; +use penumbra_auction::auction::AuctionId; +use penumbra_keys::keys::AddressIndex; +use penumbra_num::Amount; +use penumbra_proto::view::v1::GasPricesRequest; +use penumbra_view::ViewClient; +use penumbra_wallet::plan::Planner; +use rand_core::OsRng; + +#[derive(Debug, Subcommand)] +pub enum AuctionCmd { + /// Commands related to Dutch auctions + #[clap(display_order = 100, subcommand)] + Dutch(DutchCmd), +} + +/// Commands related to querying Dutch auctions. +#[derive(Debug, Subcommand)] +pub enum DutchCmd { + /// Withdraws the reserves of the Dutch auction. + #[clap(display_order = 100, name = "id")] + DutchAuctionQueryId { + /// The auction to withdraw funds from. + #[clap(long, display_order = 100)] + auction_id: String, + }, +} + +impl DutchCmd { + /// Process the command by performing the appropriate action. + pub async fn exec(&self, app: &mut App) -> anyhow::Result<()> { + match self { + DutchCmd::DutchAuctionQueryId { auction_id } => { + let auction_id = auction_id.parse::()?; + + // Query stateful auction information from view server + let client = app.view().auctions_by_id(auction_id).await?; + + let dutch_auction = &client[0]; + + println!( + "Dutch auction description and state: {:?} and {:?}", + dutch_auction.description, dutch_auction.state + ); + } + } + Ok(()) + } +} diff --git a/crates/view/src/client.rs b/crates/view/src/client.rs index 4de810c8b6..90ea250cae 100644 --- a/crates/view/src/client.rs +++ b/crates/view/src/client.rs @@ -2,6 +2,8 @@ use std::{collections::BTreeMap, future::Future, pin::Pin}; use anyhow::Result; use futures::{FutureExt, Stream, StreamExt, TryStreamExt}; +use penumbra_auction::auction::{dutch::{DutchAuction, DutchAuctionState}, AuctionId}; +use penumbra_tct::Position; use tonic::{codegen::Bytes, Streaming}; use tracing::instrument; @@ -17,10 +19,10 @@ use penumbra_dex::{ use penumbra_fee::GasPrices; use penumbra_keys::{keys::AddressIndex, Address}; use penumbra_num::Amount; -use penumbra_proto::view::v1::{ +use penumbra_proto::{core::component::auction, serializers::bech32str::auction_id, view::v1::{ self as pb, view_service_client::ViewServiceClient, BalancesResponse, BroadcastTransactionResponse, WitnessRequest, -}; +}}; use penumbra_sct::Nullifier; use penumbra_shielded_pool::{fmd, note}; use penumbra_stake::IdentityKey; @@ -306,6 +308,12 @@ pub trait ViewClient { fn unclaimed_swaps( &mut self, ) -> Pin>> + Send + 'static>>; + + /// Queries for auctions controlled by the user's wallet. + fn auctions_by_index(&mut self, address_index: AddressIndex) -> Pin>> + Send + 'static>>; + + /// Queries for auctions controlled by the user's wallet. + fn auctions_by_id(&mut self, auction_id: AuctionId) -> Pin>> + Send + 'static>>; } // We need to tell `async_trait` not to add a `Send` bound to the boxed @@ -915,4 +923,26 @@ where } .boxed() } + + fn auctions_by_index( + &mut self, + address_index: AddressIndex + ) -> Pin>> + Send + 'static>> { + let _ = address_index; + let _request = pb::AuctionsRequest { + account_filter: todo!(), + include_inactive: todo!(), + query_latest_state: todo!(), + }; + + // TODO: craft a tonic request and handle responses. + } + + fn auctions_by_id( + &mut self, + _auction_id: AuctionId + ) -> Pin>> + Send + 'static>> { + // TODO: fill in stub for `pcli query auction id AUCTION_ID` (#4243) + todo!(); + } } diff --git a/crates/view/src/service.rs b/crates/view/src/service.rs index 5f66711c15..3708ec2dea 100644 --- a/crates/view/src/service.rs +++ b/crates/view/src/service.rs @@ -10,6 +10,7 @@ use async_stream::try_stream; use camino::Utf8Path; use decaf377::Fq; use futures::stream::{StreamExt, TryStreamExt}; +use penumbra_auction::auction; use rand::Rng; use rand_core::OsRng; use tokio::sync::{watch, RwLock}; @@ -394,7 +395,21 @@ impl ViewService for ViewServer { &self, _request: tonic::Request, ) -> Result, tonic::Status> { - unimplemented!("auctions") + let _auction = self.storage.auction_by_address().await.map_err(|_| { + tonic::Status::failed_precondition("Error retrieving auction information.") + })?; + + let stream = try_stream! { + yield pb::AuctionsResponse { id: todo!(), note_record: todo!(), auction: todo!(), positions: todo!() } + }; + + Ok(tonic::Response::new( + stream + .map_err(|e: anyhow::Error| { + tonic::Status::unavailable(format!("error getting auction: {e}")) + }) + .boxed(), + )) } async fn broadcast_transaction( diff --git a/crates/view/src/storage.rs b/crates/view/src/storage.rs index 7b8b0819e7..da7937b14a 100644 --- a/crates/view/src/storage.rs +++ b/crates/view/src/storage.rs @@ -6,6 +6,8 @@ use camino::Utf8Path; use decaf377::{FieldExt, Fq}; use once_cell::sync::Lazy; use parking_lot::Mutex; +use penumbra_auction::auction::dutch::DutchAuctionState; +use penumbra_auction::auction::AuctionId; use r2d2_sqlite::{ rusqlite::{OpenFlags, OptionalExtension}, SqliteConnectionManager, @@ -1592,4 +1594,11 @@ impl Storage { Ok(records) } + + pub async fn auction_by_address( + &self, + ) -> anyhow::Result> { + // TODO: Add a sqlite table to track auction state/ + todo!() + } }