Skip to content

Commit

Permalink
proto: change BalancesResponse to have Views
Browse files Browse the repository at this point in the history
  • Loading branch information
grod220 committed Feb 23, 2024
1 parent bcff1a8 commit 5e7808a
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 73 deletions.
15 changes: 15 additions & 0 deletions crates/proto/src/gen/penumbra.view.v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,10 +552,25 @@ impl ::prost::Name for BalancesRequest {
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct BalancesResponse {
/// Deprecated: use `account_address` instead.
#[deprecated]
#[prost(message, optional, tag = "1")]
pub account: ::core::option::Option<super::super::core::keys::v1::AddressIndex>,
/// Deprecated: use `balance_view` instead.
#[deprecated]
#[prost(message, optional, tag = "2")]
pub balance: ::core::option::Option<super::super::core::asset::v1::Value>,
/// The default address for the account.
///
/// Note that the returned balance is for all funds sent to the account,
/// not just funds sent to its default address.
#[prost(message, optional, tag = "3")]
pub account_address: ::core::option::Option<
super::super::core::keys::v1::AddressView,
>,
/// The account's balance, with metadata.
#[prost(message, optional, tag = "4")]
pub balance_view: ::core::option::Option<super::super::core::asset::v1::ValueView>,
}
impl ::prost::Name for BalancesResponse {
const NAME: &'static str = "BalancesResponse";
Expand Down
36 changes: 36 additions & 0 deletions crates/proto/src/gen/penumbra.view.v1.serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1377,13 +1377,25 @@ impl serde::Serialize for BalancesResponse {
if self.balance.is_some() {
len += 1;
}
if self.account_address.is_some() {
len += 1;
}
if self.balance_view.is_some() {
len += 1;
}
let mut struct_ser = serializer.serialize_struct("penumbra.view.v1.BalancesResponse", len)?;
if let Some(v) = self.account.as_ref() {
struct_ser.serialize_field("account", v)?;
}
if let Some(v) = self.balance.as_ref() {
struct_ser.serialize_field("balance", v)?;
}
if let Some(v) = self.account_address.as_ref() {
struct_ser.serialize_field("accountAddress", v)?;
}
if let Some(v) = self.balance_view.as_ref() {
struct_ser.serialize_field("balanceView", v)?;
}
struct_ser.end()
}
}
Expand All @@ -1396,12 +1408,18 @@ impl<'de> serde::Deserialize<'de> for BalancesResponse {
const FIELDS: &[&str] = &[
"account",
"balance",
"account_address",
"accountAddress",
"balance_view",
"balanceView",
];

#[allow(clippy::enum_variant_names)]
enum GeneratedField {
Account,
Balance,
AccountAddress,
BalanceView,
__SkipField__,
}
impl<'de> serde::Deserialize<'de> for GeneratedField {
Expand All @@ -1426,6 +1444,8 @@ impl<'de> serde::Deserialize<'de> for BalancesResponse {
match value {
"account" => Ok(GeneratedField::Account),
"balance" => Ok(GeneratedField::Balance),
"accountAddress" | "account_address" => Ok(GeneratedField::AccountAddress),
"balanceView" | "balance_view" => Ok(GeneratedField::BalanceView),
_ => Ok(GeneratedField::__SkipField__),
}
}
Expand All @@ -1447,6 +1467,8 @@ impl<'de> serde::Deserialize<'de> for BalancesResponse {
{
let mut account__ = None;
let mut balance__ = None;
let mut account_address__ = None;
let mut balance_view__ = None;
while let Some(k) = map_.next_key()? {
match k {
GeneratedField::Account => {
Expand All @@ -1461,6 +1483,18 @@ impl<'de> serde::Deserialize<'de> for BalancesResponse {
}
balance__ = map_.next_value()?;
}
GeneratedField::AccountAddress => {
if account_address__.is_some() {
return Err(serde::de::Error::duplicate_field("accountAddress"));
}
account_address__ = map_.next_value()?;
}
GeneratedField::BalanceView => {
if balance_view__.is_some() {
return Err(serde::de::Error::duplicate_field("balanceView"));
}
balance_view__ = map_.next_value()?;
}
GeneratedField::__SkipField__ => {
let _ = map_.next_value::<serde::de::IgnoredAny>()?;
}
Expand All @@ -1469,6 +1503,8 @@ impl<'de> serde::Deserialize<'de> for BalancesResponse {
Ok(BalancesResponse {
account: account__,
balance: balance__,
account_address: account_address__,
balance_view: balance_view__,
})
}
}
Expand Down
Binary file modified crates/proto/src/gen/proto_descriptor.bin.no_lfs
Binary file not shown.
39 changes: 17 additions & 22 deletions crates/view/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use tracing::instrument;

use penumbra_app::params::AppParameters;
use penumbra_asset::asset::{self, Id, Metadata};
use penumbra_asset::ValueView;
use penumbra_dex::{
lp::position::{self},
TradingPair,
Expand All @@ -15,8 +16,8 @@ use penumbra_fee::GasPrices;
use penumbra_keys::{keys::AddressIndex, Address};
use penumbra_num::Amount;
use penumbra_proto::view::v1::{
self as pb, view_service_client::ViewServiceClient, BroadcastTransactionResponse,
WitnessRequest,
self as pb, view_service_client::ViewServiceClient, BalancesResponse,
BroadcastTransactionResponse, WitnessRequest,
};
use penumbra_sct::Nullifier;
use penumbra_shielded_pool::{fmd, note};
Expand Down Expand Up @@ -503,26 +504,19 @@ where
}),
);

let balances: Vec<_> = req.await?.into_inner().try_collect().await?;
let balances: Vec<BalancesResponse> = req.await?.into_inner().try_collect().await?;

balances
.into_iter()
.map(|rsp| {
let balance = rsp
.balance
.ok_or_else(|| anyhow::anyhow!("empty balance type"))?;

let asset = balance
.asset_id
.ok_or_else(|| anyhow::anyhow!("empty asset type"))?
.try_into()?;

let amount = balance
.amount
.ok_or_else(|| anyhow::anyhow!("empty amount type"))?
.try_into()?;

Ok((asset, amount))
let pb_value_view = rsp
.balance_view
.ok_or_else(|| anyhow::anyhow!("empty balance view"))?;

let value_view: ValueView = pb_value_view.try_into()?;
let id = value_view.asset_id();
let amount = value_view.value().amount;
Ok((id, amount))
})
.collect()
}
Expand Down Expand Up @@ -869,26 +863,27 @@ where
Some(status) => match status {
pb::witness_and_build_response::Status::BuildProgress(_) => {
// TODO: should update progress here
},
}
pb::witness_and_build_response::Status::Complete(c) => {
return c.transaction
.ok_or_else(|| {
anyhow::anyhow!("WitnessAndBuildResponse complete status message missing transaction")
})?
.try_into();
},
}
},
None => {
// No status is unexpected behavior
return Err(anyhow::anyhow!(
"empty WitnessAndBuildResponse message"
));},
));
}
}
}

