diff --git a/Cargo.lock b/Cargo.lock index f02f69ce05..29bd7bfeff 100644 --- a/Cargo.lock +++ b/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", ] diff --git a/account-decoder/Cargo.toml b/account-decoder/Cargo.toml index d90f3e8870..2b5097cd4a 100644 --- a/account-decoder/Cargo.toml +++ b/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" diff --git a/accounts-cluster-bench/Cargo.toml b/accounts-cluster-bench/Cargo.toml index 6feae5490b..a307c22859 100644 --- a/accounts-cluster-bench/Cargo.toml +++ b/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" } diff --git a/ci/do-audit.sh b/ci/do-audit.sh index ea21a36eb3..395218e27d 100755 --- a/ci/do-audit.sh +++ b/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 diff --git a/fetch-spl.sh b/fetch-spl.sh index cf0f2b4123..542da6af3f 100755 --- a/fetch-spl.sh +++ b/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 diff --git a/program-test/src/programs.rs b/program-test/src/programs.rs index bb5912328c..f2cfd0e05f 100644 --- a/program-test/src/programs.rs +++ b/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"), ), ]; diff --git a/program-test/src/programs/spl_associated-token-account-1.0.3.so b/program-test/src/programs/spl_associated-token-account-1.0.3.so deleted file mode 100644 index 9b29778691..0000000000 Binary files a/program-test/src/programs/spl_associated-token-account-1.0.3.so and /dev/null differ diff --git a/program-test/src/programs/spl_associated_token_account-1.0.5.so b/program-test/src/programs/spl_associated_token_account-1.0.5.so new file mode 100755 index 0000000000..7b360e4cad Binary files /dev/null and b/program-test/src/programs/spl_associated_token_account-1.0.5.so differ diff --git a/program-test/src/programs/spl_token-3.2.0.so b/program-test/src/programs/spl_token-3.2.0.so deleted file mode 100644 index 9b8c9549fc..0000000000 Binary files a/program-test/src/programs/spl_token-3.2.0.so and /dev/null differ diff --git a/program-test/src/programs/spl_token-3.3.0.so b/program-test/src/programs/spl_token-3.3.0.so new file mode 100644 index 0000000000..84098a6a6a Binary files /dev/null and b/program-test/src/programs/spl_token-3.3.0.so differ diff --git a/programs/bpf/Cargo.lock b/programs/bpf/Cargo.lock index 50f816098b..09d68bb445 100644 --- a/programs/bpf/Cargo.lock +++ b/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", ] diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 4bfbb15bd2..1afc1ddfce 100644 --- a/rpc/Cargo.toml +++ b/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"] } diff --git a/tokens/Cargo.toml b/tokens/Cargo.toml index 7a04caefe3..13ea4fbed1 100644 --- a/tokens/Cargo.toml +++ b/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" diff --git a/tokens/src/spl_token.rs b/tokens/src/spl_token.rs index f1882a3d0e..9ea9d05651 100644 --- a/tokens/src/spl_token.rs +++ b/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}, diff --git a/transaction-status/Cargo.toml b/transaction-status/Cargo.toml index 479cebfe40..42c6ce806c 100644 --- a/transaction-status/Cargo.toml +++ b/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] diff --git a/transaction-status/src/parse_associated_token.rs b/transaction-status/src/parse_associated_token.rs index 15457232d2..4dcf03426f 100644 --- a/transaction-status/src/parse_associated_token.rs +++ b/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, }, }, }; @@ -83,6 +111,42 @@ mod test { .collect() } + #[test] + 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)); + #[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(); @@ -90,8 +154,6 @@ mod test { 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(); - 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(), }) } ); diff --git a/transaction-status/src/parse_token.rs b/transaction-status/src/parse_token.rs index 5891b87418..6c9ba99abc 100644 --- a/transaction-status/src/parse_token.rs +++ b/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 = vec![]; @@ -96,6 +130,21 @@ pub fn parse_token( }), }) } + TokenInstruction::InitializeMultisig2 { m } => { + check_num_token_accounts(&instruction.accounts, 2)?; + let mut signers: Vec = 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(),