rialo_oracle_processor_interface/
instruction.rs1use rialo_s_instruction::{AccountMeta, Instruction};
9use rialo_s_program::system_program;
10use rialo_s_pubkey::Pubkey;
11use rialo_types::{Nonce, OracleId};
12use serde::{Deserialize, Serialize};
13
14pub use crate::state::OracleUpdate;
15
16pub const ORACLE_REPORT_SEED: &[u8] = b"oracle_report";
18
19pub const ORACLE_REPORT_PAYER_SEED: &[u8] = b"report_payer";
21
22pub const ORACLE_UPDATE_PAYER: Pubkey =
24 Pubkey::from_str_const("Qrac1eUpdatePayer11111111111111111111111111");
25
26#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
29pub enum OracleProcessorInstruction {
30 Report {
32 oracle_id: OracleId,
34 updates: Vec<OracleUpdate>,
36 },
37}
38
39impl OracleProcessorInstruction {
40 pub fn report(payer: Pubkey, oracle_id: OracleId, updates: Vec<OracleUpdate>) -> Instruction {
64 use rialo_events_core::derive_event_address;
65
66 use crate::event::OracleReportEvent;
67
68 let (report_key, _bump) = derive_report_address(&oracle_id.creator, oracle_id.nonce);
70
71 let event = OracleReportEvent::new(oracle_id);
73 let (event_key, _bump) = derive_event_address(&event.instance_topic(), &crate::id());
74
75 Instruction::new_with_bincode(
76 crate::id(),
77 &OracleProcessorInstruction::Report { oracle_id, updates },
78 vec![
79 AccountMeta::new(payer, true),
80 AccountMeta::new(report_key, false),
81 AccountMeta::new(event_key, false),
82 AccountMeta::new_readonly(system_program::id(), false),
83 ],
84 )
85 }
86}
87
88pub fn derive_report_address<NONCE: Into<Nonce>>(creator: &Pubkey, nonce: NONCE) -> (Pubkey, u8) {
99 let nonce: Nonce = nonce.into();
100 Pubkey::find_program_address(
101 &[ORACLE_REPORT_SEED, &creator.to_bytes(), nonce.as_bytes()],
102 &crate::id(),
103 )
104}
105
106#[cfg(test)]
107mod tests {
108 use rialo_events_core::RialoEvent;
109 use rialo_s_pubkey::Pubkey;
110
111 use super::*;
112
113 #[derive(Default, RialoEvent)]
114 struct TestEvent {
115 name: String,
116 value: u64,
117 }
118
119 #[test]
120 fn test_report_oracle_updates() {
121 use rialo_events_core::derive_event_address;
122
123 use crate::event::OracleReportEvent;
124
125 let authority_key = [0; 96];
126 let payer = Pubkey::new_unique();
127 let data = vec![0, 1, 2, 3];
128
129 let updates = vec![OracleUpdate::new(data, authority_key)];
130 let nonce = Nonce::from(b"test-oracle-42");
131 let oracle_id = OracleId::new(payer, nonce);
132
133 let instruction = OracleProcessorInstruction::report(payer, oracle_id, updates.clone());
135
136 let event = OracleReportEvent::new(oracle_id);
138 let (expected_event_key, _) = derive_event_address(&event.instance_topic(), &crate::id());
139
140 let expected_accounts = vec![
142 AccountMeta::new(payer, true),
143 AccountMeta::new(
144 derive_report_address(&oracle_id.creator, oracle_id.nonce).0,
145 false,
146 ),
147 AccountMeta::new(expected_event_key, false),
148 AccountMeta::new_readonly(system_program::id(), false),
149 ];
150
151 let expected_data = bincode::serialize(&OracleProcessorInstruction::Report {
153 oracle_id,
154 updates: updates.clone(),
155 })
156 .unwrap();
157
158 assert_eq!(instruction.data, expected_data);
159 assert_eq!(instruction.accounts, expected_accounts);
160 assert_eq!(instruction.program_id, crate::id());
161 }
162
163 #[test]
164 fn test_report_address_derivation() {
165 let oracle_creator = Pubkey::new_unique();
166 let (report_pubkey1, _) = derive_report_address(&oracle_creator, b"test-oracle-a42");
167 let (report_pubkey2, _) = derive_report_address(&oracle_creator, b"test-oracle-43");
168 assert_ne!(report_pubkey1, report_pubkey2);
169 }
170}