Err(anyhow::anyhow!("should have received complete status or error"))
}
.boxed()
.boxed()
}

fn unclaimed_swaps(
Expand Down
57 changes: 51 additions & 6 deletions crates/view/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use tonic::{async_trait, transport::Channel, Request, Response, Status};
use tracing::instrument;
use url::Url;

use penumbra_asset::asset::Metadata;
use penumbra_asset::{asset, Value};
use penumbra_dex::{
lp::{
Expand All @@ -28,6 +29,8 @@ use penumbra_dex::{
TradingPair,
};
use penumbra_fee::Fee;
use penumbra_keys::keys::WalletId;
use penumbra_keys::AddressView;
use penumbra_keys::{
keys::{AddressIndex, FullViewingKey},
Address,
Expand Down Expand Up @@ -918,6 +921,7 @@ impl ViewService for ViewServer {
}))
}

#[allow(deprecated)]
#[instrument(skip(self, request))]
async fn balances(
&self,
Expand Down Expand Up @@ -949,15 +953,56 @@ impl ViewService for ViewServer {

tracing::debug!(?account_filter, ?asset_id_filter, ?result);

let self2 = self.clone();
let stream = try_stream! {
// retrieve balance and address views
for element in result {
yield pb::BalancesResponse {
account: account_filter.clone().map(Into::into),
balance: Some(Value {
asset_id: element.0.into(),
amount: element.1.into(),
}.into()),
let metadata: Metadata = self2
.asset_metadata_by_id(Request::new(pb::AssetMetadataByIdRequest {
asset_id: Some(element.id.into()),
}))
.await?
.into_inner()
.denom_metadata
.context("denom metadata not found")?
.try_into()?;

let value = Value {
asset_id: element.id,
amount: element.amount.into(),
};

let value_view = value.view_with_denom(metadata)?;

let address: Address = self2
.address_by_index(Request::new(pb::AddressByIndexRequest {
address_index: account_filter.map(Into::into),
}))
.await?
.into_inner()
.address
.context("address not found")?
.try_into()?;

let wallet_id: WalletId = self2
.wallet_id(Request::new(pb::WalletIdRequest {}))
.await?
.into_inner()
.wallet_id
.context("wallet id not found")?
.try_into()?;

let address_view = AddressView::Decoded {
address,
index: element.address_index,
wallet_id,
};

yield pb::BalancesResponse {
account_address: Some(address_view.into()),
balance_view: Some(value_view.into()),
balance: None,
account: None,
}
}
};
Expand Down
Loading

0 comments on commit 5e7808a

Please sign in to comment.