From dbd3b6b53ab95a7f26613711ee7e3f57447c6474 Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Mon, 25 Jul 2022 14:39:13 -0700 Subject: [PATCH] Parse more token-2022 extensions and instructions (#26746) * Bump spl-token-2022 * Support parsing InterestBearingConfig extension * Parse InitializeNonTransferableMint instructions * Parse InterestBearingMint instructions * Bump solana-program rebuild threshold --- Cargo.lock | 96 ++++++++++--------- account-decoder/Cargo.toml | 2 +- account-decoder/src/parse_token.rs | 10 +- account-decoder/src/parse_token_extension.rs | 38 ++++++++ ci/test-stable.sh | 2 +- client/Cargo.toml | 2 +- programs/bpf/Cargo.lock | 96 ++++++++++--------- rpc/Cargo.toml | 2 +- rpc/src/rpc.rs | 22 +++-- transaction-status/Cargo.toml | 2 +- transaction-status/src/parse_token.rs | 34 ++++++- .../extension/interest_bearing_mint.rs | 64 +++++++++++++ .../src/parse_token/extension/mod.rs | 1 + transaction-status/src/token_balances.rs | 16 +++- 14 files changed, 277 insertions(+), 110 deletions(-) create mode 100644 transaction-status/src/parse_token/extension/interest_bearing_mint.rs diff --git a/Cargo.lock b/Cargo.lock index a0176ca98..99ebd9b25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3110,15 +3110,6 @@ dependencies = [ "crypto-mac", ] -[[package]] -name = "pbkdf2" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271779f35b581956db91a3e55737327a03aa051e90b1c47aeb189508533adfd7" -dependencies = [ - "digest 0.10.3", -] - [[package]] name = "pbkdf2" version = "0.11.0" @@ -5194,23 +5185,35 @@ dependencies = [ [[package]] name = "solana-frozen-abi" -version = "1.10.17" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be6cabe7c4a9daa4f66c841f95334a9e9bebabc92cab81726702e9ef10fa7341" +checksum = "d6d2bcb469e59d941e9d45702c91af940f6a8f4a5947f51bafe72844ed9b71a4" dependencies = [ + "ahash", + "blake3", + "block-buffer 0.9.0", "bs58", "bv", + "byteorder", + "cc", + "either", "generic-array 0.14.5", + "getrandom 0.1.16", + "hashbrown 0.11.2", "im", "lazy_static", "log", "memmap2", + "once_cell", + "rand_core 0.6.3", "rustc_version 0.4.0", "serde", "serde_bytes", "serde_derive", + "serde_json", "sha2 0.10.2", - "solana-frozen-abi-macro 1.10.17", + "solana-frozen-abi-macro 1.11.3", + "subtle", "thiserror", ] @@ -5249,9 +5252,9 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "1.10.17" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b583fcfb0336680016aa2c8a04078eba53d290fba56c00df483f97df967b8b6" +checksum = "4f1f8cd2f387d17ccfb2bd5dd097d9b3c1fa14acfa49e95a63ece15a4622b8d0" dependencies = [ "proc-macro2 1.0.38", "quote 1.0.18", @@ -5564,9 +5567,9 @@ dependencies = [ [[package]] name = "solana-logger" -version = "1.10.17" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4508b5a41ca5a5d6a0d95496412188484492301c75024c0f5b289f1253e0eab" +checksum = "3faca9d9fe587dc5827e06acdcca072e5b744bef0488b98fb21b77932e642afb" dependencies = [ "env_logger", "lazy_static", @@ -5735,9 +5738,9 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.10.17" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1de171aad74cc5dc8b17b72bffe07c1daf27c18a7614ccfb7cbea8fbc64f562b" +checksum = "b57df37154125f5e4ba0eaa0e5ea3cbc747a950480ddd89395036c4d3b77b66b" dependencies = [ "base64 0.13.0", "bincode", @@ -5748,31 +5751,38 @@ dependencies = [ "bs58", "bv", "bytemuck", + "cc", "console_error_panic_hook", "console_log", "curve25519-dalek", - "getrandom 0.1.16", + "getrandom 0.2.3", "itertools", "js-sys", "lazy_static", + "libc", "libsecp256k1", "log", + "memoffset", "num-derive", "num-traits", "parking_lot 0.12.1", "rand 0.7.3", + "rand_chacha 0.2.2", "rustc_version 0.4.0", "rustversion", "serde", "serde_bytes", "serde_derive", + "serde_json", "sha2 0.10.2", "sha3 0.10.1", - "solana-frozen-abi 1.10.17", - "solana-frozen-abi-macro 1.10.17", - "solana-sdk-macro 1.10.17", + "solana-frozen-abi 1.11.3", + "solana-frozen-abi-macro 1.11.3", + "solana-sdk-macro 1.11.3", "thiserror", + "tiny-bip39", "wasm-bindgen", + "zeroize", ] [[package]] @@ -6043,9 +6053,9 @@ dependencies = [ [[package]] name = "solana-sdk" -version = "1.10.17" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6002fadb15a463895f809e3f11f78c416c0b54a7e89ff951a8731afeeadd93ae" +checksum = "09d17897e0ca6c36cf90dc4d58a8f6bb2e3af80afc74b1825e779ee087af5c4a" dependencies = [ "assert_matches", "base64 0.13.0", @@ -6070,7 +6080,7 @@ dependencies = [ "memmap2", "num-derive", "num-traits", - "pbkdf2 0.10.1", + "pbkdf2 0.11.0", "qstring", "rand 0.7.3", "rand_chacha 0.2.2", @@ -6082,11 +6092,11 @@ dependencies = [ "serde_json", "sha2 0.10.2", "sha3 0.10.1", - "solana-frozen-abi 1.10.17", - "solana-frozen-abi-macro 1.10.17", - "solana-logger 1.10.17", - "solana-program 1.10.17", - "solana-sdk-macro 1.10.17", + "solana-frozen-abi 1.11.3", + "solana-frozen-abi-macro 1.11.3", + "solana-logger 1.11.3", + "solana-program 1.11.3", + "solana-sdk-macro 1.11.3", "thiserror", "uriparse", "wasm-bindgen", @@ -6147,9 +6157,9 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.10.17" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dde2f2b735059d320dd316cf85dc6a765d7300f68ea2d596872a46412ef1e16" +checksum = "148d14ba16fed65d2426cd33fbe0661c4c8543721bfb5472f486a509cf01f8c2" dependencies = [ "bs58", "proc-macro2 1.0.38", @@ -6557,9 +6567,9 @@ dependencies = [ [[package]] name = "solana-zk-token-sdk" -version = "1.10.17" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ce018de0c31cc60953512b915b349333233763c65d6abec2bc517c16988ac19" +checksum = "03ca28bafde8d752654a1efbe0911cffc0f2f1518d3eefe094db94cbda8fc965" dependencies = [ "aes-gcm-siv", "arrayref", @@ -6578,8 +6588,8 @@ dependencies = [ "serde", "serde_json", "sha3 0.9.1", - "solana-program 1.10.17", - "solana-sdk 1.10.17", + "solana-program 1.11.3", + "solana-sdk 1.11.3", "subtle", "thiserror", "zeroize", @@ -6660,7 +6670,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b013067447a1396303ddfc294f36e3d260a32f8a16c501c295bcdc7de39b490" dependencies = [ "borsh", - "solana-program 1.10.17", + "solana-program 1.11.3", "spl-token", ] @@ -6670,7 +6680,7 @@ version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0dc6f70db6bacea7ff25870b016a65ba1d1b6013536f08e4fd79a8f9005325" dependencies = [ - "solana-program 1.10.17", + "solana-program 1.11.3", ] [[package]] @@ -6683,23 +6693,23 @@ dependencies = [ "num-derive", "num-traits", "num_enum", - "solana-program 1.10.17", + "solana-program 1.11.3", "thiserror", ] [[package]] name = "spl-token-2022" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83f001b3579e69a695a22e458fa1a4b76ab25a142544a094e3f65af63dc61c2f" +checksum = "e684f055853cf11bdc9cd3301da1a3238bc95d25c9e563fd67533c2314900eab" dependencies = [ "arrayref", "bytemuck", "num-derive", "num-traits", "num_enum", - "solana-program 1.10.17", - "solana-zk-token-sdk 1.10.17", + "solana-program 1.11.3", + "solana-zk-token-sdk 1.11.3", "spl-memo", "spl-token", "thiserror", diff --git a/account-decoder/Cargo.toml b/account-decoder/Cargo.toml index bf44f420d..076a9664c 100644 --- a/account-decoder/Cargo.toml +++ b/account-decoder/Cargo.toml @@ -23,7 +23,7 @@ solana-config-program = { path = "../programs/config", version = "=1.11.5" } solana-sdk = { path = "../sdk", version = "=1.11.5" } solana-vote-program = { path = "../programs/vote", version = "=1.11.5" } spl-token = { version = "=3.3.0", features = ["no-entrypoint"] } -spl-token-2022 = { version = "=0.3.0", features = ["no-entrypoint"] } +spl-token-2022 = { version = "=0.4.1", features = ["no-entrypoint"] } thiserror = "1.0" zstd = "0.11.2" diff --git a/account-decoder/src/parse_token.rs b/account-decoder/src/parse_token.rs index 4a94f00aa..ab5eb7f95 100644 --- a/account-decoder/src/parse_token.rs +++ b/account-decoder/src/parse_token.rs @@ -552,8 +552,10 @@ mod test { account_state.pack_base(); account_state.init_account_type().unwrap(); - account_state.init_extension::().unwrap(); - let mut memo_transfer = account_state.init_extension::().unwrap(); + account_state + .init_extension::(true) + .unwrap(); + let mut memo_transfer = account_state.init_extension::(true).unwrap(); memo_transfer.require_incoming_transfer_memos = true.into(); assert!(parse_token(&account_data, None).is_err()); @@ -620,7 +622,9 @@ mod test { let mut mint_state = StateWithExtensionsMut::::unpack_uninitialized(&mut mint_data).unwrap(); - let mut mint_close_authority = mint_state.init_extension::().unwrap(); + let mut mint_close_authority = mint_state + .init_extension::(true) + .unwrap(); mint_close_authority.close_authority = OptionalNonZeroPubkey::try_from(Some(owner_pubkey)).unwrap(); diff --git a/account-decoder/src/parse_token_extension.rs b/account-decoder/src/parse_token_extension.rs index 092e91514..c9e60fb20 100644 --- a/account-decoder/src/parse_token_extension.rs +++ b/account-decoder/src/parse_token_extension.rs @@ -1,5 +1,6 @@ use { crate::parse_token::UiAccountState, + solana_sdk::clock::UnixTimestamp, spl_token_2022::{ extension::{self, BaseState, ExtensionType, StateWithExtensions}, solana_program::pubkey::Pubkey, @@ -18,6 +19,8 @@ pub enum UiExtension { DefaultAccountState(UiDefaultAccountState), ImmutableOwner, MemoTransfer(UiMemoTransfer), + NonTransferable, + InterestBearingConfig(UiInterestBearingConfig), UnparseableExtension, } @@ -50,6 +53,11 @@ pub fn parse_extension( .get_extension::() .map(|&extension| UiExtension::MemoTransfer(extension.into())) .unwrap_or(UiExtension::UnparseableExtension), + ExtensionType::NonTransferable => UiExtension::NonTransferable, + ExtensionType::InterestBearingConfig => account + .get_extension::() + .map(|&extension| UiExtension::InterestBearingConfig(extension.into())) + .unwrap_or(UiExtension::UnparseableExtension), } } @@ -159,3 +167,33 @@ impl From for UiMemoTransfer { } } } + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct UiInterestBearingConfig { + pub rate_authority: Option, + pub initialization_timestamp: UnixTimestamp, + pub pre_update_average_rate: i16, + pub last_update_timestamp: UnixTimestamp, + pub current_rate: i16, +} + +impl From for UiInterestBearingConfig { + fn from( + interest_bearing_config: extension::interest_bearing_mint::InterestBearingConfig, + ) -> Self { + let rate_authority: Option = interest_bearing_config.rate_authority.into(); + + Self { + rate_authority: rate_authority.map(|pubkey| pubkey.to_string()), + initialization_timestamp: UnixTimestamp::from( + interest_bearing_config.initialization_timestamp, + ), + pre_update_average_rate: i16::from(interest_bearing_config.pre_update_average_rate), + last_update_timestamp: UnixTimestamp::from( + interest_bearing_config.last_update_timestamp, + ), + current_rate: i16::from(interest_bearing_config.current_rate), + } + } +} diff --git a/ci/test-stable.sh b/ci/test-stable.sh index 4becb32c3..5372183da 100755 --- a/ci/test-stable.sh +++ b/ci/test-stable.sh @@ -81,7 +81,7 @@ test-stable-bpf) # latest mainbeta release version. solana_program_count=$(grep -c 'solana-program v' cargo.log) rm -f cargo.log - if ((solana_program_count > 4)); then + if ((solana_program_count > 10)); then echo "Regression of build redundancy ${solana_program_count}." echo "Review dependency features that trigger redundant rebuilds of solana-program." exit 1 diff --git a/client/Cargo.toml b/client/Cargo.toml index 570b3f65b..ce1da6dd1 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -49,7 +49,7 @@ solana-streamer = { path = "../streamer", version = "=1.11.5" } solana-transaction-status = { path = "../transaction-status", version = "=1.11.5" } solana-version = { path = "../version", version = "=1.11.5" } solana-vote-program = { path = "../programs/vote", version = "=1.11.5" } -spl-token-2022 = { version = "=0.3.0", features = ["no-entrypoint"] } +spl-token-2022 = { version = "=0.4.1", features = ["no-entrypoint"] } thiserror = "1.0" tokio = { version = "~1.14.1", features = ["full"] } tokio-stream = "0.1.9" diff --git a/programs/bpf/Cargo.lock b/programs/bpf/Cargo.lock index fea7fb8b6..7cc8e0176 100644 --- a/programs/bpf/Cargo.lock +++ b/programs/bpf/Cargo.lock @@ -2838,15 +2838,6 @@ dependencies = [ "crypto-mac", ] -[[package]] -name = "pbkdf2" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271779f35b581956db91a3e55737327a03aa051e90b1c47aeb189508533adfd7" -dependencies = [ - "digest 0.10.3", -] - [[package]] name = "pbkdf2" version = "0.11.0" @@ -4762,23 +4753,35 @@ dependencies = [ [[package]] name = "solana-frozen-abi" -version = "1.10.10" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7299c2ca50bd2d8a5b4a8043e4817892b5e700345234a31adc5b4c1208a32283" +checksum = "d6d2bcb469e59d941e9d45702c91af940f6a8f4a5947f51bafe72844ed9b71a4" dependencies = [ + "ahash", + "blake3", + "block-buffer 0.9.0", "bs58", "bv", + "byteorder 1.4.3", + "cc", + "either", "generic-array 0.14.5", + "getrandom 0.1.14", + "hashbrown 0.11.2", "im", "lazy_static", "log", "memmap2", + "once_cell", + "rand_core 0.6.3", "rustc_version", "serde", "serde_bytes", "serde_derive", + "serde_json", "sha2 0.10.2", - "solana-frozen-abi-macro 1.10.10", + "solana-frozen-abi-macro 1.11.3", + "subtle", "thiserror", ] @@ -4816,9 +4819,9 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "1.10.10" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726d2fbe5b1b21cb8a81b8c3c1d1aca32bfcfd795f92536d8ff3e66e2e51df8" +checksum = "4f1f8cd2f387d17ccfb2bd5dd097d9b3c1fa14acfa49e95a63ece15a4622b8d0" dependencies = [ "proc-macro2 1.0.38", "quote 1.0.18", @@ -4974,9 +4977,9 @@ dependencies = [ [[package]] name = "solana-logger" -version = "1.10.10" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6aeaa4145cc77bbfab151a233b14e611a82747fd2eee611a52e07f582544d6" +checksum = "3faca9d9fe587dc5827e06acdcca072e5b744bef0488b98fb21b77932e642afb" dependencies = [ "env_logger", "lazy_static", @@ -5085,9 +5088,9 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.10.10" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6425f7248eb69806ae5e8c193a5b7dcfc764516d2f0d354cdf80bacaf422a188" +checksum = "b57df37154125f5e4ba0eaa0e5ea3cbc747a950480ddd89395036c4d3b77b66b" dependencies = [ "base64 0.13.0", "bincode", @@ -5098,31 +5101,38 @@ dependencies = [ "bs58", "bv", "bytemuck", + "cc", "console_error_panic_hook", "console_log", "curve25519-dalek", - "getrandom 0.1.14", + "getrandom 0.2.4", "itertools", "js-sys", "lazy_static", + "libc", "libsecp256k1", "log", + "memoffset", "num-derive", "num-traits", "parking_lot 0.12.1", "rand 0.7.3", + "rand_chacha 0.2.2", "rustc_version", "rustversion", "serde", "serde_bytes", "serde_derive", + "serde_json", "sha2 0.10.2", "sha3 0.10.1", - "solana-frozen-abi 1.10.10", - "solana-frozen-abi-macro 1.10.10", - "solana-sdk-macro 1.10.10", + "solana-frozen-abi 1.11.3", + "solana-frozen-abi-macro 1.11.3", + "solana-sdk-macro 1.11.3", "thiserror", + "tiny-bip39", "wasm-bindgen", + "zeroize", ] [[package]] @@ -5355,9 +5365,9 @@ dependencies = [ [[package]] name = "solana-sdk" -version = "1.10.10" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5ad83e1a502a53512e0e077fbaa76bf73b19e8789dc014c940077506e8fb7ac" +checksum = "09d17897e0ca6c36cf90dc4d58a8f6bb2e3af80afc74b1825e779ee087af5c4a" dependencies = [ "assert_matches", "base64 0.13.0", @@ -5382,7 +5392,7 @@ dependencies = [ "memmap2", "num-derive", "num-traits", - "pbkdf2 0.10.1", + "pbkdf2 0.11.0", "qstring", "rand 0.7.3", "rand_chacha 0.2.2", @@ -5394,11 +5404,11 @@ dependencies = [ "serde_json", "sha2 0.10.2", "sha3 0.10.1", - "solana-frozen-abi 1.10.10", - "solana-frozen-abi-macro 1.10.10", - "solana-logger 1.10.10", - "solana-program 1.10.10", - "solana-sdk-macro 1.10.10", + "solana-frozen-abi 1.11.3", + "solana-frozen-abi-macro 1.11.3", + "solana-logger 1.11.3", + "solana-program 1.11.3", + "solana-sdk-macro 1.11.3", "thiserror", "uriparse", "wasm-bindgen", @@ -5455,9 +5465,9 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.10.10" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0e117d4d001f4f3c1e568979da52d76a75d814344c1debf9febd10b5a571993" +checksum = "148d14ba16fed65d2426cd33fbe0661c4c8543721bfb5472f486a509cf01f8c2" dependencies = [ "bs58", "proc-macro2 1.0.38", @@ -5749,9 +5759,9 @@ dependencies = [ [[package]] name = "solana-zk-token-sdk" -version = "1.10.10" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b48cc8372b23949286546f1b73c3859e06b1d42b8d2c13162484d6ca4b35cb2" +checksum = "03ca28bafde8d752654a1efbe0911cffc0f2f1518d3eefe094db94cbda8fc965" dependencies = [ "aes-gcm-siv", "arrayref", @@ -5770,8 +5780,8 @@ dependencies = [ "serde", "serde_json", "sha3 0.9.1", - "solana-program 1.10.10", - "solana-sdk 1.10.10", + "solana-program 1.11.3", + "solana-sdk 1.11.3", "subtle", "thiserror", "zeroize", @@ -5852,7 +5862,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b013067447a1396303ddfc294f36e3d260a32f8a16c501c295bcdc7de39b490" dependencies = [ "borsh", - "solana-program 1.10.10", + "solana-program 1.11.3", "spl-token", ] @@ -5862,7 +5872,7 @@ version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0dc6f70db6bacea7ff25870b016a65ba1d1b6013536f08e4fd79a8f9005325" dependencies = [ - "solana-program 1.10.10", + "solana-program 1.11.3", ] [[package]] @@ -5875,23 +5885,23 @@ dependencies = [ "num-derive", "num-traits", "num_enum", - "solana-program 1.10.10", + "solana-program 1.11.3", "thiserror", ] [[package]] name = "spl-token-2022" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83f001b3579e69a695a22e458fa1a4b76ab25a142544a094e3f65af63dc61c2f" +checksum = "e684f055853cf11bdc9cd3301da1a3238bc95d25c9e563fd67533c2314900eab" dependencies = [ "arrayref", "bytemuck", "num-derive", "num-traits", "num_enum", - "solana-program 1.10.10", - "solana-zk-token-sdk 1.10.10", + "solana-program 1.11.3", + "solana-zk-token-sdk 1.11.3", "spl-memo", "spl-token", "thiserror", diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 292717b52..05a46ca1f 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -50,7 +50,7 @@ solana-transaction-status = { path = "../transaction-status", version = "=1.11.5 solana-version = { path = "../version", version = "=1.11.5" } solana-vote-program = { path = "../programs/vote", version = "=1.11.5" } spl-token = { version = "=3.3.0", features = ["no-entrypoint"] } -spl-token-2022 = { version = "=0.3.0", features = ["no-entrypoint"] } +spl-token-2022 = { version = "=0.4.1", features = ["no-entrypoint"] } stream-cancel = "0.8.1" thiserror = "1.0" tokio = { version = "~1.14.1", features = ["full"] } diff --git a/rpc/src/rpc.rs b/rpc/src/rpc.rs index f36f47123..7c4a34ded 100644 --- a/rpc/src/rpc.rs +++ b/rpc/src/rpc.rs @@ -7303,8 +7303,10 @@ pub mod tests { account_state.base = account_base; account_state.pack_base(); account_state.init_account_type().unwrap(); - account_state.init_extension::().unwrap(); - let mut memo_transfer = account_state.init_extension::().unwrap(); + account_state + .init_extension::(true) + .unwrap(); + let mut memo_transfer = account_state.init_extension::(true).unwrap(); memo_transfer.require_incoming_transfer_memos = true.into(); let token_account = AccountSharedData::from(Account { @@ -7332,8 +7334,9 @@ pub mod tests { mint_state.base = mint_base; mint_state.pack_base(); mint_state.init_account_type().unwrap(); - let mut mint_close_authority = - mint_state.init_extension::().unwrap(); + let mut mint_close_authority = mint_state + .init_extension::(true) + .unwrap(); mint_close_authority.close_authority = OptionalNonZeroPubkey::try_from(Some(owner)).unwrap(); @@ -7801,8 +7804,10 @@ pub mod tests { account_state.base = account_base; account_state.pack_base(); account_state.init_account_type().unwrap(); - account_state.init_extension::().unwrap(); - let mut memo_transfer = account_state.init_extension::().unwrap(); + account_state + .init_extension::(true) + .unwrap(); + let mut memo_transfer = account_state.init_extension::(true).unwrap(); memo_transfer.require_incoming_transfer_memos = true.into(); let token_account = AccountSharedData::from(Account { @@ -7829,8 +7834,9 @@ pub mod tests { mint_state.base = mint_base; mint_state.pack_base(); mint_state.init_account_type().unwrap(); - let mut mint_close_authority = - mint_state.init_extension::().unwrap(); + let mut mint_close_authority = mint_state + .init_extension::(true) + .unwrap(); mint_close_authority.close_authority = OptionalNonZeroPubkey::try_from(Some(owner)).unwrap(); diff --git a/transaction-status/Cargo.toml b/transaction-status/Cargo.toml index 7052f6ade..c9e5a724b 100644 --- a/transaction-status/Cargo.toml +++ b/transaction-status/Cargo.toml @@ -29,7 +29,7 @@ solana-vote-program = { path = "../programs/vote", version = "=1.11.5" } spl-associated-token-account = { version = "=1.0.5", features = ["no-entrypoint"] } spl-memo = { version = "=3.0.1", features = ["no-entrypoint"] } spl-token = { version = "=3.3.0", features = ["no-entrypoint"] } -spl-token-2022 = { version = "=0.3.0", features = ["no-entrypoint"] } +spl-token-2022 = { version = "=0.4.1", features = ["no-entrypoint"] } thiserror = "1.0" [package.metadata.docs.rs] diff --git a/transaction-status/src/parse_token.rs b/transaction-status/src/parse_token.rs index 4640c984f..3c43cfbf4 100644 --- a/transaction-status/src/parse_token.rs +++ b/transaction-status/src/parse_token.rs @@ -3,8 +3,8 @@ use { check_num_accounts, ParsableProgram, ParseInstructionError, ParsedInstructionEnum, }, extension::{ - default_account_state::*, memo_transfer::*, mint_close_authority::*, reallocate::*, - transfer_fee::*, + default_account_state::*, interest_bearing_mint::*, memo_transfer::*, + mint_close_authority::*, reallocate::*, transfer_fee::*, }, serde_json::{json, Map, Value}, solana_account_decoder::parse_token::{ @@ -227,7 +227,8 @@ pub fn parse_token( | AuthorityType::FreezeAccount | AuthorityType::TransferFeeConfig | AuthorityType::WithheldWithdraw - | AuthorityType::CloseMint => "mint", + | AuthorityType::CloseMint + | AuthorityType::InterestRate => "mint", AuthorityType::AccountOwner | AuthorityType::CloseAccount => "account", }; let mut value = json!({ @@ -550,6 +551,27 @@ pub fn parse_token( }), }) } + TokenInstruction::InitializeNonTransferableMint => { + check_num_token_accounts(&instruction.accounts, 1)?; + Ok(ParsedInstructionEnum { + instruction_type: "initializeNonTransferableMint".to_string(), + info: json!({ + "mint": account_keys[instruction.accounts[0] as usize].to_string(), + }), + }) + } + TokenInstruction::InterestBearingMintExtension => { + if instruction.data.len() < 2 { + return Err(ParseInstructionError::InstructionNotParsable( + ParsableProgram::SplToken, + )); + } + parse_interest_bearing_mint_instruction( + &instruction.data[1..], + &instruction.accounts, + account_keys, + ) + } } } @@ -563,6 +585,7 @@ pub enum UiAuthorityType { TransferFeeConfig, WithheldWithdraw, CloseMint, + InterestRate, } impl From for UiAuthorityType { @@ -575,6 +598,7 @@ impl From for UiAuthorityType { AuthorityType::TransferFeeConfig => UiAuthorityType::TransferFeeConfig, AuthorityType::WithheldWithdraw => UiAuthorityType::WithheldWithdraw, AuthorityType::CloseMint => UiAuthorityType::CloseMint, + AuthorityType::InterestRate => UiAuthorityType::InterestRate, } } } @@ -591,6 +615,8 @@ pub enum UiExtensionType { DefaultAccountState, ImmutableOwner, MemoTransfer, + NonTransferable, + InterestBearingConfig, } impl From for UiExtensionType { @@ -607,6 +633,8 @@ impl From for UiExtensionType { ExtensionType::DefaultAccountState => UiExtensionType::DefaultAccountState, ExtensionType::ImmutableOwner => UiExtensionType::ImmutableOwner, ExtensionType::MemoTransfer => UiExtensionType::MemoTransfer, + ExtensionType::NonTransferable => UiExtensionType::NonTransferable, + ExtensionType::InterestBearingConfig => UiExtensionType::InterestBearingConfig, } } } diff --git a/transaction-status/src/parse_token/extension/interest_bearing_mint.rs b/transaction-status/src/parse_token/extension/interest_bearing_mint.rs new file mode 100644 index 000000000..a3e6b7d42 --- /dev/null +++ b/transaction-status/src/parse_token/extension/interest_bearing_mint.rs @@ -0,0 +1,64 @@ +use { + super::*, + spl_token_2022::{ + extension::interest_bearing_mint::{ + instruction::{InitializeInstructionData, InterestBearingMintInstruction}, + BasisPoints, + }, + instruction::{decode_instruction_data, decode_instruction_type}, + }, +}; + +pub(in crate::parse_token) fn parse_interest_bearing_mint_instruction( + instruction_data: &[u8], + account_indexes: &[u8], + account_keys: &AccountKeys, +) -> Result { + match decode_instruction_type(instruction_data) + .map_err(|_| ParseInstructionError::InstructionNotParsable(ParsableProgram::SplToken))? + { + InterestBearingMintInstruction::Initialize => { + check_num_token_accounts(account_indexes, 1)?; + let InitializeInstructionData { + rate_authority, + rate, + } = *decode_instruction_data(instruction_data).map_err(|_| { + ParseInstructionError::InstructionNotParsable(ParsableProgram::SplToken) + })?; + let rate_authority = rate_authority; + let rate_authority: Option = rate_authority.into(); + Ok(ParsedInstructionEnum { + instruction_type: "initializeInterestBearingConfig".to_string(), + info: json!({ + "mint": account_keys[account_indexes[0] as usize].to_string(), + "rateAuthority": rate_authority.map(|pubkey| pubkey.to_string()), + "rate": i16::from(rate), + }), + }) + } + InterestBearingMintInstruction::UpdateRate => { + check_num_token_accounts(account_indexes, 2)?; + let new_rate: BasisPoints = + *decode_instruction_data(instruction_data).map_err(|_| { + ParseInstructionError::InstructionNotParsable(ParsableProgram::SplToken) + })?; + let mut value = json!({ + "mint": account_keys[account_indexes[0] as usize].to_string(), + "newRate": i16::from(new_rate), + }); + let map = value.as_object_mut().unwrap(); + parse_signers( + map, + 1, + account_keys, + account_indexes, + "rateAuthority", + "multisigRateAuthority", + ); + Ok(ParsedInstructionEnum { + instruction_type: "updateInterestBearingConfigRate".to_string(), + info: value, + }) + } + } +} diff --git a/transaction-status/src/parse_token/extension/mod.rs b/transaction-status/src/parse_token/extension/mod.rs index 5a6580056..3c8494265 100644 --- a/transaction-status/src/parse_token/extension/mod.rs +++ b/transaction-status/src/parse_token/extension/mod.rs @@ -1,6 +1,7 @@ use super::*; pub(super) mod default_account_state; +pub(super) mod interest_bearing_mint; pub(super) mod memo_transfer; pub(super) mod mint_close_authority; pub(super) mod reallocate; diff --git a/transaction-status/src/token_balances.rs b/transaction-status/src/token_balances.rs index 381ba7383..b4c047410 100644 --- a/transaction-status/src/token_balances.rs +++ b/transaction-status/src/token_balances.rs @@ -325,7 +325,9 @@ mod test { mint_state.base = mint_base; mint_state.pack_base(); mint_state.init_account_type().unwrap(); - let mut mint_close_authority = mint_state.init_extension::().unwrap(); + let mut mint_close_authority = mint_state + .init_extension::(true) + .unwrap(); mint_close_authority.close_authority = OptionalNonZeroPubkey::try_from(Some(spl_token_pubkey(&mint_authority))).unwrap(); @@ -368,8 +370,10 @@ mod test { account_state.base = token_base; account_state.pack_base(); account_state.init_account_type().unwrap(); - account_state.init_extension::().unwrap(); - let mut memo_transfer = account_state.init_extension::().unwrap(); + account_state + .init_extension::(true) + .unwrap(); + let mut memo_transfer = account_state.init_extension::(true).unwrap(); memo_transfer.require_incoming_transfer_memos = true.into(); let spl_token_account = Account { @@ -408,8 +412,10 @@ mod test { account_state.base = other_mint_token_base; account_state.pack_base(); account_state.init_account_type().unwrap(); - account_state.init_extension::().unwrap(); - let mut memo_transfer = account_state.init_extension::().unwrap(); + account_state + .init_extension::(true) + .unwrap(); + let mut memo_transfer = account_state.init_extension::(true).unwrap(); memo_transfer.require_incoming_transfer_memos = true.into(); let other_mint_token_account = Account {