Skip to content

Commit

Permalink
proto: add spend to TransactionPlannerRequest (#4615)
Browse files Browse the repository at this point in the history
## Describe your changes

previously, there wasn't an need to explicitly specify a _spend_ as a
user intent until non-zero fees were introduced. In that context, this
proto-related modification is necessary in order to allow a user to send
an _entire_ balance for a specific asset.

## Issue ticket number and link

## Checklist before requesting a review

- [x] If this code contains consensus-breaking changes, I have added the
"consensus-breaking" label. Otherwise, I declare my belief that there
are not consensus-breaking changes, for the following reason:
  • Loading branch information
TalDerei committed Jun 16, 2024
1 parent c59e5d0 commit d098f23
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 2 deletions.
23 changes: 23 additions & 0 deletions crates/proto/src/gen/penumbra.view.v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ pub struct TransactionPlannerRequest {
/// Request contents
#[prost(message, repeated, tag = "20")]
pub outputs: ::prost::alloc::vec::Vec<transaction_planner_request::Output>,
#[prost(message, repeated, tag = "21")]
pub spends: ::prost::alloc::vec::Vec<transaction_planner_request::Spend>,
#[prost(message, repeated, tag = "30")]
pub swaps: ::prost::alloc::vec::Vec<transaction_planner_request::Swap>,
#[prost(message, repeated, tag = "31")]
Expand Down Expand Up @@ -328,6 +330,27 @@ pub mod transaction_planner_request {
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Spend {
/// The input amount and denomination in which the Spend is issued.
#[prost(message, optional, tag = "1")]
pub value: ::core::option::Option<super::super::super::core::asset::v1::Value>,
/// The source address from which the Spend will be sent.
#[prost(message, optional, tag = "2")]
pub address: ::core::option::Option<
super::super::super::core::keys::v1::Address,
>,
}
impl ::prost::Name for Spend {
const NAME: &'static str = "Spend";
const PACKAGE: &'static str = "penumbra.view.v1";
fn full_name() -> ::prost::alloc::string::String {
::prost::alloc::format!(
"penumbra.view.v1.TransactionPlannerRequest.{}", Self::NAME
)
}
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Swap {
/// The input amount and denomination to be traded in the Swap.
#[prost(message, optional, tag = "1")]
Expand Down
129 changes: 129 additions & 0 deletions crates/proto/src/gen/penumbra.view.v1.serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6068,6 +6068,9 @@ impl serde::Serialize for TransactionPlannerRequest {
if !self.outputs.is_empty() {
len += 1;
}
if !self.spends.is_empty() {
len += 1;
}
if !self.swaps.is_empty() {
len += 1;
}
Expand Down Expand Up @@ -6130,6 +6133,9 @@ impl serde::Serialize for TransactionPlannerRequest {
if !self.outputs.is_empty() {
struct_ser.serialize_field("outputs", &self.outputs)?;
}
if !self.spends.is_empty() {
struct_ser.serialize_field("spends", &self.spends)?;
}
if !self.swaps.is_empty() {
struct_ser.serialize_field("swaps", &self.swaps)?;
}
Expand Down Expand Up @@ -6201,6 +6207,7 @@ impl<'de> serde::Deserialize<'de> for TransactionPlannerRequest {
"memo",
"source",
"outputs",
"spends",
"swaps",
"swap_claims",
"swapClaims",
Expand Down Expand Up @@ -6239,6 +6246,7 @@ impl<'de> serde::Deserialize<'de> for TransactionPlannerRequest {
Memo,
Source,
Outputs,
Spends,
Swaps,
SwapClaims,
Delegations,
Expand Down Expand Up @@ -6282,6 +6290,7 @@ impl<'de> serde::Deserialize<'de> for TransactionPlannerRequest {
"memo" => Ok(GeneratedField::Memo),
"source" => Ok(GeneratedField::Source),
"outputs" => Ok(GeneratedField::Outputs),
"spends" => Ok(GeneratedField::Spends),
"swaps" => Ok(GeneratedField::Swaps),
"swapClaims" | "swap_claims" => Ok(GeneratedField::SwapClaims),
"delegations" => Ok(GeneratedField::Delegations),
Expand Down Expand Up @@ -6322,6 +6331,7 @@ impl<'de> serde::Deserialize<'de> for TransactionPlannerRequest {
let mut memo__ = None;
let mut source__ = None;
let mut outputs__ = None;
let mut spends__ = None;
let mut swaps__ = None;
let mut swap_claims__ = None;
let mut delegations__ = None;
Expand Down Expand Up @@ -6366,6 +6376,12 @@ impl<'de> serde::Deserialize<'de> for TransactionPlannerRequest {
}
outputs__ = Some(map_.next_value()?);
}
GeneratedField::Spends => {
if spends__.is_some() {
return Err(serde::de::Error::duplicate_field("spends"));
}
spends__ = Some(map_.next_value()?);
}
GeneratedField::Swaps => {
if swaps__.is_some() {
return Err(serde::de::Error::duplicate_field("swaps"));
Expand Down Expand Up @@ -6482,6 +6498,7 @@ impl<'de> serde::Deserialize<'de> for TransactionPlannerRequest {
memo: memo__,
source: source__,
outputs: outputs__.unwrap_or_default(),
spends: spends__.unwrap_or_default(),
swaps: swaps__.unwrap_or_default(),
swap_claims: swap_claims__.unwrap_or_default(),
delegations: delegations__.unwrap_or_default(),
Expand Down Expand Up @@ -7358,6 +7375,118 @@ impl<'de> serde::Deserialize<'de> for transaction_planner_request::PositionWithd
deserializer.deserialize_struct("penumbra.view.v1.TransactionPlannerRequest.PositionWithdraw", FIELDS, GeneratedVisitor)
}
}
impl serde::Serialize for transaction_planner_request::Spend {
#[allow(deprecated)]
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeStruct;
let mut len = 0;
if self.value.is_some() {
len += 1;
}
if self.address.is_some() {
len += 1;
}
let mut struct_ser = serializer.serialize_struct("penumbra.view.v1.TransactionPlannerRequest.Spend", len)?;
if let Some(v) = self.value.as_ref() {
struct_ser.serialize_field("value", v)?;
}
if let Some(v) = self.address.as_ref() {
struct_ser.serialize_field("address", v)?;
}
struct_ser.end()
}
}
impl<'de> serde::Deserialize<'de> for transaction_planner_request::Spend {
#[allow(deprecated)]
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
const FIELDS: &[&str] = &[
"value",
"address",
];

#[allow(clippy::enum_variant_names)]
enum GeneratedField {
Value,
Address,
__SkipField__,
}
impl<'de> serde::Deserialize<'de> for GeneratedField {
fn deserialize<D>(deserializer: D) -> std::result::Result<GeneratedField, D::Error>
where
D: serde::Deserializer<'de>,
{
struct GeneratedVisitor;

impl<'de> serde::de::Visitor<'de> for GeneratedVisitor {
type Value = GeneratedField;

fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(formatter, "expected one of: {:?}", &FIELDS)
}

#[allow(unused_variables)]
fn visit_str<E>(self, value: &str) -> std::result::Result<GeneratedField, E>
where
E: serde::de::Error,
{
match value {
"value" => Ok(GeneratedField::Value),
"address" => Ok(GeneratedField::Address),
_ => Ok(GeneratedField::__SkipField__),
}
}
}
deserializer.deserialize_identifier(GeneratedVisitor)
}
}
struct GeneratedVisitor;
impl<'de> serde::de::Visitor<'de> for GeneratedVisitor {
type Value = transaction_planner_request::Spend;

fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str("struct penumbra.view.v1.TransactionPlannerRequest.Spend")
}

fn visit_map<V>(self, mut map_: V) -> std::result::Result<transaction_planner_request::Spend, V::Error>
where
V: serde::de::MapAccess<'de>,
{
let mut value__ = None;
let mut address__ = None;
while let Some(k) = map_.next_key()? {
match k {
GeneratedField::Value => {
if value__.is_some() {
return Err(serde::de::Error::duplicate_field("value"));
}
value__ = map_.next_value()?;
}
GeneratedField::Address => {
if address__.is_some() {
return Err(serde::de::Error::duplicate_field("address"));
}
address__ = map_.next_value()?;
}
GeneratedField::__SkipField__ => {
let _ = map_.next_value::<serde::de::IgnoredAny>()?;
}
}
}
Ok(transaction_planner_request::Spend {
value: value__,
address: address__,
})
}
}
deserializer.deserialize_struct("penumbra.view.v1.TransactionPlannerRequest.Spend", FIELDS, GeneratedVisitor)
}
}
impl serde::Serialize for transaction_planner_request::Swap {
#[allow(deprecated)]
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
Expand Down
Binary file modified crates/proto/src/gen/proto_descriptor.bin.no_lfs
Binary file not shown.
2 changes: 1 addition & 1 deletion deployments/scripts/protobuf-codegen
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ done
echo "Pulling proto dependencies from BSR..."
pushd "${repo_root}/proto/"
# Make sure the lockfile is up to date.
buf dep update penumbra
buf mod update penumbra

# Pull our vendored cosmos/IBC proto defs so we can get reflection for service definitions.
# The penumbra dependencies will override some of these.
Expand Down
9 changes: 8 additions & 1 deletion proto/penumbra/penumbra/view/v1/view.proto
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ message TransactionPlannerRequest {

// Request contents
repeated Output outputs = 20;
repeated Spend spends = 21;
repeated Swap swaps = 30;
repeated SwapClaim swap_claims = 31;
repeated Delegate delegations = 40;
Expand Down Expand Up @@ -282,6 +283,12 @@ message TransactionPlannerRequest {
// The address to which Output will be sent.
core.keys.v1.Address address = 2;
}
message Spend {
// The input amount and denomination in which the Spend is issued.
core.asset.v1.Value value = 1;
// The source address from which the Spend will be sent.
core.keys.v1.Address address = 2;
}
message Swap {
// The input amount and denomination to be traded in the Swap.
core.asset.v1.Value value = 1;
Expand Down Expand Up @@ -749,4 +756,4 @@ message UnbondingTokensByAddressIndexResponse {
// `true` if the `unbonding_delay` (from `StakeParameters`) has passed or the
// validator has unbonded.
bool claimable = 2;
}
}

0 comments on commit d098f23

Please sign in to comment.