Skip to content

Commit

Permalink
token-2022: Execute transfer hook during confidential transfer (#6098)
Browse files Browse the repository at this point in the history
* Move confidential-transfer test types for reuse

* token-client: Add extra accounts for conf transfers

* token-2022: Execute transfer hook in conf transfer

* Test transfer hook with a confidential transfer

* Featurize "confidential-hook"

* Add new helper for adding the account metas

* Replace self.pubkey -> self.get_address()
  • Loading branch information
joncinque authored Jan 18, 2024
1 parent 3252cad commit 14db758
Show file tree
Hide file tree
Showing 7 changed files with 593 additions and 258 deletions.
198 changes: 139 additions & 59 deletions token/client/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2149,20 +2149,32 @@ where
.new_decryptable_available_balance(transfer_amount, source_aes_key)
.map_err(|_| TokenError::AccountDecryption)?;

self.process_ixs(
&confidential_transfer::instruction::transfer(
&self.program_id,
source_account,
&self.pubkey,
destination_account,
new_decryptable_available_balance,
source_authority,
&multisig_signers,
proof_location,
)?,
signing_keypairs,
let mut instructions = confidential_transfer::instruction::transfer(
&self.program_id,
source_account,
self.get_address(),
destination_account,
new_decryptable_available_balance,
source_authority,
&multisig_signers,
proof_location,
)?;
offchain::add_extra_account_metas(
&mut instructions[0],
source_account,
self.get_address(),
destination_account,
source_authority,
u64::MAX,
|address| {
self.client
.get_account(address)
.map_ok(|opt| opt.map(|acc| acc.data))
},
)
.await
.map_err(|_| TokenError::AccountNotFound)?;
self.process_ixs(&instructions, signing_keypairs).await
}

/// Transfer tokens confidentially using split proofs.
Expand Down Expand Up @@ -2195,22 +2207,32 @@ where
.new_decryptable_available_balance(transfer_amount, source_aes_key)
.map_err(|_| TokenError::AccountDecryption)?;

self.process_ixs(
&[
confidential_transfer::instruction::transfer_with_split_proofs(
&self.program_id,
source_account,
&self.pubkey,
destination_account,
new_decryptable_available_balance.into(),
source_authority,
context_state_accounts,
source_decrypt_handles,
)?,
],
signing_keypairs,
let mut instruction = confidential_transfer::instruction::transfer_with_split_proofs(
&self.program_id,
source_account,
self.get_address(),
destination_account,
new_decryptable_available_balance.into(),
source_authority,
context_state_accounts,
source_decrypt_handles,
)?;
offchain::add_extra_account_metas(
&mut instruction,
source_account,
self.get_address(),
destination_account,
source_authority,
u64::MAX,
|address| {
self.client
.get_account(address)
.map_ok(|opt| opt.map(|acc| acc.data))
},
)
.await
.map_err(|_| TokenError::AccountNotFound)?;
self.process_ixs(&[instruction], signing_keypairs).await
}

/// Transfer tokens confidentially using split proofs in parallel
Expand Down Expand Up @@ -2261,16 +2283,32 @@ where
.new_decryptable_available_balance(transfer_amount, source_aes_key)
.map_err(|_| TokenError::AccountDecryption)?;

let transfer_instruction = confidential_transfer::instruction::transfer_with_split_proofs(
&self.program_id,
let mut transfer_instruction =
confidential_transfer::instruction::transfer_with_split_proofs(
&self.program_id,
source_account,
self.get_address(),
destination_account,
new_decryptable_available_balance.into(),
source_authority,
context_state_accounts,
&source_decrypt_handles,
)?;
offchain::add_extra_account_metas(
&mut transfer_instruction,
source_account,
&self.pubkey,
self.get_address(),
destination_account,
new_decryptable_available_balance.into(),
source_authority,
context_state_accounts,
&source_decrypt_handles,
)?;
u64::MAX,
|address| {
self.client
.get_account(address)
.map_ok(|opt| opt.map(|acc| acc.data))
},
)
.await
.map_err(|_| TokenError::AccountNotFound)?;

let transfer_with_equality_and_ciphertext_validity = self
.create_equality_and_ciphertext_validity_proof_context_states_for_transfer_parallel(
Expand Down Expand Up @@ -2685,17 +2723,33 @@ where
// additional compute budget required for `VerifyTransferWithFee`
const TRANSFER_WITH_FEE_COMPUTE_BUDGET: u32 = 500_000;

let mut instructions = confidential_transfer::instruction::transfer_with_fee(
&self.program_id,
source_account,
destination_account,
self.get_address(),
new_decryptable_available_balance,
source_authority,
&multisig_signers,
proof_location,
)?;
offchain::add_extra_account_metas(
&mut instructions[0],
source_account,
self.get_address(),
destination_account,
source_authority,
u64::MAX,
|address| {
self.client
.get_account(address)
.map_ok(|opt| opt.map(|acc| acc.data))
},
)
.await
.map_err(|_| TokenError::AccountNotFound)?;
self.process_ixs_with_additional_compute_budget(
&confidential_transfer::instruction::transfer_with_fee(
&self.program_id,
source_account,
destination_account,
&self.pubkey,
new_decryptable_available_balance,
source_authority,
&multisig_signers,
proof_location,
)?,
&instructions,
TRANSFER_WITH_FEE_COMPUTE_BUDGET,
signing_keypairs,
)
Expand Down Expand Up @@ -2732,22 +2786,33 @@ where
.new_decryptable_available_balance(transfer_amount, source_aes_key)
.map_err(|_| TokenError::AccountDecryption)?;

self.process_ixs(
&[
confidential_transfer::instruction::transfer_with_fee_and_split_proofs(
&self.program_id,
source_account,
&self.pubkey,
destination_account,
new_decryptable_available_balance.into(),
source_authority,
context_state_accounts,
source_decrypt_handles,
)?,
],
signing_keypairs,
let mut instruction =
confidential_transfer::instruction::transfer_with_fee_and_split_proofs(
&self.program_id,
source_account,
self.get_address(),
destination_account,
new_decryptable_available_balance.into(),
source_authority,
context_state_accounts,
source_decrypt_handles,
)?;
offchain::add_extra_account_metas(
&mut instruction,
source_account,
self.get_address(),
destination_account,
source_authority,
u64::MAX,
|address| {
self.client
.get_account(address)
.map_ok(|opt| opt.map(|acc| acc.data))
},
)
.await
.map_err(|_| TokenError::AccountNotFound)?;
self.process_ixs(&[instruction], signing_keypairs).await
}

/// Transfer tokens confidentially using split proofs in parallel
Expand Down Expand Up @@ -2823,17 +2888,32 @@ where
.new_decryptable_available_balance(transfer_amount, source_aes_key)
.map_err(|_| TokenError::AccountDecryption)?;

let transfer_instruction =
let mut transfer_instruction =
confidential_transfer::instruction::transfer_with_fee_and_split_proofs(
&self.program_id,
source_account,
&self.pubkey,
self.get_address(),
destination_account,
new_decryptable_available_balance.into(),
source_authority,
context_state_accounts,
&source_decrypt_handles,
)?;
offchain::add_extra_account_metas(
&mut transfer_instruction,
source_account,
self.get_address(),
destination_account,
source_authority,
u64::MAX,
|address| {
self.client
.get_account(address)
.map_ok(|opt| opt.map(|acc| acc.data))
},
)
.await
.map_err(|_| TokenError::AccountNotFound)?;

let transfer_with_equality_and_ciphertext_valdity = self
.create_equality_and_ciphertext_validity_proof_context_states_for_transfer_with_fee_parallel(
Expand Down
Loading

0 comments on commit 14db758

Please sign in to comment.