Skip to content

Commit

Permalink
Use itf native support for sum types
Browse files Browse the repository at this point in the history
  • Loading branch information
romac committed Dec 7, 2023
1 parent fd8f39c commit 3f56287
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 153 deletions.
2 changes: 1 addition & 1 deletion Code/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ async-trait = "0.1"
ed25519-consensus = "2.1.0"
futures = "0.3"
glob = "0.3.0"
itf = "0.2.1"
itf = "0.2.2"
num-bigint = "0.4.4"
rand = { version = "0.8.5", features = ["std_rng"] }
serde = "1.0"
Expand Down
57 changes: 3 additions & 54 deletions Code/itf/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,72 +1,21 @@
use serde::Deserialize;

#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Hash)]
pub struct EmptyObject {}

pub type Height = i64;
pub type Weight = i64;
pub type Round = i64;
pub type Address = String;
pub type NonNilValue = String;

#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VoteTypeTag {
pub tag: String, // "Precommit" or "Prevote"
pub value: EmptyObject,
}

#[derive(Clone, Debug, PartialEq, Eq)]
#[serde(tag = "tag", content = "value")]
pub enum VoteType {
Prevote,
Precommit,
}

impl TryFrom<VoteTypeTag> for VoteType {
type Error = String;
fn try_from(v: VoteTypeTag) -> Result<Self, Self::Error> {
match v.tag.as_str() {
"Prevote" => Ok(VoteType::Prevote),
"Precommit" => Ok(VoteType::Precommit),
_ => todo!(), // error
}
}
}

pub type SerdeVoteType = serde_with::TryFromInto<VoteTypeTag>;

#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Hash)]
#[serde(untagged)]
pub enum ValueValues {
Val(NonNilValue),
Nil(EmptyObject),
}

#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Hash)]
#[serde(rename_all = "camelCase")]
pub struct ValueTag {
pub tag: String, // "Nil" or "Val"
pub value: ValueValues,
}

#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Hash)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize)]
#[serde(tag = "tag", content = "value")]
pub enum Value {
Nil,
Val(String),
}

impl TryFrom<ValueTag> for Value {
type Error = String;
fn try_from(v: ValueTag) -> Result<Self, Self::Error> {
match v.tag.as_str() {
"Nil" => Ok(Value::Nil),
"Val" => match v.value {
ValueValues::Val(v) => Ok(Value::Val(v)),
ValueValues::Nil(_) => todo!(), // error
},
_ => todo!(), // error
}
}
}

pub type SerdeValue = serde_with::TryFromInto<ValueTag>;
110 changes: 13 additions & 97 deletions Code/itf/src/votekeeper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,114 +3,35 @@ use std::collections::{HashMap, HashSet};

use serde::Deserialize;

use crate::types::{
Address, EmptyObject, Height, NonNilValue, Round, SerdeValue, SerdeVoteType, Value, VoteType,
Weight,
};
use crate::types::{Address, Height, NonNilValue, Round, Value, VoteType, Weight};

#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
#[serde(untagged)]
pub enum WeightedVoteValues {
#[serde(with = "As::<(Same, Integer, Integer)>")]
WV((Vote, Weight, Round)),
NoWeightedVote(EmptyObject),
}

#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
pub struct WeightedVoteTag {
pub tag: String,
pub value: WeightedVoteValues,
}

#[derive(Clone, Debug, PartialEq, Eq)]
#[serde(tag = "tag", content = "value")]
pub enum WeightedVote {
NoWeightedVote,
WV(Vote, Weight, Round),
}

impl TryFrom<WeightedVoteTag> for WeightedVote {
type Error = String;
fn try_from(v: WeightedVoteTag) -> Result<Self, Self::Error> {
match v.tag.as_str() {
"NoWeightedVote" => Ok(WeightedVote::NoWeightedVote),
"WV" => match v.value {
WeightedVoteValues::WV((v, w, r)) => Ok(WeightedVote::WV(v, w, r)),
WeightedVoteValues::NoWeightedVote(_) => todo!(),
},
_ => todo!(), // error
}
}
}

pub type SerdeWeightedVote = serde_with::TryFromInto<WeightedVoteTag>;

#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Hash)]
#[serde(untagged)]
pub enum VoteKeeperOutputValues {
None(EmptyObject),
#[serde(with = "As::<Integer>")]
Round(Round),
#[serde(with = "As::<(Integer, Same)>")]
RoundValue((Round, NonNilValue)),
}

