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}