-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinitialize_oracle_queue.rs
87 lines (75 loc) · 2.84 KB
/
initialize_oracle_queue.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use ephemeral_vrf_api::prelude::EphemeralVrfError::Unauthorized;
use ephemeral_vrf_api::prelude::*;
use steel::*;
/// Process the initialization of the Oracle queue
///
///
/// Accounts:
///
/// 0; `[signer]` The payer of the transaction fees
/// 1; `[]` The Oracle public key
/// 2; `[]` The Oracle data account
/// 3; `[]` The Oracle queue account (PDA to be created)
/// 4; `[]` The System program
///
/// Requirements:
///
/// - The payer (account 0) must be a signer.
/// - The Oracle data account (account 2) must have the correct seeds ([ORACLE_DATA, oracle.key]).
/// - The Oracle queue account (account 3) must be empty and use the correct seeds ([QUEUE, oracle.key, index]).
/// - The Oracle must have been registered for at least 200 slots.
///
/// 1. Parse the instruction data and extract arguments (InitializeOracleQueue).
/// 2. Confirm the Oracle is authorized (enough time has passed since registration).
/// 3. Create the Oracle queue PDA.
/// 4. Write the default QueueAccount data to the new PDA.
pub fn process_initialize_oracle_queue(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult {
// Parse args.
let args = InitializeOracleQueue::try_from_bytes(data)?;
// Load accounts.
let [signer_info, oracle_info, oracle_data_info, oracle_queue_info, system_program] = accounts
else {
return Err(ProgramError::NotEnoughAccountKeys);
};
signer_info.is_signer()?;
oracle_data_info.has_seeds(
&[ORACLE_DATA, oracle_info.key.to_bytes().as_ref()],
&ephemeral_vrf_api::ID,
)?;
oracle_queue_info.is_writable()?.is_empty()?.has_seeds(
&[QUEUE, oracle_info.key.to_bytes().as_ref(), &[args.index]],
&ephemeral_vrf_api::ID,
)?;
let oracle_data = oracle_data_info.as_account_mut::<Oracle>(&ephemeral_vrf_api::ID)?;
#[cfg(not(feature = "test-sbf"))]
let current_slot = Clock::get()?.slot;
#[cfg(feature = "test-sbf")]
let current_slot = 500;
if current_slot - oracle_data.registration_slot < 200 {
log(format!(
"Oracle {} not authorized or not yet reached an operational slot",
oracle_info.key
));
return Err(Unauthorized.into());
}
let mut oracle_queue_bytes = vec![];
let oracle_queue = QueueAccount {
index: args.index,
..Default::default()
};
oracle_queue.to_bytes_with_discriminator(&mut oracle_queue_bytes)?;
create_pda(
oracle_queue_info,
&ephemeral_vrf_api::ID,
oracle_queue_bytes.len(),
&[QUEUE, oracle_info.key.to_bytes().as_ref(), &[args.index]],
oracle_queue_pda(oracle_info.key, args.index).1,
system_program,
signer_info,
)?;
{
let mut oracle_queue_data = oracle_queue_info.try_borrow_mut_data()?;
oracle_queue_data.copy_from_slice(&oracle_queue_bytes);
}
Ok(())
}