Skip to content

Commit

Permalink
PARTIAL: adapt rust code to use no proto options
Browse files Browse the repository at this point in the history
The governance module is the most problematic here: we'd been depending
on optionality rather hard. To accommodate the lack of options in the
protos, we use a submessage type of "Withdrawn" which can be present or
not.
  • Loading branch information
conorsch committed Aug 17, 2023
1 parent 95a24e9 commit dc71918
Show file tree
Hide file tree
Showing 7 changed files with 390 additions and 216 deletions.
11 changes: 5 additions & 6 deletions crates/core/component/stake/src/validator/bonding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ impl From<State> for pb::BondingState {
}
},
unbonding_epoch: match v {
State::Unbonding { unbonding_epoch } => Some(unbonding_epoch),
_ => None,
State::Unbonding { unbonding_epoch } => unbonding_epoch,
// REVIEW: is setting 0 here equivalent to None?
_ => 0,

},
}
}
Expand All @@ -71,10 +73,7 @@ impl TryFrom<pb::BondingState> for State {
pb::bonding_state::BondingStateEnum::Bonded => Ok(State::Bonded),
pb::bonding_state::BondingStateEnum::Unbonded => Ok(State::Unbonded),
pb::bonding_state::BondingStateEnum::Unbonding => {
let Some(unbonding_epoch) = v.unbonding_epoch else {
anyhow::bail!("unbonding epoch should be set for unbonding state")
};
Ok(State::Unbonding { unbonding_epoch })
Ok(State::Unbonding { unbonding_epoch: v.unbonding_epoch })
}
pb::bonding_state::BondingStateEnum::Unspecified => {
Err(anyhow::anyhow!("unspecified bonding state!"))
Expand Down
12 changes: 6 additions & 6 deletions crates/core/transaction/src/proposal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -581,12 +581,12 @@ impl From<Outcome<String>> for pb::ProposalOutcome {
}
Outcome::Failed { withdrawn } => {
pb::proposal_outcome::Outcome::Failed(pb::proposal_outcome::Failed {
withdrawn_with_reason: withdrawn.into(),
withdrawn: withdrawn.into(),
})
}
Outcome::Slashed { withdrawn } => {
pb::proposal_outcome::Outcome::Slashed(pb::proposal_outcome::Slashed {
withdrawn_with_reason: withdrawn.into(),
withdrawn: withdrawn.into(),
})
}
};
Expand All @@ -609,12 +609,12 @@ impl TryFrom<pb::ProposalOutcome> for Outcome<String> {
Outcome::Passed
}
pb::proposal_outcome::Outcome::Failed(pb::proposal_outcome::Failed {
withdrawn_with_reason,
withdrawn: withdrawn.into(),
}) => Outcome::Failed {
withdrawn: withdrawn_with_reason.into(),
},
pb::proposal_outcome::Outcome::Slashed(pb::proposal_outcome::Slashed {
withdrawn_with_reason,
withdrawn: withdrawn.into(),
}) => Outcome::Slashed {
withdrawn: withdrawn_with_reason.into(),
},
Expand Down Expand Up @@ -667,12 +667,12 @@ impl TryFrom<pb::ProposalOutcome> for Outcome<()> {
Outcome::Passed
}
pb::proposal_outcome::Outcome::Failed(pb::proposal_outcome::Failed {
withdrawn_with_reason,
withdrawn: withdrawn.into(),
}) => Outcome::Failed {
withdrawn: <Withdrawn<String>>::from(withdrawn_with_reason).try_into()?,
},
pb::proposal_outcome::Outcome::Slashed(pb::proposal_outcome::Slashed {
withdrawn_with_reason,
withdrawn: withdrawn.into(),
}) => Outcome::Slashed {
withdrawn: <Withdrawn<String>>::from(withdrawn_with_reason).try_into()?,
},
Expand Down
20 changes: 14 additions & 6 deletions crates/proto/src/gen/penumbra.core.governance.v1alpha1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,14 @@ pub struct ProposalOutcome {
}
/// Nested message and enum types in `ProposalOutcome`.
pub mod proposal_outcome {
/// Whether or not the proposal was withdrawn.
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Withdrawn {
/// The reason for withdrawing the proposal during the voting period.
#[prost(string, tag = "1")]
pub reason: ::prost::alloc::string::String,
}
/// The proposal was passed.
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
Expand All @@ -281,17 +289,17 @@ pub mod proposal_outcome {
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Failed {
/// The proposal was withdrawn during the voting period.
#[prost(string, tag = "1")]
pub withdrawn_with_reason: ::prost::alloc::string::String,
/// Present if the proposal was withdrawn during the voting period.
#[prost(message, optional, tag = "1")]
pub withdrawn: ::core::option::Option<Withdrawn>,
}
/// The proposal did not pass, and was slashed.
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Slashed {
/// The proposal was withdrawn during the voting period.
#[prost(string, tag = "1")]
pub withdrawn_with_reason: ::prost::alloc::string::String,
/// Present if the proposal was withdrawn during the voting period.
#[prost(message, optional, tag = "1")]
pub withdrawn: ::core::option::Option<Withdrawn>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Oneof)]
Expand Down
141 changes: 115 additions & 26 deletions crates/proto/src/gen/penumbra.core.governance.v1alpha1.serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1702,12 +1702,12 @@ impl serde::Serialize for proposal_outcome::Failed {
{
use serde::ser::SerializeStruct;
let mut len = 0;
if !self.withdrawn_with_reason.is_empty() {
if self.withdrawn.is_some() {
len += 1;
}
let mut struct_ser = serializer.serialize_struct("penumbra.core.governance.v1alpha1.ProposalOutcome.Failed", len)?;
if !self.withdrawn_with_reason.is_empty() {
struct_ser.serialize_field("withdrawnWithReason", &self.withdrawn_with_reason)?;
if let Some(v) = self.withdrawn.as_ref() {
struct_ser.serialize_field("withdrawn", v)?;
}
struct_ser.end()
}
Expand All @@ -1719,13 +1719,12 @@ impl<'de> serde::Deserialize<'de> for proposal_outcome::Failed {
D: serde::Deserializer<'de>,
{
const FIELDS: &[&str] = &[
"withdrawn_with_reason",
"withdrawnWithReason",
"withdrawn",
];

#[allow(clippy::enum_variant_names)]
enum GeneratedField {
WithdrawnWithReason,
Withdrawn,
}
impl<'de> serde::Deserialize<'de> for GeneratedField {
fn deserialize<D>(deserializer: D) -> std::result::Result<GeneratedField, D::Error>
Expand All @@ -1747,7 +1746,7 @@ impl<'de> serde::Deserialize<'de> for proposal_outcome::Failed {
E: serde::de::Error,
{
match value {
"withdrawnWithReason" | "withdrawn_with_reason" => Ok(GeneratedField::WithdrawnWithReason),
"withdrawn" => Ok(GeneratedField::Withdrawn),
_ => Err(serde::de::Error::unknown_field(value, FIELDS)),
}
}
Expand All @@ -1767,19 +1766,19 @@ impl<'de> serde::Deserialize<'de> for proposal_outcome::Failed {
where
V: serde::de::MapAccess<'de>,
{
let mut withdrawn_with_reason__ = None;
let mut withdrawn__ = None;
while let Some(k) = map.next_key()? {
match k {
GeneratedField::WithdrawnWithReason => {
if withdrawn_with_reason__.is_some() {
return Err(serde::de::Error::duplicate_field("withdrawnWithReason"));
GeneratedField::Withdrawn => {
if withdrawn__.is_some() {
return Err(serde::de::Error::duplicate_field("withdrawn"));
}
withdrawn_with_reason__ = Some(map.next_value()?);
withdrawn__ = map.next_value()?;
}
}
}
Ok(proposal_outcome::Failed {
withdrawn_with_reason: withdrawn_with_reason__.unwrap_or_default(),
withdrawn: withdrawn__,
})
}
}
Expand Down Expand Up @@ -1865,12 +1864,12 @@ impl serde::Serialize for proposal_outcome::Slashed {
{
use serde::ser::SerializeStruct;
let mut len = 0;
if !self.withdrawn_with_reason.is_empty() {
if self.withdrawn.is_some() {
len += 1;
}
let mut struct_ser = serializer.serialize_struct("penumbra.core.governance.v1alpha1.ProposalOutcome.Slashed", len)?;
if !self.withdrawn_with_reason.is_empty() {
struct_ser.serialize_field("withdrawnWithReason", &self.withdrawn_with_reason)?;
if let Some(v) = self.withdrawn.as_ref() {
struct_ser.serialize_field("withdrawn", v)?;
}
struct_ser.end()
}
Expand All @@ -1882,13 +1881,12 @@ impl<'de> serde::Deserialize<'de> for proposal_outcome::Slashed {
D: serde::Deserializer<'de>,
{
const FIELDS: &[&str] = &[
"withdrawn_with_reason",
"withdrawnWithReason",
"withdrawn",
];

#[allow(clippy::enum_variant_names)]
enum GeneratedField {
WithdrawnWithReason,
Withdrawn,
}
impl<'de> serde::Deserialize<'de> for GeneratedField {
fn deserialize<D>(deserializer: D) -> std::result::Result<GeneratedField, D::Error>
Expand All @@ -1910,7 +1908,7 @@ impl<'de> serde::Deserialize<'de> for proposal_outcome::Slashed {
E: serde::de::Error,
{
match value {
"withdrawnWithReason" | "withdrawn_with_reason" => Ok(GeneratedField::WithdrawnWithReason),
"withdrawn" => Ok(GeneratedField::Withdrawn),
_ => Err(serde::de::Error::unknown_field(value, FIELDS)),
}
}
Expand All @@ -1930,25 +1928,116 @@ impl<'de> serde::Deserialize<'de> for proposal_outcome::Slashed {
where
V: serde::de::MapAccess<'de>,
{
let mut withdrawn_with_reason__ = None;
let mut withdrawn__ = None;
while let Some(k) = map.next_key()? {
match k {
GeneratedField::WithdrawnWithReason => {
if withdrawn_with_reason__.is_some() {
return Err(serde::de::Error::duplicate_field("withdrawnWithReason"));
GeneratedField::Withdrawn => {
if withdrawn__.is_some() {
return Err(serde::de::Error::duplicate_field("withdrawn"));
}
withdrawn_with_reason__ = Some(map.next_value()?);
withdrawn__ = map.next_value()?;
}
}
}
Ok(proposal_outcome::Slashed {
withdrawn_with_reason: withdrawn_with_reason__.unwrap_or_default(),
withdrawn: withdrawn__,
})
}
}
deserializer.deserialize_struct("penumbra.core.governance.v1alpha1.ProposalOutcome.Slashed", FIELDS, GeneratedVisitor)
}
}
impl serde::Serialize for proposal_outcome::Withdrawn {
#[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.reason.is_empty() {
len += 1;
}
let mut struct_ser = serializer.serialize_struct("penumbra.core.governance.v1alpha1.ProposalOutcome.Withdrawn", len)?;
if !self.reason.is_empty() {
struct_ser.serialize_field("reason", &self.reason)?;
}
struct_ser.end()
}
}
impl<'de> serde::Deserialize<'de> for proposal_outcome::Withdrawn {
#[allow(deprecated)]
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
const FIELDS: &[&str] = &[
"reason",
];

#[allow(clippy::enum_variant_names)]
enum GeneratedField {
Reason,
}
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 {
"reason" => Ok(GeneratedField::Reason),
_ => Err(serde::de::Error::unknown_field(value, FIELDS)),
}
}
}
deserializer.deserialize_identifier(GeneratedVisitor)
}
}
struct GeneratedVisitor;
impl<'de> serde::de::Visitor<'de> for GeneratedVisitor {
type Value = proposal_outcome::Withdrawn;

fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str("struct penumbra.core.governance.v1alpha1.ProposalOutcome.Withdrawn")
}

fn visit_map<V>(self, mut map: V) -> std::result::Result<proposal_outcome::Withdrawn, V::Error>
where
V: serde::de::MapAccess<'de>,
{
let mut reason__ = None;
while let Some(k) = map.next_key()? {
match k {
GeneratedField::Reason => {
if reason__.is_some() {
return Err(serde::de::Error::duplicate_field("reason"));
}
reason__ = Some(map.next_value()?);
}
}
}
Ok(proposal_outcome::Withdrawn {
reason: reason__.unwrap_or_default(),
})
}
}
deserializer.deserialize_struct("penumbra.core.governance.v1alpha1.ProposalOutcome.Withdrawn", FIELDS, GeneratedVisitor)
}
}
impl serde::Serialize for ProposalState {
#[allow(deprecated)]
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
Expand Down
4 changes: 2 additions & 2 deletions crates/proto/src/gen/proto_descriptor.bin
Git LFS file not shown
Loading

0 comments on commit dc71918

Please sign in to comment.