casper_types/chainspec/
refund_handling.rsuse num_rational::Ratio;
use num_traits::Zero;
use serde::{Deserialize, Serialize};
use crate::bytesrepr::{self, FromBytes, ToBytes};
const REFUND_HANDLING_REFUND_TAG: u8 = 0;
const REFUND_HANDLING_BURN_TAG: u8 = 1;
const REFUND_HANDLING_NONE_TAG: u8 = 2;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum RefundHandling {
Refund {
refund_ratio: Ratio<u64>,
},
Burn {
refund_ratio: Ratio<u64>,
},
#[default]
NoRefund,
}
impl RefundHandling {
pub fn skip_refund(&self) -> bool {
match self {
RefundHandling::NoRefund => true,
RefundHandling::Refund { refund_ratio } => refund_ratio.is_zero(),
RefundHandling::Burn { .. } => false,
}
}
pub fn refund_ratio(&self) -> Ratio<u64> {
match self {
RefundHandling::Refund { refund_ratio } | RefundHandling::Burn { refund_ratio } => {
*refund_ratio
}
RefundHandling::NoRefund => Ratio::zero(),
}
}
}
impl ToBytes for RefundHandling {
fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
let mut buffer = bytesrepr::allocate_buffer(self)?;
match self {
RefundHandling::Refund { refund_ratio } => {
buffer.push(REFUND_HANDLING_REFUND_TAG);
buffer.extend(refund_ratio.to_bytes()?);
}
RefundHandling::Burn { refund_ratio } => {
buffer.push(REFUND_HANDLING_BURN_TAG);
buffer.extend(refund_ratio.to_bytes()?);
}
RefundHandling::NoRefund => {
buffer.push(REFUND_HANDLING_NONE_TAG);
}
}
Ok(buffer)
}
fn serialized_length(&self) -> usize {
1 + match self {
RefundHandling::Refund { refund_ratio } => refund_ratio.serialized_length(),
RefundHandling::Burn { refund_ratio } => refund_ratio.serialized_length(),
RefundHandling::NoRefund => 0,
}
}
}
impl FromBytes for RefundHandling {
fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
let (tag, rem) = u8::from_bytes(bytes)?;
match tag {
REFUND_HANDLING_REFUND_TAG => {
let (refund_ratio, rem) = FromBytes::from_bytes(rem)?;
Ok((RefundHandling::Refund { refund_ratio }, rem))
}
REFUND_HANDLING_BURN_TAG => {
let (refund_ratio, rem) = FromBytes::from_bytes(rem)?;
Ok((RefundHandling::Burn { refund_ratio }, rem))
}
REFUND_HANDLING_NONE_TAG => Ok((RefundHandling::NoRefund, rem)),
_ => Err(bytesrepr::Error::Formatting),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn bytesrepr_roundtrip_for_refund() {
let refund_config = RefundHandling::Refund {
refund_ratio: Ratio::new(49, 313),
};
bytesrepr::test_serialization_roundtrip(&refund_config);
}
#[test]
fn bytesrepr_roundtrip_for_burn() {
let refund_config = RefundHandling::Burn {
refund_ratio: Ratio::new(49, 313),
};
bytesrepr::test_serialization_roundtrip(&refund_config);
}
#[test]
fn bytesrepr_roundtrip_for_no_refund() {
let refund_config = RefundHandling::NoRefund;
bytesrepr::test_serialization_roundtrip(&refund_config);
}
}