solend_sdk/state/
last_update.rs

1use crate::error::LendingError;
2use solana_program::{clock::Slot, program_error::ProgramError};
3use std::cmp::Ordering;
4
5/// Number of slots to consider stale after
6pub const STALE_AFTER_SLOTS_ELAPSED: u64 = 1;
7
8/// Last update state
9#[derive(Clone, Debug, Default)]
10pub struct LastUpdate {
11    /// Last slot when updated
12    pub slot: Slot,
13    /// True when marked stale, false when slot updated
14    pub stale: bool,
15}
16
17impl LastUpdate {
18    /// Create new last update
19    pub fn new(slot: Slot) -> Self {
20        Self { slot, stale: true }
21    }
22
23    /// Return slots elapsed since given slot
24    pub fn slots_elapsed(&self, slot: Slot) -> Result<u64, ProgramError> {
25        let slots_elapsed = slot
26            .checked_sub(self.slot)
27            .ok_or(LendingError::MathOverflow)?;
28        Ok(slots_elapsed)
29    }
30
31    /// Set last update slot
32    pub fn update_slot(&mut self, slot: Slot) {
33        self.slot = slot;
34        self.stale = false;
35    }
36
37    /// Set stale to true
38    pub fn mark_stale(&mut self) {
39        self.stale = true;
40    }
41
42    /// Check if marked stale or last update slot is too long ago
43    pub fn is_stale(&self, slot: Slot) -> Result<bool, ProgramError> {
44        Ok(self.stale || self.slots_elapsed(slot)? >= STALE_AFTER_SLOTS_ELAPSED)
45    }
46}
47
48impl PartialEq for LastUpdate {
49    fn eq(&self, other: &Self) -> bool {
50        self.slot == other.slot
51    }
52}
53
54impl PartialOrd for LastUpdate {
55    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
56        self.slot.partial_cmp(&other.slot)
57    }
58}