Skip to content

Commit

Permalink
Add delegator vote to TxPlannerReq (#4689)
Browse files Browse the repository at this point in the history
Web consumer uses TransactionPlannerRequest to initiate planning between
frontend<->extension. To support delegator voting, we'd need to add to
this protobuf definition.

This reflects the way the core repo assembles a plan:
https://github.com/penumbra-zone/penumbra/blob/main/crates/bin/pcli/src/command/tx.rs#L899-L938

@plaidfinch, thoughts?
  • Loading branch information
grod220 committed Jul 3, 2024
1 parent 7abfcff commit a7e9d81
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 0 deletions.
Binary file modified crates/cnidarium/src/gen/proto_descriptor.bin.no_lfs
Binary file not shown.
36 changes: 36 additions & 0 deletions crates/proto/src/gen/penumbra.view.v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,10 @@ pub struct TransactionPlannerRequest {
pub dutch_auction_withdraw_actions: ::prost::alloc::vec::Vec<
transaction_planner_request::ActionDutchAuctionWithdraw,
>,
#[prost(message, repeated, tag = "76")]
pub delegator_votes: ::prost::alloc::vec::Vec<
transaction_planner_request::DelegatorVote,
>,
/// The epoch index of the transaction being planned.
#[deprecated]
#[prost(uint64, tag = "200")]
Expand Down Expand Up @@ -599,6 +603,38 @@ pub mod transaction_planner_request {
)
}
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct DelegatorVote {
/// The proposal being voted on.
#[prost(uint64, tag = "1")]
pub proposal: u64,
/// The vote.
#[prost(message, optional, tag = "2")]
pub vote: ::core::option::Option<
super::super::super::core::component::governance::v1::Vote,
>,
/// The block height at which the proposal started voting.
#[prost(uint64, tag = "3")]
pub start_block_height: u64,
/// The position of the state commitment tree at which the proposal is considered to have started voting.
#[prost(uint64, tag = "4")]
pub start_position: u64,
/// The validators rate data for the proposal.
#[prost(message, repeated, tag = "5")]
pub rate_data: ::prost::alloc::vec::Vec<
super::super::super::core::component::stake::v1::RateData,
>,
}
impl ::prost::Name for DelegatorVote {
const NAME: &'static str = "DelegatorVote";
const PACKAGE: &'static str = "penumbra.view.v1";
fn full_name() -> ::prost::alloc::string::String {
::prost::alloc::format!(
"penumbra.view.v1.TransactionPlannerRequest.{}", Self::NAME
)
}
}
/// Specifies either that the planner should compute fees automatically or that it should use a fixed fee amount.
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Oneof)]
Expand Down
193 changes: 193 additions & 0 deletions crates/proto/src/gen/penumbra.view.v1.serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6110,6 +6110,9 @@ impl serde::Serialize for TransactionPlannerRequest {
if !self.dutch_auction_withdraw_actions.is_empty() {
len += 1;
}
if !self.delegator_votes.is_empty() {
len += 1;
}
if self.epoch_index != 0 {
len += 1;
}
Expand Down Expand Up @@ -6175,6 +6178,9 @@ impl serde::Serialize for TransactionPlannerRequest {
if !self.dutch_auction_withdraw_actions.is_empty() {
struct_ser.serialize_field("dutchAuctionWithdrawActions", &self.dutch_auction_withdraw_actions)?;
}
if !self.delegator_votes.is_empty() {
struct_ser.serialize_field("delegatorVotes", &self.delegator_votes)?;
}
if self.epoch_index != 0 {
#[allow(clippy::needless_borrow)]
struct_ser.serialize_field("epochIndex", ToString::to_string(&self.epoch_index).as_str())?;
Expand Down Expand Up @@ -6231,6 +6237,8 @@ impl<'de> serde::Deserialize<'de> for TransactionPlannerRequest {
"dutchAuctionEndActions",
"dutch_auction_withdraw_actions",
"dutchAuctionWithdrawActions",
"delegator_votes",
"delegatorVotes",
"epoch_index",
"epochIndex",
"epoch",
Expand Down Expand Up @@ -6260,6 +6268,7 @@ impl<'de> serde::Deserialize<'de> for TransactionPlannerRequest {
DutchAuctionScheduleActions,
DutchAuctionEndActions,
DutchAuctionWithdrawActions,
DelegatorVotes,
EpochIndex,
Epoch,
AutoFee,
Expand Down Expand Up @@ -6304,6 +6313,7 @@ impl<'de> serde::Deserialize<'de> for TransactionPlannerRequest {
"dutchAuctionScheduleActions" | "dutch_auction_schedule_actions" => Ok(GeneratedField::DutchAuctionScheduleActions),
"dutchAuctionEndActions" | "dutch_auction_end_actions" => Ok(GeneratedField::DutchAuctionEndActions),
"dutchAuctionWithdrawActions" | "dutch_auction_withdraw_actions" => Ok(GeneratedField::DutchAuctionWithdrawActions),
"delegatorVotes" | "delegator_votes" => Ok(GeneratedField::DelegatorVotes),
"epochIndex" | "epoch_index" => Ok(GeneratedField::EpochIndex),
"epoch" => Ok(GeneratedField::Epoch),
"autoFee" | "auto_fee" => Ok(GeneratedField::AutoFee),
Expand Down Expand Up @@ -6345,6 +6355,7 @@ impl<'de> serde::Deserialize<'de> for TransactionPlannerRequest {
let mut dutch_auction_schedule_actions__ = None;
let mut dutch_auction_end_actions__ = None;
let mut dutch_auction_withdraw_actions__ = None;
let mut delegator_votes__ = None;
let mut epoch_index__ = None;
let mut epoch__ = None;
let mut fee_mode__ = None;
Expand Down Expand Up @@ -6460,6 +6471,12 @@ impl<'de> serde::Deserialize<'de> for TransactionPlannerRequest {
}
dutch_auction_withdraw_actions__ = Some(map_.next_value()?);
}
GeneratedField::DelegatorVotes => {
if delegator_votes__.is_some() {
return Err(serde::de::Error::duplicate_field("delegatorVotes"));
}
delegator_votes__ = Some(map_.next_value()?);
}
GeneratedField::EpochIndex => {
if epoch_index__.is_some() {
return Err(serde::de::Error::duplicate_field("epochIndex"));
Expand Down Expand Up @@ -6512,6 +6529,7 @@ impl<'de> serde::Deserialize<'de> for TransactionPlannerRequest {
dutch_auction_schedule_actions: dutch_auction_schedule_actions__.unwrap_or_default(),
dutch_auction_end_actions: dutch_auction_end_actions__.unwrap_or_default(),
dutch_auction_withdraw_actions: dutch_auction_withdraw_actions__.unwrap_or_default(),
delegator_votes: delegator_votes__.unwrap_or_default(),
epoch_index: epoch_index__.unwrap_or_default(),
epoch: epoch__,
fee_mode: fee_mode__,
Expand Down Expand Up @@ -6941,6 +6959,181 @@ impl<'de> serde::Deserialize<'de> for transaction_planner_request::Delegate {
deserializer.deserialize_struct("penumbra.view.v1.TransactionPlannerRequest.Delegate", FIELDS, GeneratedVisitor)
}
}
impl serde::Serialize for transaction_planner_request::DelegatorVote {
#[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.proposal != 0 {
len += 1;
}
if self.vote.is_some() {
len += 1;
}
if self.start_block_height != 0 {
len += 1;
}
if self.start_position != 0 {
len += 1;
}
if !self.rate_data.is_empty() {
len += 1;
}
let mut struct_ser = serializer.serialize_struct("penumbra.view.v1.TransactionPlannerRequest.DelegatorVote", len)?;
if self.proposal != 0 {
#[allow(clippy::needless_borrow)]
struct_ser.serialize_field("proposal", ToString::to_string(&self.proposal).as_str())?;
}
if let Some(v) = self.vote.as_ref() {
struct_ser.serialize_field("vote", v)?;
}
if self.start_block_height != 0 {
#[allow(clippy::needless_borrow)]
struct_ser.serialize_field("startBlockHeight", ToString::to_string(&self.start_block_height).as_str())?;
}
if self.start_position != 0 {
#[allow(clippy::needless_borrow)]
struct_ser.serialize_field("startPosition", ToString::to_string(&self.start_position).as_str())?;
}
if !self.rate_data.is_empty() {
struct_ser.serialize_field("rateData", &self.rate_data)?;
}
struct_ser.end()
}
}
impl<'de> serde::Deserialize<'de> for transaction_planner_request::DelegatorVote {
#[allow(deprecated)]
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
const FIELDS: &[&str] = &[
"proposal",
"vote",
"start_block_height",
"startBlockHeight",
"start_position",
"startPosition",
"rate_data",
"rateData",
];

#[allow(clippy::enum_variant_names)]
enum GeneratedField {
Proposal,
Vote,
StartBlockHeight,
StartPosition,
RateData,
__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 {
"proposal" => Ok(GeneratedField::Proposal),
"vote" => Ok(GeneratedField::Vote),
"startBlockHeight" | "start_block_height" => Ok(GeneratedField::StartBlockHeight),
"startPosition" | "start_position" => Ok(GeneratedField::StartPosition),
"rateData" | "rate_data" => Ok(GeneratedField::RateData),
_ => Ok(GeneratedField::__SkipField__),
}
}
}
deserializer.deserialize_identifier(GeneratedVisitor)
}
}
struct GeneratedVisitor;
impl<'de> serde::de::Visitor<'de> for GeneratedVisitor {
type Value = transaction_planner_request::DelegatorVote;

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

fn visit_map<V>(self, mut map_: V) -> std::result::Result<transaction_planner_request::DelegatorVote, V::Error>
where
V: serde::de::MapAccess<'de>,
{
let mut proposal__ = None;
let mut vote__ = None;
let mut start_block_height__ = None;
let mut start_position__ = None;
let mut rate_data__ = None;
while let Some(k) = map_.next_key()? {
match k {
GeneratedField::Proposal => {
if proposal__.is_some() {
return Err(serde::de::Error::duplicate_field("proposal"));
}
proposal__ =
Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0)
;
}
GeneratedField::Vote => {
if vote__.is_some() {
return Err(serde::de::Error::duplicate_field("vote"));
}
vote__ = map_.next_value()?;
}
GeneratedField::StartBlockHeight => {
if start_block_height__.is_some() {
return Err(serde::de::Error::duplicate_field("startBlockHeight"));
}
start_block_height__ =
Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0)
;
}
GeneratedField::StartPosition => {
if start_position__.is_some() {
return Err(serde::de::Error::duplicate_field("startPosition"));
}
start_position__ =
Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0)
;
}
GeneratedField::RateData => {
if rate_data__.is_some() {
return Err(serde::de::Error::duplicate_field("rateData"));
}
rate_data__ = Some(map_.next_value()?);
}
GeneratedField::__SkipField__ => {
let _ = map_.next_value::<serde::de::IgnoredAny>()?;
}
}
}
Ok(transaction_planner_request::DelegatorVote {
proposal: proposal__.unwrap_or_default(),
vote: vote__,
start_block_height: start_block_height__.unwrap_or_default(),
start_position: start_position__.unwrap_or_default(),
rate_data: rate_data__.unwrap_or_default(),
})
}
}
deserializer.deserialize_struct("penumbra.view.v1.TransactionPlannerRequest.DelegatorVote", FIELDS, GeneratedVisitor)
}
}
impl serde::Serialize for transaction_planner_request::Output {
#[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.
15 changes: 15 additions & 0 deletions proto/penumbra/penumbra/view/v1/view.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import "penumbra/core/asset/v1/asset.proto";
import "penumbra/core/component/auction/v1/auction.proto";
import "penumbra/core/component/dex/v1/dex.proto";
import "penumbra/core/component/fee/v1/fee.proto";
import "penumbra/core/component/governance/v1/governance.proto";
import "penumbra/core/component/ibc/v1/ibc.proto";
import "penumbra/core/component/sct/v1/sct.proto";
import "penumbra/core/component/shielded_pool/v1/shielded_pool.proto";
Expand Down Expand Up @@ -261,6 +262,7 @@ message TransactionPlannerRequest {
repeated ActionDutchAuctionSchedule dutch_auction_schedule_actions = 73;
repeated ActionDutchAuctionEnd dutch_auction_end_actions = 74;
repeated ActionDutchAuctionWithdraw dutch_auction_withdraw_actions = 75;
repeated DelegatorVote delegator_votes = 76;

// Specifies either that the planner should compute fees automatically or that it should use a fixed fee amount.
oneof fee_mode {
Expand Down Expand Up @@ -363,6 +365,19 @@ message TransactionPlannerRequest {
// The sequence number of the withdrawal.
uint64 seq = 2;
}

message DelegatorVote {
// The proposal being voted on.
uint64 proposal = 1;
// The vote.
core.component.governance.v1.Vote vote = 2;
// The block height at which the proposal started voting.
uint64 start_block_height = 3;
// The position of the state commitment tree at which the proposal is considered to have started voting.
uint64 start_position = 4;
// The validators rate data for the proposal.
repeated core.component.stake.v1.RateData rate_data = 5;
}
}

message TransactionPlannerResponse {
Expand Down

0 comments on commit a7e9d81

Please sign in to comment.