Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 29479fc

Browse files
authored
token-2022: Make program and crate deployable (#2985)
* token-2022: Make program and crate deployable * Featurize the syscall usage * Re-add GenericTokenAccount * Rebase correctly with GenericTokenAccount * Add updated valid_account_data implementation
1 parent 810c79e commit 29479fc

File tree

10 files changed

+279
-72
lines changed

10 files changed

+279
-72
lines changed

token/program-2022-test/tests/memo_transfer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ async fn test_memo_transfers(
9595
&[&ctx.payer, &alice],
9696
ctx.last_blockhash,
9797
);
98+
#[allow(clippy::useless_conversion)]
9899
let err: TransactionError = ctx
99100
.banks_client
100101
.process_transaction(tx)

token/program-2022/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ exclude = ["js/**"]
1111
[features]
1212
no-entrypoint = []
1313
test-bpf = []
14+
# Remove these features once the underlying syscalls are released on all networks
15+
default = ["reallocate", "sibling-instruction", "zk-ops"]
16+
reallocate = []
17+
sibling-instruction = []
18+
zk-ops = []
1419

1520
[dependencies]
1621
arrayref = "0.3.6"

token/program-2022/src/extension/confidential_transfer/processor.rs

Lines changed: 97 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,28 @@ use {
44
error::TokenError,
55
extension::{
66
confidential_transfer::{instruction::*, *},
7-
transfer_fee::TransferFeeConfig,
87
StateWithExtensions, StateWithExtensionsMut,
98
},
109
processor::Processor,
1110
state::{Account, Mint},
1211
},
1312
solana_program::{
1413
account_info::{next_account_info, AccountInfo},
15-
clock::Clock,
1614
entrypoint::ProgramResult,
1715
instruction::Instruction,
1816
msg,
1917
program_error::ProgramError,
2018
pubkey::Pubkey,
21-
sysvar::{instructions::get_instruction_relative, Sysvar},
19+
sysvar::instructions::get_instruction_relative,
2220
},
23-
solana_zk_token_sdk::{zk_token_elgamal::ops, zk_token_proof_program},
21+
solana_zk_token_sdk::zk_token_proof_program,
22+
};
23+
// Remove feature once zk ops syscalls are enabled on all networks
24+
#[cfg(feature = "zk-ops")]
25+
use {
26+
crate::extension::transfer_fee::TransferFeeConfig,
27+
solana_program::{clock::Clock, sysvar::Sysvar},
28+
solana_zk_token_sdk::zk_token_elgamal::ops,
2429
};
2530

