use anchor_lang::prelude::*;
pub const OBSERVATION_SEED: &str = "o";
#[account(zero_copy)]
#[derive(Default)]
#[repr(packed)]
pub struct ObservationState {
pub bump: u8,
pub index: u16,
pub block_timestamp: u32,
pub tick_cumulative: i64,
pub seconds_per_liquidity_cumulative_x32: u64,
pub initialized: bool,
}
impl ObservationState {
pub fn transform(self, block_timestamp: u32, tick: i32, liquidity: u64) -> ObservationState {
let delta = block_timestamp - self.block_timestamp;
ObservationState {
bump: self.bump,
index: self.index,
block_timestamp,
tick_cumulative: self.tick_cumulative + tick as i64 * delta as i64,
seconds_per_liquidity_cumulative_x32: self.seconds_per_liquidity_cumulative_x32
+ ((delta as u64) << 32) / if liquidity > 0 { liquidity } else { 1 },
initialized: true,
}
}
pub fn update(
&mut self,
block_timestamp: u32,
tick: i32,
liquidity: u64,
cardinality: u16,
cardinality_next: u16,
) -> u16 {
if self.block_timestamp == block_timestamp {
return cardinality;
}
*self = self.transform(block_timestamp, tick, liquidity);
if cardinality_next > cardinality && self.index == (cardinality - 1) {
cardinality_next
} else {
cardinality
}
}
pub fn observe_latest(self, time: u32, tick: i32, liquidity: u64) -> (i64, u64) {
let mut last = self;
if self.block_timestamp != time {
last = self.transform(time, tick, liquidity)
}
(
last.tick_cumulative,
last.seconds_per_liquidity_cumulative_x32,
)
}
}
pub fn _block_timestamp() -> u32 {
Clock::get().unwrap().unix_timestamp as u32 }
#[event]
pub struct IncreaseObservationCardinalityNext {
pub observation_cardinality_next_old: u16,
pub observation_cardinality_next_new: u16,
}
#[cfg(test)]
mod test {
use super::*;
}