1use crate::account::AccountView;
11use crate::address::Address;
12use crate::error::ProgramError;
13use crate::instruction::{InstructionAccount, InstructionView, Signer};
14use crate::ProgramResult;
15
16pub const SYSTEM_PROGRAM_ID: Address = Address::new_from_array([
18 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
19]);
20
21pub use hopper_native::system::{
22 NonceState, MAX_SEED_LEN, NONCE_ACCOUNT_LEN, NONCE_STATE_INITIALIZED, NONCE_VERSION_CURRENT,
23 RECENT_BLOCKHASHES_ID, RENT_SYSVAR_ID,
24};
25
26#[doc(hidden)]
60pub mod encoders {
61 #[inline(always)]
65 pub fn encode_create_account(lamports: u64, space: u64, owner: &[u8; 32]) -> [u8; 52] {
66 let mut data = [0u8; 52];
67 data[0..4].copy_from_slice(&0u32.to_le_bytes());
68 data[4..12].copy_from_slice(&lamports.to_le_bytes());
69 data[12..20].copy_from_slice(&space.to_le_bytes());
70 data[20..52].copy_from_slice(owner);
71 data
72 }
73
74 #[inline(always)]
78 pub fn encode_create_account_allow_prefund(
79 lamports: u64,
80 space: u64,
81 owner: &[u8; 32],
82 ) -> [u8; 52] {
83 let mut data = [0u8; 52];
84 data[0..4].copy_from_slice(&13u32.to_le_bytes());
85 data[4..12].copy_from_slice(&lamports.to_le_bytes());
86 data[12..20].copy_from_slice(&space.to_le_bytes());
87 data[20..52].copy_from_slice(owner);
88 data
89 }
90
91 #[inline(always)]
93 pub fn encode_transfer(lamports: u64) -> [u8; 12] {
94 let mut data = [0u8; 12];
95 data[0..4].copy_from_slice(&2u32.to_le_bytes());
96 data[4..12].copy_from_slice(&lamports.to_le_bytes());
97 data
98 }
99
100 #[inline(always)]
102 pub fn encode_assign(owner: &[u8; 32]) -> [u8; 36] {
103 let mut data = [0u8; 36];
104 data[0..4].copy_from_slice(&1u32.to_le_bytes());
105 data[4..36].copy_from_slice(owner);
106 data
107 }
108
109 #[inline(always)]
111 pub fn encode_allocate(space: u64) -> [u8; 12] {
112 let mut data = [0u8; 12];
113 data[0..4].copy_from_slice(&8u32.to_le_bytes());
114 data[4..12].copy_from_slice(&space.to_le_bytes());
115 data
116 }
117
118 #[inline(always)]
127 pub fn encode_advance_nonce_account() -> [u8; 4] {
128 4u32.to_le_bytes()
129 }
130
131 #[inline(always)]
134 pub fn encode_withdraw_nonce_account(lamports: u64) -> [u8; 12] {
135 let mut data = [0u8; 12];
136 data[0..4].copy_from_slice(&5u32.to_le_bytes());
137 data[4..12].copy_from_slice(&lamports.to_le_bytes());
138 data
139 }
140
141 #[inline(always)]
144 pub fn encode_initialize_nonce_account(authority: &[u8; 32]) -> [u8; 36] {
145 let mut data = [0u8; 36];
146 data[0..4].copy_from_slice(&6u32.to_le_bytes());
147 data[4..36].copy_from_slice(authority);
148 data
149 }
150
151 #[inline(always)]
154 pub fn encode_authorize_nonce_account(new_authority: &[u8; 32]) -> [u8; 36] {
155 let mut data = [0u8; 36];
156 data[0..4].copy_from_slice(&7u32.to_le_bytes());
157 data[4..36].copy_from_slice(new_authority);
158 data
159 }
160
161 #[inline(always)]
164 pub fn encode_upgrade_nonce_account() -> [u8; 4] {
165 12u32.to_le_bytes()
166 }
167}
168
169pub struct CreateAccount<'a, 'b> {
173 pub from: &'a AccountView<'a>,
174 pub to: &'a AccountView<'a>,
175 pub lamports: u64,
176 pub space: u64,
177 pub owner: &'b Address,
178}
179
180impl CreateAccount<'_, '_> {
181 #[inline]
182 pub fn invoke(&self) -> ProgramResult {
183 self.invoke_signed(&[])
184 }
185
186 #[inline]
187 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
188 let data =
189 encoders::encode_create_account(self.lamports, self.space, self.owner.as_array());
190
191 let accounts = [
192 InstructionAccount::writable_signer(self.from.address()),
193 InstructionAccount::writable_signer(self.to.address()),
194 ];
195 let views = [self.from, self.to];
196 let instruction = InstructionView {
197 program_id: &SYSTEM_PROGRAM_ID,
198 data: &data,
199 accounts: &accounts,
200 };
201
202 crate::cpi::invoke_signed(&instruction, &views, signers)
203 }
204}
205
206pub struct CreateAccountAllowPrefund<'a, 'b> {
225 pub to: &'a AccountView<'a>,
226 pub funding: Option<(&'a AccountView<'a>, u64)>,
229 pub space: u64,
230 pub owner: &'b Address,
231}
232
233impl CreateAccountAllowPrefund<'_, '_> {
234 #[inline]
235 pub fn invoke(&self) -> ProgramResult {
236 self.invoke_signed(&[])
237 }
238
239 #[inline]
240 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
241 let data = encoders::encode_create_account_allow_prefund(
242 self.funding.map_or(0, |(_, lamports)| lamports),
243 self.space,
244 self.owner.as_array(),
245 );
246
247 match self.funding {
248 Some((from, _)) => {
249 let accounts = [
250 InstructionAccount::writable_signer(self.to.address()),
251 InstructionAccount::writable_signer(from.address()),
252 ];
253 let views = [self.to, from];
254 let instruction = InstructionView {
255 program_id: &SYSTEM_PROGRAM_ID,
256 data: &data,
257 accounts: &accounts,
258 };
259 crate::cpi::invoke_signed(&instruction, &views, signers)
260 }
261 None => {
262 let accounts = [InstructionAccount::writable_signer(self.to.address())];
263 let views = [self.to];
264 let instruction = InstructionView {
265 program_id: &SYSTEM_PROGRAM_ID,
266 data: &data,
267 accounts: &accounts,
268 };
269 crate::cpi::invoke_signed(&instruction, &views, signers)
270 }
271 }
272 }
273}
274
275pub struct Transfer<'a> {
279 pub from: &'a AccountView<'a>,
280 pub to: &'a AccountView<'a>,
281 pub lamports: u64,
282}
283
284impl Transfer<'_> {
285 #[inline]
286 pub fn invoke(&self) -> ProgramResult {
287 self.invoke_signed(&[])
288 }
289
290 #[inline]
291 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
292 let data = encoders::encode_transfer(self.lamports);
293
294 let accounts = [
295 InstructionAccount::writable_signer(self.from.address()),
296 InstructionAccount::writable(self.to.address()),
297 ];
298 let views = [self.from, self.to];
299 let instruction = InstructionView {
300 program_id: &SYSTEM_PROGRAM_ID,
301 data: &data,
302 accounts: &accounts,
303 };
304
305 crate::cpi::invoke_signed(&instruction, &views, signers)
306 }
307}
308
309pub struct Assign<'a, 'b> {
313 pub account: &'a AccountView<'a>,
314 pub owner: &'b Address,
315}
316
317impl Assign<'_, '_> {
318 #[inline]
319 pub fn invoke(&self) -> ProgramResult {
320 self.invoke_signed(&[])
321 }
322
323 #[inline]
324 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
325 let data = encoders::encode_assign(self.owner.as_array());
326
327 let accounts = [InstructionAccount::writable_signer(self.account.address())];
328 let views = [self.account];
329 let instruction = InstructionView {
330 program_id: &SYSTEM_PROGRAM_ID,
331 data: &data,
332 accounts: &accounts,
333 };
334
335 crate::cpi::invoke_signed(&instruction, &views, signers)
336 }
337}
338
339pub struct Allocate<'a> {
343 pub account: &'a AccountView<'a>,
344 pub space: u64,
345}
346
347impl Allocate<'_> {
348 #[inline]
349 pub fn invoke(&self) -> ProgramResult {
350 self.invoke_signed(&[])
351 }
352
353 #[inline]
354 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
355 let data = encoders::encode_allocate(self.space);
356
357 let accounts = [InstructionAccount::writable_signer(self.account.address())];
358 let views = [self.account];
359 let instruction = InstructionView {
360 program_id: &SYSTEM_PROGRAM_ID,
361 data: &data,
362 accounts: &accounts,
363 };
364
365 crate::cpi::invoke_signed(&instruction, &views, signers)
366 }
367}
368
369pub struct CreateAccountWithSeed<'a, 'b> {
375 pub from: &'a AccountView<'a>,
376 pub to: &'a AccountView<'a>,
377 pub base: &'a AccountView<'a>,
378 pub seed: &'b [u8],
379 pub lamports: u64,
380 pub space: u64,
381 pub owner: &'b Address,
382}
383
384impl CreateAccountWithSeed<'_, '_> {
385 #[inline]
386 pub fn invoke(&self) -> ProgramResult {
387 self.invoke_signed(&[])
388 }
389
390 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
391 if self.seed.len() > MAX_SEED_LEN {
392 return Err(ProgramError::MaxSeedLengthExceeded);
393 }
394 let mut data = [0u8; 4 + 32 + 8 + MAX_SEED_LEN + 8 + 8 + 32];
395 data[0] = 3;
396 let mut n = 4;
397 data[n..n + 32].copy_from_slice(self.base.address().as_array());
398 n += 32;
399 data[n..n + 8].copy_from_slice(&(self.seed.len() as u64).to_le_bytes());
400 n += 8;
401 data[n..n + self.seed.len()].copy_from_slice(self.seed);
402 n += self.seed.len();
403 data[n..n + 8].copy_from_slice(&self.lamports.to_le_bytes());
404 n += 8;
405 data[n..n + 8].copy_from_slice(&self.space.to_le_bytes());
406 n += 8;
407 data[n..n + 32].copy_from_slice(self.owner.as_array());
408 n += 32;
409
410 let accounts = [
411 InstructionAccount::writable_signer(self.from.address()),
412 InstructionAccount::writable(self.to.address()),
413 InstructionAccount::readonly_signer(self.base.address()),
414 ];
415 let views = [self.from, self.to, self.base];
416 let instruction = InstructionView {
417 program_id: &SYSTEM_PROGRAM_ID,
418 data: &data[..n],
419 accounts: &accounts,
420 };
421 crate::cpi::invoke_signed(&instruction, &views, signers)
422 }
423}
424
425pub struct AllocateWithSeed<'a, 'b> {
427 pub account: &'a AccountView<'a>,
428 pub base: &'a AccountView<'a>,
429 pub seed: &'b [u8],
430 pub space: u64,
431 pub owner: &'b Address,
432}
433
434impl AllocateWithSeed<'_, '_> {
435 #[inline]
436 pub fn invoke(&self) -> ProgramResult {
437 self.invoke_signed(&[])
438 }
439
440 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
441 if self.seed.len() > MAX_SEED_LEN {
442 return Err(ProgramError::MaxSeedLengthExceeded);
443 }
444 let mut data = [0u8; 4 + 32 + 8 + MAX_SEED_LEN + 8 + 32];
445 data[0] = 9;
446 let mut n = 4;
447 data[n..n + 32].copy_from_slice(self.base.address().as_array());
448 n += 32;
449 data[n..n + 8].copy_from_slice(&(self.seed.len() as u64).to_le_bytes());
450 n += 8;
451 data[n..n + self.seed.len()].copy_from_slice(self.seed);
452 n += self.seed.len();
453 data[n..n + 8].copy_from_slice(&self.space.to_le_bytes());
454 n += 8;
455 data[n..n + 32].copy_from_slice(self.owner.as_array());
456 n += 32;
457
458 let accounts = [
459 InstructionAccount::writable(self.account.address()),
460 InstructionAccount::readonly_signer(self.base.address()),
461 ];
462 let views = [self.account, self.base];
463 let instruction = InstructionView {
464 program_id: &SYSTEM_PROGRAM_ID,
465 data: &data[..n],
466 accounts: &accounts,
467 };
468 crate::cpi::invoke_signed(&instruction, &views, signers)
469 }
470}
471
472pub struct AssignWithSeed<'a, 'b> {
474 pub account: &'a AccountView<'a>,
475 pub base: &'a AccountView<'a>,
476 pub seed: &'b [u8],
477 pub owner: &'b Address,
478}
479
480impl AssignWithSeed<'_, '_> {
481 #[inline]
482 pub fn invoke(&self) -> ProgramResult {
483 self.invoke_signed(&[])
484 }
485
486 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
487 if self.seed.len() > MAX_SEED_LEN {
488 return Err(ProgramError::MaxSeedLengthExceeded);
489 }
490 let mut data = [0u8; 4 + 32 + 8 + MAX_SEED_LEN + 32];
491 data[0] = 10;
492 let mut n = 4;
493 data[n..n + 32].copy_from_slice(self.base.address().as_array());
494 n += 32;
495 data[n..n + 8].copy_from_slice(&(self.seed.len() as u64).to_le_bytes());
496 n += 8;
497 data[n..n + self.seed.len()].copy_from_slice(self.seed);
498 n += self.seed.len();
499 data[n..n + 32].copy_from_slice(self.owner.as_array());
500 n += 32;
501
502 let accounts = [
503 InstructionAccount::writable(self.account.address()),
504 InstructionAccount::readonly_signer(self.base.address()),
505 ];
506 let views = [self.account, self.base];
507 let instruction = InstructionView {
508 program_id: &SYSTEM_PROGRAM_ID,
509 data: &data[..n],
510 accounts: &accounts,
511 };
512 crate::cpi::invoke_signed(&instruction, &views, signers)
513 }
514}
515
516pub struct TransferWithSeed<'a, 'b> {
518 pub from: &'a AccountView<'a>,
519 pub base: &'a AccountView<'a>,
520 pub to: &'a AccountView<'a>,
521 pub lamports: u64,
522 pub from_seed: &'b [u8],
523 pub from_owner: &'b Address,
524}
525
526impl TransferWithSeed<'_, '_> {
527 #[inline]
528 pub fn invoke(&self) -> ProgramResult {
529 self.invoke_signed(&[])
530 }
531
532 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
533 if self.from_seed.len() > MAX_SEED_LEN {
534 return Err(ProgramError::MaxSeedLengthExceeded);
535 }
536 let mut data = [0u8; 4 + 8 + 8 + MAX_SEED_LEN + 32];
537 data[0] = 11;
538 let mut n = 4;
539 data[n..n + 8].copy_from_slice(&self.lamports.to_le_bytes());
540 n += 8;
541 data[n..n + 8].copy_from_slice(&(self.from_seed.len() as u64).to_le_bytes());
542 n += 8;
543 data[n..n + self.from_seed.len()].copy_from_slice(self.from_seed);
544 n += self.from_seed.len();
545 data[n..n + 32].copy_from_slice(self.from_owner.as_array());
546 n += 32;
547
548 let accounts = [
549 InstructionAccount::writable(self.from.address()),
550 InstructionAccount::readonly_signer(self.base.address()),
551 InstructionAccount::writable(self.to.address()),
552 ];
553 let views = [self.from, self.base, self.to];
554 let instruction = InstructionView {
555 program_id: &SYSTEM_PROGRAM_ID,
556 data: &data[..n],
557 accounts: &accounts,
558 };
559 crate::cpi::invoke_signed(&instruction, &views, signers)
560 }
561}
562
563pub struct AdvanceNonceAccount<'a> {
569 pub nonce: &'a AccountView<'a>,
570 pub recent_blockhashes: &'a AccountView<'a>,
571 pub authority: &'a AccountView<'a>,
572}
573
574impl AdvanceNonceAccount<'_> {
575 #[inline]
576 pub fn invoke(&self) -> ProgramResult {
577 self.invoke_signed(&[])
578 }
579
580 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
581 let data = encoders::encode_advance_nonce_account();
582 let accounts = [
583 InstructionAccount::writable(self.nonce.address()),
584 InstructionAccount::readonly(self.recent_blockhashes.address()),
585 InstructionAccount::readonly_signer(self.authority.address()),
586 ];
587 let views = [self.nonce, self.recent_blockhashes, self.authority];
588 let instruction = InstructionView {
589 program_id: &SYSTEM_PROGRAM_ID,
590 data: &data,
591 accounts: &accounts,
592 };
593 crate::cpi::invoke_signed(&instruction, &views, signers)
594 }
595}
596
597pub struct WithdrawNonceAccount<'a> {
599 pub nonce: &'a AccountView<'a>,
600 pub to: &'a AccountView<'a>,
601 pub recent_blockhashes: &'a AccountView<'a>,
602 pub rent: &'a AccountView<'a>,
603 pub authority: &'a AccountView<'a>,
604 pub lamports: u64,
605}
606
607impl WithdrawNonceAccount<'_> {
608 #[inline]
609 pub fn invoke(&self) -> ProgramResult {
610 self.invoke_signed(&[])
611 }
612
613 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
614 let data = encoders::encode_withdraw_nonce_account(self.lamports);
615 let accounts = [
616 InstructionAccount::writable(self.nonce.address()),
617 InstructionAccount::writable(self.to.address()),
618 InstructionAccount::readonly(self.recent_blockhashes.address()),
619 InstructionAccount::readonly(self.rent.address()),
620 InstructionAccount::readonly_signer(self.authority.address()),
621 ];
622 let views = [
623 self.nonce,
624 self.to,
625 self.recent_blockhashes,
626 self.rent,
627 self.authority,
628 ];
629 let instruction = InstructionView {
630 program_id: &SYSTEM_PROGRAM_ID,
631 data: &data,
632 accounts: &accounts,
633 };
634 crate::cpi::invoke_signed(&instruction, &views, signers)
635 }
636}
637
638pub struct InitializeNonceAccount<'a, 'b> {
640 pub nonce: &'a AccountView<'a>,
641 pub recent_blockhashes: &'a AccountView<'a>,
642 pub rent: &'a AccountView<'a>,
643 pub authority: &'b Address,
644}
645
646impl InitializeNonceAccount<'_, '_> {
647 #[inline]
648 pub fn invoke(&self) -> ProgramResult {
649 self.invoke_signed(&[])
650 }
651
652 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
653 let data = encoders::encode_initialize_nonce_account(self.authority.as_array());
654 let accounts = [
655 InstructionAccount::writable(self.nonce.address()),
656 InstructionAccount::readonly(self.recent_blockhashes.address()),
657 InstructionAccount::readonly(self.rent.address()),
658 ];
659 let views = [self.nonce, self.recent_blockhashes, self.rent];
660 let instruction = InstructionView {
661 program_id: &SYSTEM_PROGRAM_ID,
662 data: &data,
663 accounts: &accounts,
664 };
665 crate::cpi::invoke_signed(&instruction, &views, signers)
666 }
667}
668
669pub struct AuthorizeNonceAccount<'a, 'b> {
671 pub nonce: &'a AccountView<'a>,
672 pub authority: &'a AccountView<'a>,
673 pub new_authority: &'b Address,
674}
675
676impl AuthorizeNonceAccount<'_, '_> {
677 #[inline]
678 pub fn invoke(&self) -> ProgramResult {
679 self.invoke_signed(&[])
680 }
681
682 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
683 let data = encoders::encode_authorize_nonce_account(self.new_authority.as_array());
684 let accounts = [
685 InstructionAccount::writable(self.nonce.address()),
686 InstructionAccount::readonly_signer(self.authority.address()),
687 ];
688 let views = [self.nonce, self.authority];
689 let instruction = InstructionView {
690 program_id: &SYSTEM_PROGRAM_ID,
691 data: &data,
692 accounts: &accounts,
693 };
694 crate::cpi::invoke_signed(&instruction, &views, signers)
695 }
696}
697
698pub struct UpgradeNonceAccount<'a> {
700 pub nonce: &'a AccountView<'a>,
701}
702
703impl UpgradeNonceAccount<'_> {
704 #[inline]
705 pub fn invoke(&self) -> ProgramResult {
706 let data = encoders::encode_upgrade_nonce_account();
707 let accounts = [InstructionAccount::writable(self.nonce.address())];
708 let views = [self.nonce];
709 let instruction = InstructionView {
710 program_id: &SYSTEM_PROGRAM_ID,
711 data: &data,
712 accounts: &accounts,
713 };
714 crate::cpi::invoke_signed(&instruction, &views, &[])
715 }
716}
717
718pub mod instructions {
720 pub use super::{
721 AdvanceNonceAccount, Allocate, AllocateWithSeed, Assign, AssignWithSeed,
722 AuthorizeNonceAccount, CreateAccount, CreateAccountAllowPrefund, CreateAccountWithSeed,
723 InitializeNonceAccount, Transfer, TransferWithSeed, UpgradeNonceAccount,
724 WithdrawNonceAccount,
725 };
726}
727
728#[cfg(test)]
729mod tests {
730 use super::*;
736
737 const OWNER: [u8; 32] = [
738 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
739 25, 26, 27, 28, 29, 30, 31,
740 ];
741
742 #[test]
743 fn create_account_encoder_matches_pre_refactor_golden_bytes() {
744 let d = encoders::encode_create_account(1, 165, &OWNER);
746 assert_eq!(d.len(), 52);
747 assert_eq!(&d[0..4], &[0, 0, 0, 0]);
748 assert_eq!(&d[4..12], &1u64.to_le_bytes());
749 assert_eq!(&d[12..20], &165u64.to_le_bytes());
750 assert_eq!(&d[20..52], &OWNER);
751 }
752
753 #[test]
754 fn transfer_encoder_matches_pre_refactor_golden_bytes() {
755 assert_eq!(
757 encoders::encode_transfer(1),
758 [2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
759 );
760 }
761
762 #[test]
763 fn assign_encoder_matches_pre_refactor_golden_bytes() {
764 let d = encoders::encode_assign(&OWNER);
765 assert_eq!(d.len(), 36);
766 assert_eq!(&d[0..4], &[1, 0, 0, 0]);
767 assert_eq!(&d[4..36], &OWNER);
768 }
769
770 #[test]
771 fn allocate_encoder_matches_pre_refactor_golden_bytes() {
772 assert_eq!(
774 encoders::encode_allocate(1),
775 [8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
776 );
777 }
778
779 #[test]
780 fn advance_nonce_account_encoder_matches_pre_refactor_golden_bytes() {
781 assert_eq!(encoders::encode_advance_nonce_account(), [4, 0, 0, 0]);
783 }
784
785 #[test]
786 fn withdraw_nonce_account_encoder_matches_pre_refactor_golden_bytes() {
787 assert_eq!(
789 encoders::encode_withdraw_nonce_account(1),
790 [5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
791 );
792 }
793
794 #[test]
795 fn initialize_nonce_account_encoder_matches_pre_refactor_golden_bytes() {
796 let d = encoders::encode_initialize_nonce_account(&OWNER);
798 assert_eq!(d.len(), 36);
799 assert_eq!(&d[0..4], &[6, 0, 0, 0]);
800 assert_eq!(&d[4..36], &OWNER);
801 }
802
803 #[test]
804 fn authorize_nonce_account_encoder_matches_pre_refactor_golden_bytes() {
805 let d = encoders::encode_authorize_nonce_account(&OWNER);
807 assert_eq!(d.len(), 36);
808 assert_eq!(&d[0..4], &[7, 0, 0, 0]);
809 assert_eq!(&d[4..36], &OWNER);
810 }
811
812 #[test]
813 fn upgrade_nonce_account_encoder_matches_pre_refactor_golden_bytes() {
814 assert_eq!(encoders::encode_upgrade_nonce_account(), [12, 0, 0, 0]);
816 }
817}