2631
fn decode_proof_instruction<T: Pod>(
@@ -246,6 +251,7 @@ fn process_empty_account(
246251
}
247252

248253
/// Processes a [Deposit] instruction.
254+
#[cfg(feature = "zk-ops")]
249255
fn process_deposit(
250256
program_id: &Pubkey,
251257
accounts: &[AccountInfo],
@@ -345,6 +351,7 @@ fn process_deposit(
345351
}
346352

347353
/// Processes a [Withdraw] instruction.
354+
#[cfg(feature = "zk-ops")]
348355
fn process_withdraw(
349356
program_id: &Pubkey,
350357
accounts: &[AccountInfo],
@@ -449,6 +456,7 @@ fn process_withdraw(
449456
}
450457

451458
/// Processes an [Transfer] instruction.
459+
#[cfg(feature = "zk-ops")]
452460
fn process_transfer(
453461
program_id: &Pubkey,
454462
accounts: &[AccountInfo],
@@ -595,6 +603,7 @@ fn process_transfer(
595603
}
596604

597605
#[allow(clippy::too_many_arguments)]
606+
#[cfg(feature = "zk-ops")]
598607
fn process_source_for_transfer(
599608
program_id: &Pubkey,
600609
token_account_info: &AccountInfo,
@@ -650,6 +659,7 @@ fn process_source_for_transfer(
650659
Ok(())
651660
}
652661

662+
#[cfg(feature = "zk-ops")]
653663
fn process_destination_for_transfer(
654664
destination_token_account_info: &AccountInfo,
655665
mint_info: &AccountInfo,
@@ -730,6 +740,7 @@ fn process_destination_for_transfer(
730740
}
731741

732742
/// Processes an [ApplyPendingBalance] instruction.
743+
#[cfg(feature = "zk-ops")]
733744
fn process_apply_pending_balance(
734745
program_id: &Pubkey,
735746
accounts: &[AccountInfo],
@@ -806,6 +817,7 @@ fn process_allow_balance_credits(
806817
}
807818

808819
/// Processes an [WithdrawWithheldTokensFromMint] instruction.
820+
#[cfg(feature = "zk-ops")]
809821
fn process_withdraw_withheld_tokens_from_mint(
810822
program_id: &Pubkey,
811823
accounts: &[AccountInfo],
@@ -894,6 +906,7 @@ fn process_withdraw_withheld_tokens_from_mint(
894906
Ok(())
895907
}
896908

909+
#[cfg(feature = "zk-ops")]
897910
fn process_withdraw_withheld_tokens_from_accounts(
898911
program_id: &Pubkey,
899912
accounts: &[AccountInfo],
@@ -1009,6 +1022,7 @@ fn process_withdraw_withheld_tokens_from_accounts(
10091022
Ok(())
10101023
}
10111024

1025+
#[cfg(feature = "zk-ops")]
10121026
fn harvest_from_account<'a, 'b>(
10131027
mint_key: &'b Pubkey,
10141028
token_account_info: &'b AccountInfo<'a>,
@@ -1032,6 +1046,7 @@ fn harvest_from_account<'a, 'b>(
10321046
}
10331047

10341048
/// Processes an [HarvestWithheldTokensToMint] instruction.
1049+
#[cfg(feature = "zk-ops")]
10351050
fn process_harvest_withheld_tokens_to_mint(accounts: &[AccountInfo]) -> ProgramResult {
10361051
let account_info_iter = &mut accounts.iter();
10371052
let mint_account_info = next_account_info(account_info_iter)?;
@@ -1061,6 +1076,7 @@ fn process_harvest_withheld_tokens_to_mint(accounts: &[AccountInfo]) -> ProgramR
10611076
Ok(())
10621077
}
10631078

1079+
#[allow(dead_code)]
10641080
pub(crate) fn process_instruction(
10651081
program_id: &Pubkey,
10661082
accounts: &[AccountInfo],
@@ -1102,38 +1118,60 @@ pub(crate) fn process_instruction(
11021118
}
11031119
ConfidentialTransferInstruction::Deposit => {
11041120
msg!("ConfidentialTransferInstruction::Deposit");
1105-
let data = decode_instruction_data::<DepositInstructionData>(input)?;
1106-
process_deposit(program_id, accounts, data.amount.into(), data.decimals)
1121+
#[cfg(feature = "zk-ops")]
1122+
{
1123+
let data = decode_instruction_data::<DepositInstructionData>(input)?;
1124+
process_deposit(program_id, accounts, data.amount.into(), data.decimals)
1125+
}
1126+
#[cfg(not(feature = "zk-ops"))]
1127+
Err(ProgramError::InvalidInstructionData)
11071128
}
11081129
ConfidentialTransferInstruction::Withdraw => {
11091130
msg!("ConfidentialTransferInstruction::Withdraw");
1110-
let data = decode_instruction_data::<WithdrawInstructionData>(input)?;
1111-
process_withdraw(
1112-
program_id,
1113-
accounts,
1114-
data.amount.into(),
1115-
data.decimals,
1116-
data.new_decryptable_available_balance,
1117-
data.proof_instruction_offset as i64,
1118-
)
1131+
#[cfg(feature = "zk-ops")]
1132+
{
1133+
let data = decode_instruction_data::<WithdrawInstructionData>(input)?;
1134+
process_withdraw(
1135+
program_id,
1136+
accounts,
1137+
data.amount.into(),
1138+
data.decimals,
1139+
data.new_decryptable_available_balance,
1140+
data.proof_instruction_offset as i64,
1141+
)
1142+
}
1143+
#[cfg(not(feature = "zk-ops"))]
1144+
Err(ProgramError::InvalidInstructionData)
11191145
}
11201146
ConfidentialTransferInstruction::Transfer => {
11211147
msg!("ConfidentialTransferInstruction::Transfer");
1122-
let data = decode_instruction_data::<TransferInstructionData>(input)?;
1123-
process_transfer(
1124-
program_id,
1125-
accounts,
1126-
data.new_source_decryptable_available_balance,
1127-
data.proof_instruction_offset as i64,
1128-
)
1148+
#[cfg(feature = "zk-ops")]
1149+
{
1150+
let data = decode_instruction_data::<TransferInstructionData>(input)?;
1151+
process_transfer(
1152+
program_id,
1153+
accounts,
1154+
data.new_source_decryptable_available_balance,
1155+
data.proof_instruction_offset as i64,
1156+
)
1157+
}
1158+
#[cfg(not(feature = "zk-ops"))]
1159+
Err(ProgramError::InvalidInstructionData)
11291160
}
11301161
ConfidentialTransferInstruction::ApplyPendingBalance => {
11311162
msg!("ConfidentialTransferInstruction::ApplyPendingBalance");
1132-
process_apply_pending_balance(
1133-
program_id,
1134-
accounts,
1135-
decode_instruction_data::<ApplyPendingBalanceData>(input)?,
1136-
)
1163+
#[cfg(feature = "zk-ops")]
1164+
{
1165+
process_apply_pending_balance(
1166+
program_id,
1167+
accounts,
1168+
decode_instruction_data::<ApplyPendingBalanceData>(input)?,
1169+
)
1170+
}
1171+
#[cfg(not(feature = "zk-ops"))]
1172+
{
1173+
Err(ProgramError::InvalidInstructionData)
1174+
}
11371175
}
11381176
ConfidentialTransferInstruction::DisableBalanceCredits => {
11391177
msg!("ConfidentialTransferInstruction::DisableBalanceCredits");
@@ -1145,26 +1183,44 @@ pub(crate) fn process_instruction(
11451183
}
11461184
ConfidentialTransferInstruction::WithdrawWithheldTokensFromMint => {
11471185
msg!("ConfidentialTransferInstruction::WithdrawWithheldTokensFromMint");
1148-
let data = decode_instruction_data::<WithdrawWithheldTokensFromMintData>(input)?;
1149-
process_withdraw_withheld_tokens_from_mint(
1150-
program_id,
1151-
accounts,
1152-
data.proof_instruction_offset as i64,
1153-
)
1186+
#[cfg(feature = "zk-ops")]
1187+
{
1188+
let data = decode_instruction_data::<WithdrawWithheldTokensFromMintData>(input)?;
1189+
process_withdraw_withheld_tokens_from_mint(
1190+
program_id,
1191+
accounts,
1192+
data.proof_instruction_offset as i64,
1193+
)
1194+
}
1195+
#[cfg(not(feature = "zk-ops"))]
1196+
Err(ProgramError::InvalidInstructionData)
11541197
}
11551198
ConfidentialTransferInstruction::WithdrawWithheldTokensFromAccounts => {
11561199
msg!("ConfidentialTransferInstruction::WithdrawWithheldTokensFromAccounts");
1157-
let data = decode_instruction_data::<WithdrawWithheldTokensFromAccountsData>(input)?;
1158-
process_withdraw_withheld_tokens_from_accounts(
1159-
program_id,
1160-
accounts,
1161-
data.num_token_accounts,
1162-
data.proof_instruction_offset as i64,
1163-
)
1200+
#[cfg(feature = "zk-ops")]
1201+
{
1202+
let data =
1203+
decode_instruction_data::<WithdrawWithheldTokensFromAccountsData>(input)?;
1204+
process_withdraw_withheld_tokens_from_accounts(
1205+
program_id,
1206+
accounts,
1207+
data.num_token_accounts,
1208+
data.proof_instruction_offset as i64,
1209+
)
1210+
}
1211+
#[cfg(not(feature = "zk-ops"))]
1212+
Err(ProgramError::InvalidInstructionData)
11641213
}
11651214
ConfidentialTransferInstruction::HarvestWithheldTokensToMint => {
11661215
msg!("ConfidentialTransferInstruction::HarvestWithheldTokensToMint");
1167-
process_harvest_withheld_tokens_to_mint(accounts)
1216+
#[cfg(feature = "zk-ops")]
1217+
{
1218+
process_harvest_withheld_tokens_to_mint(accounts)
1219+
}
1220+
#[cfg(not(feature = "zk-ops"))]
1221+
{
1222+
Err(ProgramError::InvalidInstructionData)
1223+
}
11681224
}
11691225
}
11701226
}

token/program-2022/src/extension/memo_transfer/mod.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ use {
55
state::Account,
66
},
77
bytemuck::{Pod, Zeroable},
8+
solana_program::program_error::ProgramError,
9+
};
10+
11+
// Remove feature once sibling instruction syscall is available on all networks
12+
#[cfg(feature = "sibling-instruction")]
13+
use {
14+
crate::error::TokenError,
15+
solana_program::{instruction::get_processed_sibling_instruction, pubkey::Pubkey},
816
};
917

1018
/// Memo Transfer extension instructions
@@ -31,3 +39,21 @@ pub fn memo_required(account_state: &StateWithExtensionsMut<Account>) -> bool {
3139
}
3240
false
3341
}
42+
43+
/// Check if the previous sibling instruction is a memo
44+
pub fn check_previous_sibling_instruction_is_memo() -> Result<(), ProgramError> {
45+
#[cfg(feature = "sibling-instruction")]
46+
{
47+
let is_memo_program = |program_id: &Pubkey| -> bool {
48+
program_id == &spl_memo::id() || program_id == &spl_memo::v1::id()
49+
};
50+
let previous_instruction = get_processed_sibling_instruction(0);
51+
match previous_instruction {
52+
Some(instruction) if is_memo_program(&instruction.program_id) => {}
53+
_ => {
54+
return Err(TokenError::NoMemo.into());
55+
}
56+
}
57+
}
58+
Ok(())
59+
}

token/program-2022/src/extension/memo_transfer/processor.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ fn process_diasble_required_memo_transfers(
7777
Ok(())
7878
}
7979

80+
#[allow(dead_code)]
8081
pub(crate) fn process_instruction(
8182
program_id: &Pubkey,
8283
accounts: &[AccountInfo],

token/program-2022/src/extension/reallocate.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#[cfg(feature = "reallocate")]
12
use {
23
crate::{
34
error::TokenError,
@@ -16,7 +17,18 @@ use {
1617
},
1718
};
1819

20+
/// Stub implementation to remove when reallocate is released on all networks
21+
#[cfg(not(feature = "reallocate"))]
22+
pub fn process_reallocate(
23+
_program_id: &solana_program::pubkey::Pubkey,
24+
_accounts: &[solana_program::account_info::AccountInfo],
25+
_new_extension_types: Vec<crate::extension::ExtensionType>,
26+
) -> solana_program::entrypoint::ProgramResult {
27+
Err(solana_program::program_error::ProgramError::InvalidInstructionData)
28+
}
29+
1930
/// Processes a [Reallocate](enum.TokenInstruction.html) instruction
31+
#[cfg(feature = "reallocate")]
2032
pub fn process_reallocate(
2133
program_id: &Pubkey,
2234
accounts: &[AccountInfo],

0 commit comments

Comments
 (0)