penumbra_tct/witness.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
/// When inserting a [`Commitment`](crate::Commitment) into a [`Tree`](crate::Tree), should we
/// [`Keep`](Witness::Keep) it to allow it to be witnessed later, or [`Forget`](Witness::Forget)
/// about it after updating the root hash of the tree?
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(any(test, feature = "arbitrary"), derive(proptest_derive::Arbitrary))]
pub enum Witness {
/// When inserting a [`Commitment`](crate::Commitment) into a [`Tree`](crate::Tree), this flag
/// indicates that we should immediately forget about it to save space, because we will not want
/// to witness its presence later.
///
/// This is equivalent to inserting the commitment using [`Witness::Keep`] and then immediately
/// forgetting that same commitment using [`Tree::forget`](crate::Tree::forget), though it is
/// more efficient to directly forget commitments upon insertion rather than to remember them on
/// insertion and then immediately forget them.
Forget,
/// When inserting a [`Commitment`](crate::Commitment) into a [`Tree`](crate::Tree), this flag
/// indicates that we should keep this commitment to allow it to be witnessed later.
Keep,
}
impl serde::Serialize for Witness {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
match self {
Witness::Forget => serializer.serialize_str("forget"),
Witness::Keep => serializer.serialize_str("keep"),
}
}
}
impl<'de> serde::Deserialize<'de> for Witness {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
struct WitnessVisitor;
impl<'de> serde::de::Visitor<'de> for WitnessVisitor {
type Value = Witness;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("one of \"keep\" or \"forget\"")
}
fn visit_str<E: serde::de::Error>(self, value: &str) -> Result<Self::Value, E> {
match value.to_lowercase().as_str() {
"forget" => Ok(Witness::Forget),
"keep" => Ok(Witness::Keep),
_ => Err(E::custom(format!(
"invalid witness flag: expected \"forget\" or \"keep\", found \"{value}\""
))),
}
}
}
deserializer.deserialize_str(WitnessVisitor)
}
}