|
15 | 15 | solana_instruction::{error::InstructionError, AccountMeta, Instruction}, |
16 | 16 | solana_program_error::ProgramError, |
17 | 17 | solana_program_pack::Pack, |
18 | | - solana_program_test::tokio, |
19 | 18 | solana_pubkey::Pubkey, |
20 | 19 | solana_rent::Rent, |
21 | 20 | solana_sdk_ids::bpf_loader_upgradeable, |
@@ -53,8 +52,7 @@ fn create_token_account( |
53 | 52 | } |
54 | 53 | } |
55 | 54 |
|
56 | | -/// Creates a Mollusk instance with the default feature set, excluding the |
57 | | -/// `bpf_account_data_direct_mapping` feature. |
| 55 | +/// Creates a Mollusk instance with the default feature set. |
58 | 56 | fn mollusk() -> Mollusk { |
59 | 57 | let mut mollusk = Mollusk::default(); |
60 | 58 | mollusk.add_program( |
@@ -94,8 +92,8 @@ fn unwrap_lamports_instruction( |
94 | 92 | }) |
95 | 93 | } |
96 | 94 |
|
97 | | -#[tokio::test] |
98 | | -async fn unwrap_lamports() { |
| 95 | +#[test] |
| 96 | +fn unwrap_lamports() { |
99 | 97 | let native_mint = Pubkey::new_from_array(native_mint::ID); |
100 | 98 | let authority_key = Pubkey::new_unique(); |
101 | 99 | let destination_account_key = Pubkey::new_unique(); |
@@ -141,16 +139,16 @@ async fn unwrap_lamports() { |
141 | 139 |
|
142 | 140 | // And the remaining amount must be 0. |
143 | 141 |
|
144 | | - result.resulting_accounts.iter().for_each(|(key, account)| { |
145 | | - if *key == source_account_key { |
146 | | - let token_account = spl_token::state::Account::unpack(&account.data).unwrap(); |
147 | | - assert_eq!(token_account.amount, 0); |
148 | | - } |
149 | | - }); |
| 142 | + let account = result.get_account(&source_account_key); |
| 143 | + assert!(account.is_some()); |
| 144 | + |
| 145 | + let account = account.unwrap(); |
| 146 | + let token_account = spl_token::state::Account::unpack(&account.data).unwrap(); |
| 147 | + assert_eq!(token_account.amount, 0); |
150 | 148 | } |
151 | 149 |
|
152 | | -#[tokio::test] |
153 | | -async fn unwrap_lamports_with_amount() { |
| 150 | +#[test] |
| 151 | +fn unwrap_lamports_with_amount() { |
154 | 152 | let native_mint = Pubkey::new_from_array(native_mint::ID); |
155 | 153 | let authority_key = Pubkey::new_unique(); |
156 | 154 | let destination_account_key = Pubkey::new_unique(); |
@@ -196,16 +194,16 @@ async fn unwrap_lamports_with_amount() { |
196 | 194 |
|
197 | 195 | // And the remaining amount must be 0. |
198 | 196 |
|
199 | | - result.resulting_accounts.iter().for_each(|(key, account)| { |
200 | | - if *key == source_account_key { |
201 | | - let token_account = spl_token::state::Account::unpack(&account.data).unwrap(); |
202 | | - assert_eq!(token_account.amount, 0); |
203 | | - } |
204 | | - }); |
| 197 | + let account = result.get_account(&source_account_key); |
| 198 | + assert!(account.is_some()); |
| 199 | + |
| 200 | + let account = account.unwrap(); |
| 201 | + let token_account = spl_token::state::Account::unpack(&account.data).unwrap(); |
| 202 | + assert_eq!(token_account.amount, 0); |
205 | 203 | } |
206 | 204 |
|
207 | | -#[tokio::test] |
208 | | -async fn fail_unwrap_lamports_with_insufficient_funds() { |
| 205 | +#[test] |
| 206 | +fn fail_unwrap_lamports_with_insufficient_funds() { |
209 | 207 | let native_mint = Pubkey::new_from_array(native_mint::ID); |
210 | 208 | let authority_key = Pubkey::new_unique(); |
211 | 209 | let destination_account_key = Pubkey::new_unique(); |
@@ -245,8 +243,8 @@ async fn fail_unwrap_lamports_with_insufficient_funds() { |
245 | 243 | ); |
246 | 244 | } |
247 | 245 |
|
248 | | -#[tokio::test] |
249 | | -async fn unwrap_lamports_with_parial_amount() { |
| 246 | +#[test] |
| 247 | +fn unwrap_lamports_with_parial_amount() { |
250 | 248 | let native_mint = Pubkey::new_from_array(native_mint::ID); |
251 | 249 | let authority_key = Pubkey::new_unique(); |
252 | 250 | let destination_account_key = Pubkey::new_unique(); |
@@ -294,16 +292,16 @@ async fn unwrap_lamports_with_parial_amount() { |
294 | 292 |
|
295 | 293 | // And the remaining amount must be 1_000_000_000. |
296 | 294 |
|
297 | | - result.resulting_accounts.iter().for_each(|(key, account)| { |
298 | | - if *key == source_account_key { |
299 | | - let token_account = spl_token::state::Account::unpack(&account.data).unwrap(); |
300 | | - assert_eq!(token_account.amount, 1_000_000_000); |
301 | | - } |
302 | | - }); |
| 295 | + let account = result.get_account(&source_account_key); |
| 296 | + assert!(account.is_some()); |
| 297 | + |
| 298 | + let account = account.unwrap(); |
| 299 | + let token_account = spl_token::state::Account::unpack(&account.data).unwrap(); |
| 300 | + assert_eq!(token_account.amount, 1_000_000_000); |
303 | 301 | } |
304 | 302 |
|
305 | | -#[tokio::test] |
306 | | -async fn fail_unwrap_lamports_with_invalid_authority() { |
| 303 | +#[test] |
| 304 | +fn fail_unwrap_lamports_with_invalid_authority() { |
307 | 305 | let native_mint = Pubkey::new_from_array(native_mint::ID); |
308 | 306 | let authority_key = Pubkey::new_unique(); |
309 | 307 | let destination_account_key = Pubkey::new_unique(); |
@@ -344,8 +342,8 @@ async fn fail_unwrap_lamports_with_invalid_authority() { |
344 | 342 | ); |
345 | 343 | } |
346 | 344 |
|
347 | | -#[tokio::test] |
348 | | -async fn fail_unwrap_lamports_with_non_native_account() { |
| 345 | +#[test] |
| 346 | +fn fail_unwrap_lamports_with_non_native_account() { |
349 | 347 | let mint = Pubkey::new_unique(); |
350 | 348 | let authority_key = Pubkey::new_unique(); |
351 | 349 | let destination_account_key = Pubkey::new_unique(); |
@@ -380,22 +378,14 @@ async fn fail_unwrap_lamports_with_non_native_account() { |
380 | 378 | (destination_account_key, Account::default()), |
381 | 379 | (authority_key, Account::default()), |
382 | 380 | ], |
383 | | - &[ |
384 | | - Check::err(ProgramError::Custom( |
385 | | - TokenError::NonNativeNotSupported as u32, |
386 | | - )), |
387 | | - Check::account(&source_account_key) |
388 | | - .lamports( |
389 | | - Rent::default().minimum_balance(size_of::<TokenAccount>()) + 2_000_000_000, |
390 | | - ) |
391 | | - .build(), |
392 | | - Check::account(&destination_account_key).lamports(0).build(), |
393 | | - ], |
| 381 | + &[Check::err(ProgramError::Custom( |
| 382 | + TokenError::NonNativeNotSupported as u32, |
| 383 | + ))], |
394 | 384 | ); |
395 | 385 | } |
396 | 386 |
|
397 | | -#[tokio::test] |
398 | | -async fn unwrap_lamports_with_self_transfer() { |
| 387 | +#[test] |
| 388 | +fn unwrap_lamports_with_self_transfer() { |
399 | 389 | let native_mint = Pubkey::new_from_array(native_mint::ID); |
400 | 390 | let authority_key = Pubkey::new_unique(); |
401 | 391 |
|
@@ -437,22 +427,22 @@ async fn unwrap_lamports_with_self_transfer() { |
437 | 427 | ], |
438 | 428 | ); |
439 | 429 |
|
440 | | - result.resulting_accounts.iter().for_each(|(key, account)| { |
441 | | - if *key == source_account_key { |
442 | | - let token_account = spl_token::state::Account::unpack(&account.data).unwrap(); |
443 | | - assert_eq!(token_account.amount, 2_000_000_000); |
444 | | - } |
445 | | - }); |
| 430 | + let account = result.get_account(&source_account_key); |
| 431 | + assert!(account.is_some()); |
| 432 | + |
| 433 | + let account = account.unwrap(); |
| 434 | + let token_account = spl_token::state::Account::unpack(&account.data).unwrap(); |
| 435 | + assert_eq!(token_account.amount, 2_000_000_000); |
446 | 436 | } |
447 | 437 |
|
448 | | -#[tokio::test] |
449 | | -async fn fail_unwrap_lamports_with_invalid_native_account() { |
| 438 | +#[test] |
| 439 | +fn fail_unwrap_lamports_with_invalid_native_account() { |
450 | 440 | let native_mint = Pubkey::new_from_array(native_mint::ID); |
451 | 441 | let authority_key = Pubkey::new_unique(); |
452 | 442 | let destination_account_key = Pubkey::new_unique(); |
453 | 443 | let invalid_program_owner = Pubkey::new_unique(); |
454 | 444 |
|
455 | | - // non-native account: |
| 445 | + // native account: |
456 | 446 | // - amount: 2_000_000_000 |
457 | 447 | let source_account_key = Pubkey::new_unique(); |
458 | 448 | let mut source_account = create_token_account( |
@@ -487,3 +477,153 @@ async fn fail_unwrap_lamports_with_invalid_native_account() { |
487 | 477 | )], |
488 | 478 | ); |
489 | 479 | } |
| 480 | + |
| 481 | +#[test] |
| 482 | +fn unwrap_lamports_to_native_account() { |
| 483 | + let native_mint = Pubkey::new_from_array(native_mint::ID); |
| 484 | + let authority_key = Pubkey::new_unique(); |
| 485 | + |
| 486 | + // native account: |
| 487 | + // - amount: 2_000_000_000 |
| 488 | + let source_account_key = Pubkey::new_unique(); |
| 489 | + let source_account = create_token_account( |
| 490 | + &native_mint, |
| 491 | + &authority_key, |
| 492 | + true, |
| 493 | + 2_000_000_000, |
| 494 | + &TOKEN_PROGRAM_ID, |
| 495 | + ); |
| 496 | + |
| 497 | + // destination native account: |
| 498 | + // - amount: 0 |
| 499 | + let destination_account_key = Pubkey::new_unique(); |
| 500 | + let destination_account = |
| 501 | + create_token_account(&native_mint, &authority_key, true, 0, &TOKEN_PROGRAM_ID); |
| 502 | + |
| 503 | + let instruction = unwrap_lamports_instruction( |
| 504 | + &source_account_key, |
| 505 | + &destination_account_key, |
| 506 | + &authority_key, |
| 507 | + None, |
| 508 | + ) |
| 509 | + .unwrap(); |
| 510 | + |
| 511 | + // It should succeed to unwrap 2_000_000_000 lamports. |
| 512 | + |
| 513 | + let result = mollusk().process_and_validate_instruction( |
| 514 | + &instruction, |
| 515 | + &[ |
| 516 | + (source_account_key, source_account), |
| 517 | + (destination_account_key, destination_account), |
| 518 | + (authority_key, Account::default()), |
| 519 | + ], |
| 520 | + &[ |
| 521 | + Check::success(), |
| 522 | + Check::account(&destination_account_key) |
| 523 | + .lamports( |
| 524 | + Rent::default().minimum_balance(size_of::<TokenAccount>()) + 2_000_000_000, |
| 525 | + ) |
| 526 | + .build(), |
| 527 | + Check::account(&source_account_key) |
| 528 | + .lamports(Rent::default().minimum_balance(size_of::<TokenAccount>())) |
| 529 | + .build(), |
| 530 | + ], |
| 531 | + ); |
| 532 | + |
| 533 | + // And the remaining amount on the source account must be 0. |
| 534 | + |
| 535 | + let account = result.get_account(&source_account_key); |
| 536 | + assert!(account.is_some()); |
| 537 | + |
| 538 | + let account = account.unwrap(); |
| 539 | + let token_account = spl_token::state::Account::unpack(&account.data).unwrap(); |
| 540 | + assert_eq!(token_account.amount, 0); |
| 541 | + |
| 542 | + // And the amount on the destination account must be 0 since we transferred |
| 543 | + // lamports directly to the account. |
| 544 | + |
| 545 | + let account = result.get_account(&destination_account_key); |
| 546 | + assert!(account.is_some()); |
| 547 | + |
| 548 | + let account = account.unwrap(); |
| 549 | + let token_account = spl_token::state::Account::unpack(&account.data).unwrap(); |
| 550 | + assert_eq!(token_account.amount, 0); |
| 551 | +} |
| 552 | + |
| 553 | +#[test] |
| 554 | +fn unwrap_lamports_to_token_account() { |
| 555 | + let native_mint = Pubkey::new_from_array(native_mint::ID); |
| 556 | + let authority_key = Pubkey::new_unique(); |
| 557 | + let non_native_mint = Pubkey::new_unique(); |
| 558 | + |
| 559 | + // native account: |
| 560 | + // - amount: 2_000_000_000 |
| 561 | + let source_account_key = Pubkey::new_unique(); |
| 562 | + let source_account = create_token_account( |
| 563 | + &native_mint, |
| 564 | + &authority_key, |
| 565 | + true, |
| 566 | + 2_000_000_000, |
| 567 | + &TOKEN_PROGRAM_ID, |
| 568 | + ); |
| 569 | + |
| 570 | + // destination non-native account: |
| 571 | + // - amount: 0 |
| 572 | + let destination_account_key = Pubkey::new_unique(); |
| 573 | + let destination_account = create_token_account( |
| 574 | + &non_native_mint, |
| 575 | + &authority_key, |
| 576 | + false, |
| 577 | + 0, |
| 578 | + &TOKEN_PROGRAM_ID, |
| 579 | + ); |
| 580 | + |
| 581 | + let instruction = unwrap_lamports_instruction( |
| 582 | + &source_account_key, |
| 583 | + &destination_account_key, |
| 584 | + &authority_key, |
| 585 | + None, |
| 586 | + ) |
| 587 | + .unwrap(); |
| 588 | + |
| 589 | + // It should succeed to unwrap 2_000_000_000 lamports. |
| 590 | + |
| 591 | + let result = mollusk().process_and_validate_instruction( |
| 592 | + &instruction, |
| 593 | + &[ |
| 594 | + (source_account_key, source_account), |
| 595 | + (destination_account_key, destination_account), |
| 596 | + (authority_key, Account::default()), |
| 597 | + ], |
| 598 | + &[ |
| 599 | + Check::success(), |
| 600 | + Check::account(&destination_account_key) |
| 601 | + .lamports( |
| 602 | + Rent::default().minimum_balance(size_of::<TokenAccount>()) + 2_000_000_000, |
| 603 | + ) |
| 604 | + .build(), |
| 605 | + Check::account(&source_account_key) |
| 606 | + .lamports(Rent::default().minimum_balance(size_of::<TokenAccount>())) |
| 607 | + .build(), |
| 608 | + ], |
| 609 | + ); |
| 610 | + |
| 611 | + // And the remaining amount on the source account must be 0. |
| 612 | + |
| 613 | + let account = result.get_account(&source_account_key); |
| 614 | + assert!(account.is_some()); |
| 615 | + |
| 616 | + let account = account.unwrap(); |
| 617 | + let token_account = spl_token::state::Account::unpack(&account.data).unwrap(); |
| 618 | + assert_eq!(token_account.amount, 0); |
| 619 | + |
| 620 | + // And the amount on the destination account must be 0 since we transferred |
| 621 | + // lamports directly to the account. |
| 622 | + |
| 623 | + let account = result.get_account(&destination_account_key); |
| 624 | + assert!(account.is_some()); |
| 625 | + |
| 626 | + let account = account.unwrap(); |
| 627 | + let token_account = spl_token::state::Account::unpack(&account.data).unwrap(); |
| 628 | + assert_eq!(token_account.amount, 0); |
| 629 | +} |
0 commit comments