1use borsh::BorshSerialize;
9use borsh::BorshDeserialize;
10
11pub const ROTATE_ROUND_DISCRIMINATOR: [u8; 8] = [3, 245, 202, 88, 161, 29, 51, 141];
12
13#[derive(Debug)]
15pub struct RotateRound {
16
17
18 pub authority: solana_address::Address,
19
20
21 pub satrush_config: solana_address::Address,
22
23
24 pub board: solana_address::Address,
25 pub current_round: solana_address::Address,
30 pub next_round: solana_address::Address,
37 pub slot_hashes: solana_address::Address,
42
43
44 pub system_program: solana_address::Address,
45 }
46
47impl RotateRound {
48 pub fn instruction(&self) -> solana_instruction::Instruction {
49 self.instruction_with_remaining_accounts(&[])
50 }
51 #[allow(clippy::arithmetic_side_effects)]
52 #[allow(clippy::vec_init_then_push)]
53 pub fn instruction_with_remaining_accounts(&self, remaining_accounts: &[solana_instruction::AccountMeta]) -> solana_instruction::Instruction {
54 let mut accounts = Vec::with_capacity(7+ remaining_accounts.len());
55 accounts.push(solana_instruction::AccountMeta::new(
56 self.authority,
57 true
58 ));
59 accounts.push(solana_instruction::AccountMeta::new_readonly(
60 self.satrush_config,
61 false
62 ));
63 accounts.push(solana_instruction::AccountMeta::new(
64 self.board,
65 false
66 ));
67 accounts.push(solana_instruction::AccountMeta::new(
68 self.current_round,
69 false
70 ));
71 accounts.push(solana_instruction::AccountMeta::new(
72 self.next_round,
73 false
74 ));
75 accounts.push(solana_instruction::AccountMeta::new_readonly(
76 self.slot_hashes,
77 false
78 ));
79 accounts.push(solana_instruction::AccountMeta::new_readonly(
80 self.system_program,
81 false
82 ));
83 accounts.extend_from_slice(remaining_accounts);
84 let data = RotateRoundInstructionData::new().try_to_vec().unwrap();
85
86 solana_instruction::Instruction {
87 program_id: crate::SATRUSH_ID,
88 accounts,
89 data,
90 }
91 }
92}
93
94#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
95 pub struct RotateRoundInstructionData {
96 discriminator: [u8; 8],
97 }
98
99impl RotateRoundInstructionData {
100 pub fn new() -> Self {
101 Self {
102 discriminator: [3, 245, 202, 88, 161, 29, 51, 141],
103 }
104 }
105
106 pub(crate) fn try_to_vec(&self) -> Result<Vec<u8>, std::io::Error> {
107 borsh::to_vec(self)
108 }
109 }
110
111impl Default for RotateRoundInstructionData {
112 fn default() -> Self {
113 Self::new()
114 }
115}
116
117
118
119#[derive(Clone, Debug, Default)]
131pub struct RotateRoundBuilder {
132 authority: Option<solana_address::Address>,
133 satrush_config: Option<solana_address::Address>,
134 board: Option<solana_address::Address>,
135 current_round: Option<solana_address::Address>,
136 next_round: Option<solana_address::Address>,
137 slot_hashes: Option<solana_address::Address>,
138 system_program: Option<solana_address::Address>,
139 __remaining_accounts: Vec<solana_instruction::AccountMeta>,
140}
141
142impl RotateRoundBuilder {
143 pub fn new() -> Self {
144 Self::default()
145 }
146 #[inline(always)]
147 pub fn authority(&mut self, authority: solana_address::Address) -> &mut Self {
148 self.authority = Some(authority);
149 self
150 }
151 #[inline(always)]
152 pub fn satrush_config(&mut self, satrush_config: solana_address::Address) -> &mut Self {
153 self.satrush_config = Some(satrush_config);
154 self
155 }
156 #[inline(always)]
157 pub fn board(&mut self, board: solana_address::Address) -> &mut Self {
158 self.board = Some(board);
159 self
160 }
161 #[inline(always)]
163 pub fn current_round(&mut self, current_round: solana_address::Address) -> &mut Self {
164 self.current_round = Some(current_round);
165 self
166 }
167 #[inline(always)]
171 pub fn next_round(&mut self, next_round: solana_address::Address) -> &mut Self {
172 self.next_round = Some(next_round);
173 self
174 }
175 #[inline(always)]
178 pub fn slot_hashes(&mut self, slot_hashes: solana_address::Address) -> &mut Self {
179 self.slot_hashes = Some(slot_hashes);
180 self
181 }
182 #[inline(always)]
184 pub fn system_program(&mut self, system_program: solana_address::Address) -> &mut Self {
185 self.system_program = Some(system_program);
186 self
187 }
188 #[inline(always)]
190 pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self {
191 self.__remaining_accounts.push(account);
192 self
193 }
194 #[inline(always)]
196 pub fn add_remaining_accounts(&mut self, accounts: &[solana_instruction::AccountMeta]) -> &mut Self {
197 self.__remaining_accounts.extend_from_slice(accounts);
198 self
199 }
200 #[allow(clippy::clone_on_copy)]
201 pub fn instruction(&self) -> solana_instruction::Instruction {
202 let accounts = RotateRound {
203 authority: self.authority.expect("authority is not set"),
204 satrush_config: self.satrush_config.expect("satrush_config is not set"),
205 board: self.board.expect("board is not set"),
206 current_round: self.current_round.expect("current_round is not set"),
207 next_round: self.next_round.expect("next_round is not set"),
208 slot_hashes: self.slot_hashes.unwrap_or(solana_address::address!("SysvarS1otHashes111111111111111111111111111")),
209 system_program: self.system_program.unwrap_or(solana_address::address!("11111111111111111111111111111111")),
210 };
211
212 accounts.instruction_with_remaining_accounts(&self.__remaining_accounts)
213 }
214}
215
216 pub struct RotateRoundCpiAccounts<'a, 'b> {
218
219
220 pub authority: &'b solana_account_info::AccountInfo<'a>,
221
222
223 pub satrush_config: &'b solana_account_info::AccountInfo<'a>,
224
225
226 pub board: &'b solana_account_info::AccountInfo<'a>,
227 pub current_round: &'b solana_account_info::AccountInfo<'a>,
232 pub next_round: &'b solana_account_info::AccountInfo<'a>,
239 pub slot_hashes: &'b solana_account_info::AccountInfo<'a>,
244
245
246 pub system_program: &'b solana_account_info::AccountInfo<'a>,
247 }
248
249pub struct RotateRoundCpi<'a, 'b> {
251 pub __program: &'b solana_account_info::AccountInfo<'a>,
253
254
255 pub authority: &'b solana_account_info::AccountInfo<'a>,
256
257
258 pub satrush_config: &'b solana_account_info::AccountInfo<'a>,
259
260
261 pub board: &'b solana_account_info::AccountInfo<'a>,
262 pub current_round: &'b solana_account_info::AccountInfo<'a>,
267 pub next_round: &'b solana_account_info::AccountInfo<'a>,
274 pub slot_hashes: &'b solana_account_info::AccountInfo<'a>,
279
280
281 pub system_program: &'b solana_account_info::AccountInfo<'a>,
282 }
283
284impl<'a, 'b> RotateRoundCpi<'a, 'b> {
285 pub fn new(
286 program: &'b solana_account_info::AccountInfo<'a>,
287 accounts: RotateRoundCpiAccounts<'a, 'b>,
288 ) -> Self {
289 Self {
290 __program: program,
291 authority: accounts.authority,
292 satrush_config: accounts.satrush_config,
293 board: accounts.board,
294 current_round: accounts.current_round,
295 next_round: accounts.next_round,
296 slot_hashes: accounts.slot_hashes,
297 system_program: accounts.system_program,
298 }
299 }
300 #[inline(always)]
301 pub fn invoke(&self) -> solana_program_error::ProgramResult {
302 self.invoke_signed_with_remaining_accounts(&[], &[])
303 }
304 #[inline(always)]
305 pub fn invoke_with_remaining_accounts(&self, remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)]) -> solana_program_error::ProgramResult {
306 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
307 }
308 #[inline(always)]
309 pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult {
310 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
311 }
312 #[allow(clippy::arithmetic_side_effects)]
313 #[allow(clippy::clone_on_copy)]
314 #[allow(clippy::vec_init_then_push)]
315 pub fn invoke_signed_with_remaining_accounts(
316 &self,
317 signers_seeds: &[&[&[u8]]],
318 remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)]
319 ) -> solana_program_error::ProgramResult {
320 let mut accounts = Vec::with_capacity(7+ remaining_accounts.len());
321 accounts.push(solana_instruction::AccountMeta::new(
322 *self.authority.key,
323 true
324 ));
325 accounts.push(solana_instruction::AccountMeta::new_readonly(
326 *self.satrush_config.key,
327 false
328 ));
329 accounts.push(solana_instruction::AccountMeta::new(
330 *self.board.key,
331 false
332 ));
333 accounts.push(solana_instruction::AccountMeta::new(
334 *self.current_round.key,
335 false
336 ));
337 accounts.push(solana_instruction::AccountMeta::new(
338 *self.next_round.key,
339 false
340 ));
341 accounts.push(solana_instruction::AccountMeta::new_readonly(
342 *self.slot_hashes.key,
343 false
344 ));
345 accounts.push(solana_instruction::AccountMeta::new_readonly(
346 *self.system_program.key,
347 false
348 ));
349 remaining_accounts.iter().for_each(|remaining_account| {
350 accounts.push(solana_instruction::AccountMeta {
351 pubkey: *remaining_account.0.key,
352 is_signer: remaining_account.1,
353 is_writable: remaining_account.2,
354 })
355 });
356 let data = RotateRoundInstructionData::new().try_to_vec().unwrap();
357
358 let instruction = solana_instruction::Instruction {
359 program_id: crate::SATRUSH_ID,
360 accounts,
361 data,
362 };
363 let mut account_infos = Vec::with_capacity(8 + remaining_accounts.len());
364 account_infos.push(self.__program.clone());
365 account_infos.push(self.authority.clone());
366 account_infos.push(self.satrush_config.clone());
367 account_infos.push(self.board.clone());
368 account_infos.push(self.current_round.clone());
369 account_infos.push(self.next_round.clone());
370 account_infos.push(self.slot_hashes.clone());
371 account_infos.push(self.system_program.clone());
372 remaining_accounts.iter().for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
373
374 if signers_seeds.is_empty() {
375 solana_cpi::invoke(&instruction, &account_infos)
376 } else {
377 solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds)
378 }
379 }
380}
381
382#[derive(Clone, Debug)]
394pub struct RotateRoundCpiBuilder<'a, 'b> {
395 instruction: Box<RotateRoundCpiBuilderInstruction<'a, 'b>>,
396}
397
398impl<'a, 'b> RotateRoundCpiBuilder<'a, 'b> {
399 pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self {
400 let instruction = Box::new(RotateRoundCpiBuilderInstruction {
401 __program: program,
402 authority: None,
403 satrush_config: None,
404 board: None,
405 current_round: None,
406 next_round: None,
407 slot_hashes: None,
408 system_program: None,
409 __remaining_accounts: Vec::new(),
410 });
411 Self { instruction }
412 }
413 #[inline(always)]
414 pub fn authority(&mut self, authority: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
415 self.instruction.authority = Some(authority);
416 self
417 }
418 #[inline(always)]
419 pub fn satrush_config(&mut self, satrush_config: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
420 self.instruction.satrush_config = Some(satrush_config);
421 self
422 }
423 #[inline(always)]
424 pub fn board(&mut self, board: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
425 self.instruction.board = Some(board);
426 self
427 }
428 #[inline(always)]
430 pub fn current_round(&mut self, current_round: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
431 self.instruction.current_round = Some(current_round);
432 self
433 }
434 #[inline(always)]
438 pub fn next_round(&mut self, next_round: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
439 self.instruction.next_round = Some(next_round);
440 self
441 }
442 #[inline(always)]
444 pub fn slot_hashes(&mut self, slot_hashes: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
445 self.instruction.slot_hashes = Some(slot_hashes);
446 self
447 }
448 #[inline(always)]
449 pub fn system_program(&mut self, system_program: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
450 self.instruction.system_program = Some(system_program);
451 self
452 }
453 #[inline(always)]
455 pub fn add_remaining_account(&mut self, account: &'b solana_account_info::AccountInfo<'a>, is_writable: bool, is_signer: bool) -> &mut Self {
456 self.instruction.__remaining_accounts.push((account, is_writable, is_signer));
457 self
458 }
459 #[inline(always)]
464 pub fn add_remaining_accounts(&mut self, accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)]) -> &mut Self {
465 self.instruction.__remaining_accounts.extend_from_slice(accounts);
466 self
467 }
468 #[inline(always)]
469 pub fn invoke(&self) -> solana_program_error::ProgramResult {
470 self.invoke_signed(&[])
471 }
472 #[allow(clippy::clone_on_copy)]
473 #[allow(clippy::vec_init_then_push)]
474 pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult {
475 let instruction = RotateRoundCpi {
476 __program: self.instruction.__program,
477
478 authority: self.instruction.authority.expect("authority is not set"),
479
480 satrush_config: self.instruction.satrush_config.expect("satrush_config is not set"),
481
482 board: self.instruction.board.expect("board is not set"),
483
484 current_round: self.instruction.current_round.expect("current_round is not set"),
485
486 next_round: self.instruction.next_round.expect("next_round is not set"),
487
488 slot_hashes: self.instruction.slot_hashes.expect("slot_hashes is not set"),
489
490 system_program: self.instruction.system_program.expect("system_program is not set"),
491 };
492 instruction.invoke_signed_with_remaining_accounts(signers_seeds, &self.instruction.__remaining_accounts)
493 }
494}
495
496#[derive(Clone, Debug)]
497struct RotateRoundCpiBuilderInstruction<'a, 'b> {
498 __program: &'b solana_account_info::AccountInfo<'a>,
499 authority: Option<&'b solana_account_info::AccountInfo<'a>>,
500 satrush_config: Option<&'b solana_account_info::AccountInfo<'a>>,
501 board: Option<&'b solana_account_info::AccountInfo<'a>>,
502 current_round: Option<&'b solana_account_info::AccountInfo<'a>>,
503 next_round: Option<&'b solana_account_info::AccountInfo<'a>>,
504 slot_hashes: Option<&'b solana_account_info::AccountInfo<'a>>,
505 system_program: Option<&'b solana_account_info::AccountInfo<'a>>,
506 __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>,
508}
509