#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Hash)]
pub struct VoteKeeperOutputTag {
pub tag: String,
pub value: VoteKeeperOutputValues,
#[serde(with = "As::<(Same, Integer, Integer)>")]
WV(Vote, Weight, Round),
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize)]
#[serde(tag = "tag", content = "value")]
pub enum VoteKeeperOutput {
NoVKOutput,
#[serde(with = "As::<Integer>")]
PolkaAnyVKOutput(Round),
#[serde(with = "As::<Integer>")]
PolkaNilVKOutput(Round),
#[serde(with = "As::<(Integer, Same)>")]
PolkaValueVKOutput(Round, NonNilValue),
#[serde(with = "As::<Integer>")]
PrecommitAnyVKOutput(Round),
#[serde(with = "As::<(Integer, Same)>")]
PrecommitValueVKOutput(Round, NonNilValue),
#[serde(with = "As::<Integer>")]
SkipVKOutput(Round),
}

impl TryFrom<VoteKeeperOutputTag> for VoteKeeperOutput {
type Error = String;
fn try_from(v: VoteKeeperOutputTag) -> Result<Self, Self::Error> {
match v.tag.as_str() {
"NoVKOutput" => Ok(VoteKeeperOutput::NoVKOutput),
"PolkaAnyVKOutput" => match v.value {
VoteKeeperOutputValues::Round(r) => Ok(VoteKeeperOutput::PolkaAnyVKOutput(r)),
_ => todo!(), // error
},
"PolkaNilVKOutput" => match v.value {
VoteKeeperOutputValues::Round(r) => Ok(VoteKeeperOutput::PolkaNilVKOutput(r)),
_ => todo!(), // error
},
"PolkaValueVKOutput" => match v.value {
VoteKeeperOutputValues::RoundValue((r, v)) => {
Ok(VoteKeeperOutput::PolkaValueVKOutput(r, v))
}
_ => todo!(), // error
},
"PrecommitAnyVKOutput" => match v.value {
VoteKeeperOutputValues::Round(r) => Ok(VoteKeeperOutput::PrecommitAnyVKOutput(r)),
_ => todo!(), // error
},
"PrecommitValueVKOutput" => match v.value {
VoteKeeperOutputValues::RoundValue((r, v)) => {
Ok(VoteKeeperOutput::PrecommitValueVKOutput(r, v))
}
_ => todo!(), // error
},
"SkipVKOutput" => match v.value {
VoteKeeperOutputValues::Round(r) => Ok(VoteKeeperOutput::SkipVKOutput(r)),
_ => todo!(), // error
},
_ => todo!(), // error
}
}
}

pub type SerdeVoteKeeperOutput = serde_with::TryFromInto<VoteKeeperOutputTag>;

#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Bookkeeper {
Expand All @@ -125,13 +46,11 @@ pub struct Bookkeeper {
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Vote {
#[serde(with = "As::<SerdeVoteType>")]
pub vote_type: VoteType,
#[serde(with = "As::<Integer>")]
pub height: Height,
#[serde(with = "As::<Integer>")]
pub round: Round,
#[serde(with = "As::<SerdeValue>")]
pub value_id: Value,
pub src_address: Address,
}
Expand All @@ -145,7 +64,6 @@ pub struct RoundVotes {
pub round: Round,
pub prevotes: VoteCount,
pub precommits: VoteCount,
#[serde(with = "As::<HashSet<SerdeVoteKeeperOutput>>")]
pub emitted_outputs: HashSet<VoteKeeperOutput>,
#[serde(with = "As::<HashMap<Same, Integer>>")]
pub votes_addresses_weights: HashMap<Address, Weight>,
Expand All @@ -156,7 +74,7 @@ pub struct RoundVotes {
pub struct VoteCount {
#[serde(with = "As::<Integer>")]
pub total_weight: Weight,
#[serde(with = "As::<HashMap<SerdeValue, Integer>>")]
#[serde(with = "As::<HashMap<Same, Integer>>")]
pub values_weights: HashMap<Value, Weight>,
pub votes_addresses: HashSet<Address>,
}
Expand All @@ -165,8 +83,6 @@ pub struct VoteCount {
#[serde(rename_all = "camelCase")]
pub struct State {
pub bookkeeper: Bookkeeper,
#[serde(with = "As::<SerdeVoteKeeperOutput>")]
pub last_emitted: VoteKeeperOutput,
#[serde(with = "As::<SerdeWeightedVote>")]
pub weighted_vote: WeightedVote,
}
2 changes: 1 addition & 1 deletion Code/itf/tests/votekeeper/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl ItfRunner for VoteKeeperRunner {
assert_eq!(round, &Round::new(*expected_round));
}
(actual, expected) => {
assert!(false, "actual: {:?}, expected: {:?}", actual, expected)
panic!("actual: {:?}, expected: {:?}", actual, expected)
}
},
None => assert_eq!(*expected_result, NoVKOutput),
Expand Down

0 comments on commit 3f56287

Please sign in to comment.