use anchor_lang::prelude::*;
#[account(zero_copy)]
#[derive(AnchorDeserialize, Debug, PartialEq, Default)]
pub struct RolloverMetadata {
pub index: u64,
pub rollover_fee: u64,
pub rollover_threshold: u64,
pub network_fee: u64,
pub rolledover_slot: u64,
pub close_threshold: u64,
pub additional_bytes: u64,
}
impl RolloverMetadata {
pub fn new(
index: u64,
rollover_fee: u64,
rollover_threshold: Option<u64>,
network_fee: u64,
close_threshold: Option<u64>,
additional_bytes: Option<u64>,
) -> Self {
Self {
index,
rollover_fee,
rollover_threshold: rollover_threshold.unwrap_or(u64::MAX),
network_fee,
rolledover_slot: u64::MAX,
close_threshold: close_threshold.unwrap_or(u64::MAX),
additional_bytes: additional_bytes.unwrap_or_default(),
}
}
pub fn rollover(&mut self) -> Result<()> {
if self.rollover_threshold == u64::MAX {
return err!(crate::errors::AccountCompressionErrorCode::RolloverNotConfigured);
}
if self.rolledover_slot != u64::MAX {
return err!(crate::errors::AccountCompressionErrorCode::MerkleTreeAlreadyRolledOver);
}
#[cfg(target_os = "solana")]
{
self.rolledover_slot = Clock::get()?.slot;
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rollover_metadata() {
let mut metadata = RolloverMetadata::new(0, 0, Some(95), 0, Some(100), Some(1));
assert_eq!(metadata.rollover_threshold, 95);
assert_eq!(metadata.close_threshold, 100);
assert_eq!(metadata.rolledover_slot, u64::MAX);
assert_eq!(metadata.additional_bytes, 1);
metadata.rollover().unwrap();
let mut metadata = RolloverMetadata::new(0, 0, None, 0, None, None);
assert_eq!(metadata.rollover_threshold, u64::MAX);
assert_eq!(metadata.close_threshold, u64::MAX);
assert_eq!(metadata.additional_bytes, 0);
assert_eq!(
metadata.rollover(),
Err(crate::errors::AccountCompressionErrorCode::RolloverNotConfigured.into())
);
let mut metadata = RolloverMetadata::new(0, 0, Some(95), 0, None, None);
assert_eq!(metadata.close_threshold, u64::MAX);
metadata.rollover().unwrap();
let mut metadata = RolloverMetadata::new(0, 0, Some(95), 0, None, None);
metadata.rolledover_slot = 0;
assert_eq!(metadata.close_threshold, u64::MAX);
assert_eq!(
metadata.rollover(),
Err(crate::errors::AccountCompressionErrorCode::MerkleTreeAlreadyRolledOver.into())
);
}
}