Browse Source

backport #434 to v2

Jack May 5 years ago
parent
commit
61670b05f4
1 changed files with 219 additions and 6 deletions
  1. 219 6
      program/src/processor.rs

+ 219 - 6
program/src/processor.rs

@@ -257,8 +257,8 @@ impl Processor {
         let delegate_info = next_account_info(account_info_iter)?;
         let owner_info = next_account_info(account_info_iter)?;
 
-        let mut source_data = source_account_info.data.borrow_mut();
-        Account::unpack_mut(&mut source_data, &mut |source_account: &mut Account| {
+        let mut source_account = Account::unpack(&source_account_info.data.borrow())?;
+
             if source_account.is_frozen() {
                 return Err(TokenError::AccountFrozen.into());
             }
@@ -284,8 +284,9 @@ impl Processor {
             source_account.delegate = COption::Some(*delegate_info.key);
             source_account.delegated_amount = amount;
 
+        Account::pack(source_account, &mut source_account_info.data.borrow_mut())?;
+
             Ok(())
-        })
     }
 
     /// Processes an [Revoke](enum.TokenInstruction.html) instruction.
@@ -293,8 +294,8 @@ impl Processor {
         let account_info_iter = &mut accounts.iter();
         let source_account_info = next_account_info(account_info_iter)?;
 
-        let mut source_data = source_account_info.data.borrow_mut();
-        Account::unpack_mut(&mut source_data, &mut |source_account: &mut Account| {
+        let mut source_account = Account::unpack(&source_account_info.data.borrow())?;
+
             let owner_info = next_account_info(account_info_iter)?;
 
             if source_account.is_frozen() {
@@ -311,8 +312,9 @@ impl Processor {
             source_account.delegate = COption::None;
             source_account.delegated_amount = 0;
 
+        Account::pack(source_account, &mut source_account_info.data.borrow_mut())?;
+
             Ok(())
-        })
     }
 
     /// Processes a [SetAuthority](enum.TokenInstruction.html) instruction.
@@ -1976,6 +1978,217 @@ mod tests {
         .unwrap();
     }
 
+    #[test]
+    fn test_approve_dups() {
+        let program_id = pubkey_rand();
+        let account1_key = pubkey_rand();
+        let mut account1_account = SolanaAccount::new(
+            account_minimum_balance(),
+            Account::get_packed_len(),
+            &program_id,
+        );
+        let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
+        let account2_key = pubkey_rand();
+        let mut account2_account = SolanaAccount::new(
+            account_minimum_balance(),
+            Account::get_packed_len(),
+            &program_id,
+        );
+        let account2_info: AccountInfo = (&account2_key, false, &mut account2_account).into();
+        let account3_key = pubkey_rand();
+        let mut account3_account = SolanaAccount::new(
+            account_minimum_balance(),
+            Account::get_packed_len(),
+            &program_id,
+        );
+        let account3_info: AccountInfo = (&account3_key, true, &mut account3_account).into();
+        let multisig_key = pubkey_rand();
+        let mut multisig_account = SolanaAccount::new(
+            multisig_minimum_balance(),
+            Multisig::get_packed_len(),
+            &program_id,
+        );
+        let multisig_info: AccountInfo = (&multisig_key, true, &mut multisig_account).into();
+        let owner_key = pubkey_rand();
+        let mut owner_account = SolanaAccount::default();
+        let owner_info: AccountInfo = (&owner_key, true, &mut owner_account).into();
+        let mint_key = pubkey_rand();
+        let mut mint_account =
+            SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
+        let mint_info: AccountInfo = (&mint_key, false, &mut mint_account).into();
+        let rent_key = rent::id();
+        let mut rent_sysvar = rent_sysvar();
+        let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
+
+        // create mint
+        do_process_instruction_dups(
+            initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
+            vec![mint_info.clone(), rent_info.clone()],
+        )
+        .unwrap();
+
+        // create account
+        do_process_instruction_dups(
+            initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
+            vec![
+                account1_info.clone(),
+                mint_info.clone(),
+                account1_info.clone(),
+                rent_info.clone(),
+            ],
+        )
+        .unwrap();
+
+        // create another account
+        do_process_instruction_dups(
+            initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
+            vec![
+                account2_info.clone(),
+                mint_info.clone(),
+                owner_info.clone(),
+                rent_info.clone(),
+            ],
+        )
+        .unwrap();
+
+        // mint to account
+        do_process_instruction_dups(
+            mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
+            vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
+        )
+        .unwrap();
+
+        // source-owner approve
+        do_process_instruction_dups(
+            approve(
+                &program_id,
+                &account1_key,
+                &account2_key,
+                &account1_key,
+                &[],
+                500,
+            )
+            .unwrap(),
+            vec![
+                account1_info.clone(),
+                account2_info.clone(),
+                account1_info.clone(),
+            ],
+        )
+        .unwrap();
+
+        // source-owner approve2
+        do_process_instruction_dups(
+            approve2(
+                &program_id,
+                &account1_key,
+                &mint_key,
+                &account2_key,
+                &account1_key,
+                &[],
+                500,
+                2,
+            )
+            .unwrap(),
+            vec![
+                account1_info.clone(),
+                mint_info.clone(),
+                account2_info.clone(),
+                account1_info.clone(),
+            ],
+        )
+        .unwrap();
+
+        // source-owner revoke
+        do_process_instruction_dups(
+            revoke(&program_id, &account1_key, &account1_key, &[]).unwrap(),
+            vec![account1_info.clone(), account1_info.clone()],
+        )
+        .unwrap();
+
+        // test source-multisig signer
+        do_process_instruction_dups(
+            initialize_multisig(&program_id, &multisig_key, &[&account3_key], 1).unwrap(),
+            vec![
+                multisig_info.clone(),
+                rent_info.clone(),
+                account3_info.clone(),
+            ],
+        )
+        .unwrap();
+
+        do_process_instruction_dups(
+            initialize_account(&program_id, &account3_key, &mint_key, &multisig_key).unwrap(),
+            vec![
+                account3_info.clone(),
+                mint_info.clone(),
+                multisig_info.clone(),
+                rent_info.clone(),
+            ],
+        )
+        .unwrap();
+
+        do_process_instruction_dups(
+            mint_to(&program_id, &mint_key, &account3_key, &owner_key, &[], 1000).unwrap(),
+            vec![mint_info.clone(), account3_info.clone(), owner_info.clone()],
+        )
+        .unwrap();
+
+        // source-multisig-signer approve
+        do_process_instruction_dups(
+            approve(
+                &program_id,
+                &account3_key,
+                &account2_key,
+                &multisig_key,
+                &[&account3_key],
+                500,
+            )
+            .unwrap(),
+            vec![
+                account3_info.clone(),
+                account2_info.clone(),
+                multisig_info.clone(),
+                account3_info.clone(),
+            ],
+        )
+        .unwrap();
+
+        // source-multisig-signer approve2
+        do_process_instruction_dups(
+            approve2(
+                &program_id,
+                &account3_key,
+                &mint_key,
+                &account2_key,
+                &multisig_key,
+                &[&account3_key],
+                500,
+                2,
+            )
+            .unwrap(),
+            vec![
+                account3_info.clone(),
+                mint_info.clone(),
+                account2_info.clone(),
+                multisig_info.clone(),
+                account3_info.clone(),
+            ],
+        )
+        .unwrap();
+
+        // source-owner multisig-signer
+        do_process_instruction_dups(
+            revoke(&program_id, &account3_key, &multisig_key, &[&account3_key]).unwrap(),
+            vec![
+                account3_info.clone(),
+                multisig_info.clone(),
+                account3_info.clone(),
+            ],
+        )
+        .unwrap();
+    }
+
     #[test]
     fn test_approve() {
         let program_id = pubkey_rand();