Parcourir la source

spl: Bump token to v3.3.0 and ATA to v1.0.5 (#22649)

* Bump spl-token and ATA to v3.3.0

* Add parsers for new token instructions
* Update parser for modified associated-token-account instruction

* Update to use 1.0.5 once it's released

* Update Cargo.lock in programs/bpf
Jon Cinque il y a 3 ans
Parent
commit
c43afe2d7f

+ 13 - 9
Cargo.lock

@@ -5992,6 +5992,7 @@ dependencies = [
  "Inflector",
  "base64 0.13.0",
  "bincode",
+ "borsh",
  "bs58",
  "lazy_static",
  "log",
@@ -6136,9 +6137,9 @@ dependencies = [
 
 [[package]]
 name = "solana-zk-token-sdk"
-version = "0.4.0"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f79e20a90b9e8c10baa62cbb396fd9af6a1e3d7b0c1c3ce84189d08d0f273ea8"
+checksum = "74b149253f9ed1afb68b3161b53b62b637d0dd7a3b328dffdc8bb5878d48358e"
 dependencies = [
  "aes-gcm-siv",
  "arrayref",
@@ -6234,10 +6235,11 @@ dependencies = [
 
 [[package]]
 name = "spl-associated-token-account"
-version = "1.0.3"
+version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "393e2240d521c3dd770806bff25c2c00d761ac962be106e14e22dd912007f428"
+checksum = "2b013067447a1396303ddfc294f36e3d260a32f8a16c501c295bcdc7de39b490"
 dependencies = [
+ "borsh",
  "solana-program 1.10.9",
  "spl-token",
 ]
@@ -6253,9 +6255,9 @@ dependencies = [
 
 [[package]]
 name = "spl-token"
-version = "3.2.0"
+version = "3.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93bfdd5bd7c869cb565c7d7635c4fafe189b988a0bdef81063cd9585c6b8dc01"
+checksum = "0cc67166ef99d10c18cb5e9c208901e6d8255c6513bb1f877977eba48e6cc4fb"
 dependencies = [
  "arrayref",
  "num-derive",
@@ -6267,9 +6269,9 @@ dependencies = [
 
 [[package]]
 name = "spl-token-2022"
-version = "0.1.0"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94151293267493245acd17c27702bd340619c8b91bbf6bda1322a2adf42d3faf"
+checksum = "fce48c69350134e8678de5c0956a531b7de586b28eebdddc03211ceec0660983"
 dependencies = [
  "arrayref",
  "bytemuck",
@@ -6277,7 +6279,9 @@ dependencies = [
  "num-traits",
  "num_enum",
  "solana-program 1.10.9",
- "solana-zk-token-sdk 0.4.0",
+ "solana-zk-token-sdk 0.8.1",
+ "spl-memo",
+ "spl-token",
  "thiserror",
 ]
 

+ 2 - 2
account-decoder/Cargo.toml

@@ -22,8 +22,8 @@ serde_json = "1.0.79"
 solana-config-program = { path = "../programs/config", version = "=1.11.0" }
 solana-sdk = { path = "../sdk", version = "=1.11.0" }
 solana-vote-program = { path = "../programs/vote", version = "=1.11.0" }
-spl-token = { version = "=3.2.0", features = ["no-entrypoint"] }
-spl-token-2022 = { version = "=0.1.0", features = ["no-entrypoint"] }
+spl-token = { version = "=3.3.0", features = ["no-entrypoint"] }
+spl-token-2022 = { version = "=0.2.0", features = ["no-entrypoint"] }
 thiserror = "1.0"
 zstd = "0.11.1"
 

+ 1 - 1
accounts-cluster-bench/Cargo.toml

@@ -26,7 +26,7 @@ solana-sdk = { path = "../sdk", version = "=1.11.0" }
 solana-streamer = { path = "../streamer", version = "=1.11.0" }
 solana-transaction-status = { path = "../transaction-status", version = "=1.11.0" }
 solana-version = { path = "../version", version = "=1.11.0" }
-spl-token = { version = "=3.2.0", features = ["no-entrypoint"] }
+spl-token = { version = "=3.3.0", features = ["no-entrypoint"] }
 
 [dev-dependencies]
 solana-core = { path = "../core", version = "=1.11.0" }

+ 0 - 6
ci/do-audit.sh

@@ -23,12 +23,6 @@ cargo_audit_ignores=(
   # Blocked on multiple crates updating `time` to >= 0.2.23
   --ignore RUSTSEC-2020-0071
 
-  # generic-array: arr! macro erases lifetimes
-  #
-  # Blocked on new spl dependencies on solana-program v1.9
-  # due to curve25519-dalek dependency
-  --ignore RUSTSEC-2020-0146
-
   # chrono: Potential segfault in `localtime_r` invocations
   #
   # Blocked due to no safe upgrade

+ 2 - 2
fetch-spl.sh

@@ -38,10 +38,10 @@ fetch_program() {
 
 }
 
-fetch_program token 3.2.0 TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA BPFLoader2111111111111111111111111111111111
+fetch_program token 3.3.0 TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA BPFLoader2111111111111111111111111111111111
 fetch_program memo  1.0.0 Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo BPFLoader1111111111111111111111111111111111
 fetch_program memo  3.0.0 MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr BPFLoader2111111111111111111111111111111111
-fetch_program associated-token-account 1.0.3 ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL BPFLoader2111111111111111111111111111111111
+fetch_program associated-token-account 1.0.5 ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL BPFLoader2111111111111111111111111111111111
 fetch_program feature-proposal 1.0.0 Feat1YXHhH6t1juaWF74WLcfv4XoNocjXA6sPWHNgAse BPFLoader2111111111111111111111111111111111
 
 echo "${genesis_args[@]}" > spl-genesis-args.sh

+ 2 - 2
program-test/src/programs.rs

@@ -18,7 +18,7 @@ mod spl_associated_token_account {
 }
 
 static SPL_PROGRAMS: &[(Pubkey, &[u8])] = &[
-    (spl_token::ID, include_bytes!("programs/spl_token-3.2.0.so")),
+    (spl_token::ID, include_bytes!("programs/spl_token-3.3.0.so")),
     (
         spl_memo_1_0::ID,
         include_bytes!("programs/spl_memo-1.0.0.so"),
@@ -29,7 +29,7 @@ static SPL_PROGRAMS: &[(Pubkey, &[u8])] = &[
     ),
     (
         spl_associated_token_account::ID,
-        include_bytes!("programs/spl_associated-token-account-1.0.3.so"),
+        include_bytes!("programs/spl_associated_token_account-1.0.5.so"),
     ),
 ];
 

BIN
program-test/src/programs/spl_associated-token-account-1.0.3.so


BIN
program-test/src/programs/spl_associated_token_account-1.0.5.so


BIN
program-test/src/programs/spl_token-3.2.0.so


BIN
program-test/src/programs/spl_token-3.3.0.so


+ 13 - 9
programs/bpf/Cargo.lock

@@ -3845,6 +3845,7 @@ dependencies = [
  "Inflector",
  "base64 0.13.0",
  "bincode",
+ "borsh",
  "bs58",
  "lazy_static",
  "log",
@@ -3911,9 +3912,9 @@ dependencies = [
 
 [[package]]
 name = "solana-zk-token-sdk"
-version = "0.4.0"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f79e20a90b9e8c10baa62cbb396fd9af6a1e3d7b0c1c3ce84189d08d0f273ea8"
+checksum = "74b149253f9ed1afb68b3161b53b62b637d0dd7a3b328dffdc8bb5878d48358e"
 dependencies = [
  "aes-gcm-siv",
  "arrayref",
@@ -4003,10 +4004,11 @@ dependencies = [
 
 [[package]]
 name = "spl-associated-token-account"
-version = "1.0.3"
+version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "393e2240d521c3dd770806bff25c2c00d761ac962be106e14e22dd912007f428"
+checksum = "2b013067447a1396303ddfc294f36e3d260a32f8a16c501c295bcdc7de39b490"
 dependencies = [
+ "borsh",
  "solana-program 1.10.9",
  "spl-token",
 ]
@@ -4022,9 +4024,9 @@ dependencies = [
 
 [[package]]
 name = "spl-token"
-version = "3.2.0"
+version = "3.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93bfdd5bd7c869cb565c7d7635c4fafe189b988a0bdef81063cd9585c6b8dc01"
+checksum = "0cc67166ef99d10c18cb5e9c208901e6d8255c6513bb1f877977eba48e6cc4fb"
 dependencies = [
  "arrayref",
  "num-derive",
@@ -4036,9 +4038,9 @@ dependencies = [
 
 [[package]]
 name = "spl-token-2022"
-version = "0.1.0"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94151293267493245acd17c27702bd340619c8b91bbf6bda1322a2adf42d3faf"
+checksum = "fce48c69350134e8678de5c0956a531b7de586b28eebdddc03211ceec0660983"
 dependencies = [
  "arrayref",
  "bytemuck",
@@ -4046,7 +4048,9 @@ dependencies = [
  "num-traits",
  "num_enum",
  "solana-program 1.10.9",
- "solana-zk-token-sdk 0.4.0",
+ "solana-zk-token-sdk 0.8.1",
+ "spl-memo",
+ "spl-token",
  "thiserror",
 ]
 

+ 1 - 1
rpc/Cargo.toml

@@ -48,7 +48,7 @@ solana-streamer = { path = "../streamer", version = "=1.11.0" }
 solana-transaction-status = { path = "../transaction-status", version = "=1.11.0" }
 solana-version = { path = "../version", version = "=1.11.0" }
 solana-vote-program = { path = "../programs/vote", version = "=1.11.0" }
-spl-token = { version = "=3.2.0", features = ["no-entrypoint"] }
+spl-token = { version = "=3.3.0", features = ["no-entrypoint"] }
 stream-cancel = "0.8.1"
 thiserror = "1.0"
 tokio = { version = "1", features = ["full"] }

+ 2 - 2
tokens/Cargo.toml

@@ -27,8 +27,8 @@ solana-remote-wallet = { path = "../remote-wallet", version = "=1.11.0" }
 solana-sdk = { path = "../sdk", version = "=1.11.0" }
 solana-transaction-status = { path = "../transaction-status", version = "=1.11.0" }
 solana-version = { path = "../version", version = "=1.11.0" }
-spl-associated-token-account = { version = "=1.0.3" }
-spl-token = { version = "=3.2.0", features = ["no-entrypoint"] }
+spl-associated-token-account = { version = "=1.0.5" }
+spl-token = { version = "=3.3.0", features = ["no-entrypoint"] }
 tempfile = "3.3.0"
 thiserror = "1.0"
 

+ 3 - 1
tokens/src/spl_token.rs

@@ -10,7 +10,9 @@ use {
     solana_client::rpc_client::RpcClient,
     solana_sdk::{instruction::Instruction, message::Message, native_token::lamports_to_sol},
     solana_transaction_status::parse_token::spl_token_instruction,
-    spl_associated_token_account::{create_associated_token_account, get_associated_token_address},
+    spl_associated_token_account::{
+        get_associated_token_address, instruction::create_associated_token_account,
+    },
     spl_token::{
         solana_program::program_pack::Pack,
         state::{Account as SplTokenAccount, Mint},

+ 4 - 3
transaction-status/Cargo.toml

@@ -13,6 +13,7 @@ edition = "2021"
 Inflector = "0.11.4"
 base64 = "0.13.0"
 bincode = "1.3.3"
+borsh = "0.9.1"
 bs58 = "0.4.0"
 lazy_static = "1.4.0"
 log = "0.4.14"
@@ -25,10 +26,10 @@ solana-metrics = { path = "../metrics", version = "=1.11.0" }
 solana-runtime = { path = "../runtime", version = "=1.11.0" }
 solana-sdk = { path = "../sdk", version = "=1.11.0" }
 solana-vote-program = { path = "../programs/vote", version = "=1.11.0" }
-spl-associated-token-account = { version = "=1.0.3", features = ["no-entrypoint"] }
+spl-associated-token-account = { version = "=1.0.5", features = ["no-entrypoint"] }
 spl-memo = { version = "=3.0.1", features = ["no-entrypoint"] }
-spl-token = { version = "=3.2.0", features = ["no-entrypoint"] }
-spl-token-2022 = { version = "=0.1.0", features = ["no-entrypoint"] }
+spl-token = { version = "=3.3.0", features = ["no-entrypoint"] }
+spl-token-2022 = { version = "=0.2.0", features = ["no-entrypoint"] }
 thiserror = "1.0"
 
 [package.metadata.docs.rs]

+ 79 - 18
transaction-status/src/parse_associated_token.rs

@@ -2,8 +2,10 @@ use {
     crate::parse_instruction::{
         check_num_accounts, ParsableProgram, ParseInstructionError, ParsedInstructionEnum,
     },
+    borsh::BorshDeserialize,
     serde_json::json,
     solana_sdk::{instruction::CompiledInstruction, message::AccountKeys, pubkey::Pubkey},
+    spl_associated_token_account::instruction::AssociatedTokenAccountInstruction,
 };
 
 // A helper function to convert spl_associated_token_account::id() as spl_sdk::pubkey::Pubkey
@@ -25,19 +27,42 @@ pub fn parse_associated_token(
             ));
         }
     }
-    check_num_associated_token_accounts(&instruction.accounts, 7)?;
-    Ok(ParsedInstructionEnum {
-        instruction_type: "create".to_string(),
-        info: json!({
-            "source": account_keys[instruction.accounts[0] as usize].to_string(),
-            "account": account_keys[instruction.accounts[1] as usize].to_string(),
-            "wallet": account_keys[instruction.accounts[2] as usize].to_string(),
-            "mint": account_keys[instruction.accounts[3] as usize].to_string(),
-            "systemProgram": account_keys[instruction.accounts[4] as usize].to_string(),
-            "tokenProgram": account_keys[instruction.accounts[5] as usize].to_string(),
-            "rentSysvar": account_keys[instruction.accounts[6] as usize].to_string(),
-        }),
-    })
+    if instruction.data.is_empty() {
+        check_num_associated_token_accounts(&instruction.accounts, 7)?;
+        Ok(ParsedInstructionEnum {
+            instruction_type: "create".to_string(),
+            info: json!({
+                "source": account_keys[instruction.accounts[0] as usize].to_string(),
+                "account": account_keys[instruction.accounts[1] as usize].to_string(),
+                "wallet": account_keys[instruction.accounts[2] as usize].to_string(),
+                "mint": account_keys[instruction.accounts[3] as usize].to_string(),
+                "systemProgram": account_keys[instruction.accounts[4] as usize].to_string(),
+                "tokenProgram": account_keys[instruction.accounts[5] as usize].to_string(),
+                "rentSysvar": account_keys[instruction.accounts[6] as usize].to_string(),
+            }),
+        })
+    } else {
+        let ata_instruction = AssociatedTokenAccountInstruction::try_from_slice(&instruction.data)
+            .map_err(|_| {
+                ParseInstructionError::InstructionNotParsable(ParsableProgram::SplToken)
+            })?;
+        match ata_instruction {
+            AssociatedTokenAccountInstruction::Create => {
+                check_num_associated_token_accounts(&instruction.accounts, 6)?;
+                Ok(ParsedInstructionEnum {
+                    instruction_type: "create".to_string(),
+                    info: json!({
+                        "source": account_keys[instruction.accounts[0] as usize].to_string(),
+                        "account": account_keys[instruction.accounts[1] as usize].to_string(),
+                        "wallet": account_keys[instruction.accounts[2] as usize].to_string(),
+                        "mint": account_keys[instruction.accounts[3] as usize].to_string(),
+                        "systemProgram": account_keys[instruction.accounts[4] as usize].to_string(),
+                        "tokenProgram": account_keys[instruction.accounts[5] as usize].to_string(),
+                    }),
+                })
+            }
+        }
+    }
 }
 
 fn check_num_associated_token_accounts(
@@ -49,14 +74,17 @@ fn check_num_associated_token_accounts(
 
 #[cfg(test)]
 mod test {
+    #[allow(deprecated)]
+    use spl_associated_token_account::create_associated_token_account as create_associated_token_account_deprecated;
     use {
         super::*,
         solana_account_decoder::parse_token::pubkey_from_spl_token,
         spl_associated_token_account::{
-            create_associated_token_account, get_associated_token_address,
+            get_associated_token_address,
+            instruction::create_associated_token_account,
             solana_program::{
                 instruction::CompiledInstruction as SplAssociatedTokenCompiledInstruction,
-                message::Message, pubkey::Pubkey as SplAssociatedTokenPubkey,
+                message::Message, pubkey::Pubkey as SplAssociatedTokenPubkey, sysvar,
             },
         },
     };
@@ -84,14 +112,48 @@ mod test {
     }
 
     #[test]
-    fn test_parse_associated_token() {
+    fn test_parse_associated_token_deprecated() {
         let funder = Pubkey::new_unique();
         let wallet_address = Pubkey::new_unique();
         let mint = Pubkey::new_unique();
         let associated_account_address =
             get_associated_token_address(&convert_pubkey(wallet_address), &convert_pubkey(mint));
-        let rent_sysvar = solana_sdk::sysvar::rent::id();
+        #[allow(deprecated)]
+        let create_ix = create_associated_token_account_deprecated(
+            &convert_pubkey(funder),
+            &convert_pubkey(wallet_address),
+            &convert_pubkey(mint),
+        );
+        let message = Message::new(&[create_ix], None);
+        let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
+        assert_eq!(
+            parse_associated_token(
+                &compiled_instruction,
+                &AccountKeys::new(&convert_account_keys(&message), None)
+            )
+            .unwrap(),
+            ParsedInstructionEnum {
+                instruction_type: "create".to_string(),
+                info: json!({
+                    "source": funder.to_string(),
+                    "account": associated_account_address.to_string(),
+                    "wallet": wallet_address.to_string(),
+                    "mint": mint.to_string(),
+                    "systemProgram": solana_sdk::system_program::id().to_string(),
+                    "tokenProgram": spl_token::id().to_string(),
+                    "rentSysvar": sysvar::rent::id().to_string(),
+                })
+            }
+        );
+    }
 
+    #[test]
+    fn test_parse_associated_token() {
+        let funder = Pubkey::new_unique();
+        let wallet_address = Pubkey::new_unique();
+        let mint = Pubkey::new_unique();
+        let associated_account_address =
+            get_associated_token_address(&convert_pubkey(wallet_address), &convert_pubkey(mint));
         let create_ix = create_associated_token_account(
             &convert_pubkey(funder),
             &convert_pubkey(wallet_address),
@@ -114,7 +176,6 @@ mod test {
                     "mint": mint.to_string(),
                     "systemProgram": solana_sdk::system_program::id().to_string(),
                     "tokenProgram": spl_token::id().to_string(),
-                    "rentSysvar": rent_sysvar.to_string(),
                 })
             }
         );

+ 229 - 0
transaction-status/src/parse_token.rs

@@ -56,6 +56,29 @@ pub fn parse_token(
                 info: value,
             })
         }
+        TokenInstruction::InitializeMint2 {
+            decimals,
+            mint_authority,
+            freeze_authority,
+        } => {
+            check_num_token_accounts(&instruction.accounts, 1)?;
+            let mut value = json!({
+                "mint": account_keys[instruction.accounts[0] as usize].to_string(),
+                "decimals": decimals,
+                "mintAuthority": mint_authority.to_string(),
+            });
+            let map = value.as_object_mut().unwrap();
+            if let COption::Some(freeze_authority) = freeze_authority {
+                map.insert(
+                    "freezeAuthority".to_string(),
+                    json!(freeze_authority.to_string()),
+                );
+            }
+            Ok(ParsedInstructionEnum {
+                instruction_type: "initializeMint2".to_string(),
+                info: value,
+            })
+        }
         TokenInstruction::InitializeAccount => {
             check_num_token_accounts(&instruction.accounts, 4)?;
             Ok(ParsedInstructionEnum {
@@ -80,6 +103,17 @@ pub fn parse_token(
                 }),
             })
         }
+        TokenInstruction::InitializeAccount3 { owner } => {
+            check_num_token_accounts(&instruction.accounts, 2)?;
+            Ok(ParsedInstructionEnum {
+                instruction_type: "initializeAccount3".to_string(),
+                info: json!({
+                    "account": account_keys[instruction.accounts[0] as usize].to_string(),
+                    "mint": account_keys[instruction.accounts[1] as usize].to_string(),
+                    "owner": owner.to_string(),
+                }),
+            })
+        }
         TokenInstruction::InitializeMultisig { m } => {
             check_num_token_accounts(&instruction.accounts, 3)?;
             let mut signers: Vec<String> = vec![];
@@ -96,6 +130,21 @@ pub fn parse_token(
                 }),
             })
         }
+        TokenInstruction::InitializeMultisig2 { m } => {
+            check_num_token_accounts(&instruction.accounts, 2)?;
+            let mut signers: Vec<String> = vec![];
+            for i in instruction.accounts[1..].iter() {
+                signers.push(account_keys[*i as usize].to_string());
+            }
+            Ok(ParsedInstructionEnum {
+                instruction_type: "initializeMultisig2".to_string(),
+                info: json!({
+                    "multisig": account_keys[instruction.accounts[0] as usize].to_string(),
+                    "signers": signers,
+                    "m": m,
+                }),
+            })
+        }
         TokenInstruction::Transfer { amount } => {
             check_num_token_accounts(&instruction.accounts, 3)?;
             let mut value = json!({
@@ -562,6 +611,34 @@ mod test {
             }
         );
 
+        // Test InitializeMint2
+        let initialize_mint_ix = initialize_mint2(
+            &spl_token::id(), // TODO: replace with `program_id`
+            &convert_pubkey(mint_pubkey),
+            &convert_pubkey(mint_authority),
+            Some(&convert_pubkey(freeze_authority)),
+            2,
+        )
+        .unwrap();
+        let message = make_coerced_message(initialize_mint_ix, program_id);
+        let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
+        assert_eq!(
+            parse_token(
+                &compiled_instruction,
+                &AccountKeys::new(&convert_account_keys(&message), None)
+            )
+            .unwrap(),
+            ParsedInstructionEnum {
+                instruction_type: "initializeMint2".to_string(),
+                info: json!({
+                    "mint": mint_pubkey.to_string(),
+                    "decimals": 2,
+                    "mintAuthority": mint_authority.to_string(),
+                    "freezeAuthority": freeze_authority.to_string(),
+                })
+            }
+        );
+
         // Test InitializeAccount
         let account_pubkey = Pubkey::new_unique();
         let owner = Pubkey::new_unique();
@@ -591,6 +668,59 @@ mod test {
             }
         );
 
+        // Test InitializeAccount2
+        let initialize_account_ix = initialize_account2(
+            &spl_token::id(), // TODO: replace with `program_id`
+            &convert_pubkey(account_pubkey),
+            &convert_pubkey(mint_pubkey),
+            &convert_pubkey(owner),
+        )
+        .unwrap();
+        let message = make_coerced_message(initialize_account_ix, program_id);
+        let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
+        assert_eq!(
+            parse_token(
+                &compiled_instruction,
+                &AccountKeys::new(&convert_account_keys(&message), None)
+            )
+            .unwrap(),
+            ParsedInstructionEnum {
+                instruction_type: "initializeAccount2".to_string(),
+                info: json!({
+                   "account": account_pubkey.to_string(),
+                   "mint": mint_pubkey.to_string(),
+                   "owner": owner.to_string(),
+                   "rentSysvar": rent_sysvar.to_string(),
+                })
+            }
+        );
+
+        // Test InitializeAccount3
+        let initialize_account_ix = initialize_account3(
+            &spl_token::id(),
+            &convert_pubkey(account_pubkey),
+            &convert_pubkey(mint_pubkey),
+            &convert_pubkey(owner),
+        )
+        .unwrap();
+        let message = make_coerced_message(initialize_account_ix, program_id);
+        let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
+        assert_eq!(
+            parse_token(
+                &compiled_instruction,
+                &AccountKeys::new(&convert_account_keys(&message), None)
+            )
+            .unwrap(),
+            ParsedInstructionEnum {
+                instruction_type: "initializeAccount3".to_string(),
+                info: json!({
+                   "account": account_pubkey.to_string(),
+                   "mint": mint_pubkey.to_string(),
+                   "owner": owner.to_string(),
+                })
+            }
+        );
+
         // Test InitializeMultisig
         let multisig_pubkey = Pubkey::new_unique();
         let multisig_signer0 = Pubkey::new_unique();
@@ -630,6 +760,40 @@ mod test {
             }
         );
 
+        // Test InitializeMultisig2
+        let initialize_multisig_ix = initialize_multisig2(
+            &spl_token::id(),
+            &convert_pubkey(multisig_pubkey),
+            &[
+                &convert_pubkey(multisig_signer0),
+                &convert_pubkey(multisig_signer1),
+                &convert_pubkey(multisig_signer2),
+            ],
+            2,
+        )
+        .unwrap();
+        let message = make_coerced_message(initialize_multisig_ix, program_id);
+        let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
+        assert_eq!(
+            parse_token(
+                &compiled_instruction,
+                &AccountKeys::new(&convert_account_keys(&message), None)
+            )
+            .unwrap(),
+            ParsedInstructionEnum {
+                instruction_type: "initializeMultisig2".to_string(),
+                info: json!({
+                    "multisig": multisig_pubkey.to_string(),
+                    "m": 2,
+                    "signers": vec![
+                        multisig_signer0.to_string(),
+                        multisig_signer1.to_string(),
+                        multisig_signer2.to_string(),
+                    ],
+                })
+            }
+        );
+
         // Test Transfer, incl multisig
         let recipient = Pubkey::new_unique();
         let transfer_ix = transfer(
@@ -1284,6 +1448,22 @@ mod test {
             compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
         assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
 
+        // Test InitializeMint2
+        let initialize_mint_ix = initialize_mint2(
+            &spl_token::id(),
+            &convert_pubkey(keys[0]),
+            &convert_pubkey(keys[1]),
+            Some(&convert_pubkey(keys[2])),
+            2,
+        )
+        .unwrap();
+        let message = Message::new(&[initialize_mint_ix], None);
+        let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
+        assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..0], None)).is_err());
+        compiled_instruction.accounts =
+            compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
+        assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
+
         // Test InitializeAccount
         let initialize_account_ix = initialize_account(
             &spl_token::id(),
@@ -1299,6 +1479,36 @@ mod test {
             compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
         assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
 
+        // Test InitializeAccount2
+        let initialize_account_ix = initialize_account2(
+            &spl_token::id(),
+            &convert_pubkey(keys[0]),
+            &convert_pubkey(keys[1]),
+            &convert_pubkey(keys[3]),
+        )
+        .unwrap();
+        let message = Message::new(&[initialize_account_ix], None);
+        let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
+        assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..2], None)).is_err());
+        compiled_instruction.accounts =
+            compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
+        assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
+
+        // Test InitializeAccount3
+        let initialize_account_ix = initialize_account3(
+            &spl_token::id(),
+            &convert_pubkey(keys[0]),
+            &convert_pubkey(keys[1]),
+            &convert_pubkey(keys[2]),
+        )
+        .unwrap();
+        let message = Message::new(&[initialize_account_ix], None);
+        let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
+        assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..1], None)).is_err());
+        compiled_instruction.accounts =
+            compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
+        assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
+
         // Test InitializeMultisig
         let initialize_multisig_ix = initialize_multisig(
             &spl_token::id(),
@@ -1318,6 +1528,25 @@ mod test {
             compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 3].to_vec();
         assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
 
+        // Test InitializeMultisig2
+        let initialize_multisig_ix = initialize_multisig2(
+            &spl_token::id(),
+            &convert_pubkey(keys[0]),
+            &[
+                &convert_pubkey(keys[1]),
+                &convert_pubkey(keys[2]),
+                &convert_pubkey(keys[3]),
+            ],
+            2,
+        )
+        .unwrap();
+        let message = Message::new(&[initialize_multisig_ix], None);
+        let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
+        assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..3], None)).is_err());
+        compiled_instruction.accounts =
+            compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 3].to_vec();
+        assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
+
         // Test Transfer, incl multisig
         let transfer_ix = transfer(
             &spl_token::id(),