switchboard_solana/oracle_program/accounts/
buffer_relayer.rs

1use crate::prelude::*;
2
3#[account]
4#[derive(Default)]
5pub struct BufferRelayerAccountData {
6    /// Name of the buffer account to store on-chain.
7    pub name: [u8; 32],
8    /// Public key of the OracleQueueAccountData that is currently assigned to fulfill buffer relayer update request.
9    pub queue_pubkey: Pubkey,
10    /// Token account to reward oracles for completing update request.
11    pub escrow: Pubkey,
12    /// The account delegated as the authority for making account changes.
13    pub authority: Pubkey,
14    /// Public key of the JobAccountData that defines how the buffer relayer is updated.
15    pub job_pubkey: Pubkey,
16    /// Used to protect against malicious RPC nodes providing incorrect task definitions to oracles before fulfillment
17    pub job_hash: [u8; 32],
18    /// Minimum delay between update request.
19    pub min_update_delay_seconds: u32,
20    /// Whether buffer relayer config is locked for further changes.
21    pub is_locked: bool,
22    /// The current buffer relayer update round that is yet to be confirmed.
23    pub current_round: BufferRelayerRound,
24    /// The latest confirmed buffer relayer update round.
25    pub latest_confirmed_round: BufferRelayerRound,
26    /// The buffer holding the latest confirmed result.
27    pub result: Vec<u8>,
28}
29
30#[derive(Default, Clone, AnchorSerialize, AnchorDeserialize)]
31pub struct BufferRelayerRound {
32    /// Number of successful responses.
33    pub num_success: u32,
34    /// Number of error responses.
35    pub num_error: u32,
36    /// Slot when the buffer relayer round was opened.
37    pub round_open_slot: u64,
38    /// Timestamp when the buffer relayer round was opened.
39    pub round_open_timestamp: i64,
40    /// The public key of the oracle fulfilling the buffer relayer update request.
41    pub oracle_pubkey: Pubkey,
42}
43
44impl BufferRelayerAccountData {
45    /// Returns the deserialized Switchboard Buffer Relayer account
46    ///
47    /// # Arguments
48    ///
49    /// * `switchboard_buffer` - A Solana AccountInfo referencing an existing Switchboard BufferRelayer
50    ///
51    /// # Examples
52    ///
53    /// ```ignore
54    /// use switchboard_solana::BufferRelayerAccountData;
55    ///
56    /// let buffer_account = BufferRelayerAccountData::new(buffer_account_info)?;
57    /// ```
58    pub fn new(
59        switchboard_buffer: &AccountInfo,
60    ) -> anchor_lang::Result<Box<BufferRelayerAccountData>> {
61        let data = switchboard_buffer.try_borrow_data()?;
62
63        let mut disc_bytes = [0u8; 8];
64        disc_bytes.copy_from_slice(&data[..8]);
65        if disc_bytes != BufferRelayerAccountData::discriminator() {
66            return Err(SwitchboardError::AccountDiscriminatorMismatch.into());
67        }
68
69        let mut v_mut = &data[8..];
70        Ok(Box::new(BufferRelayerAccountData::deserialize(&mut v_mut)?))
71    }
72
73    pub fn get_result(&self) -> &Vec<u8> {
74        &self.result
75    }
76
77    /// Check whether the buffer relayer has been updated in the last max_staleness seconds
78    ///
79    /// # Examples
80    ///
81    /// ```ignore
82    /// use switchboard_solana::BufferRelayerAccountData;
83    ///
84    /// let buffer = BufferRelayerAccountData::new(buffer_account_info)?;
85    /// buffer.check_staleness(clock::Clock::get().unwrap().unix_timestamp, 300)?;
86    /// ```
87    pub fn check_staleness(
88        &self,
89        unix_timestamp: i64,
90        max_staleness: i64,
91    ) -> anchor_lang::Result<()> {
92        let staleness = unix_timestamp - self.latest_confirmed_round.round_open_timestamp;
93        if staleness > max_staleness {
94            msg!("Feed has not been updated in {} seconds!", staleness);
95            return Err(SwitchboardError::StaleFeed.into());
96        }
97        Ok(())
98    }
99}