Repository: solana-labs/solana-program-library
Pull request #7021 (2024-07-17 08:43:32)

[confidential-transfer] Organize transfer proof data using structs
#### Problem
The constructor functions for proof data required for confidential transfer and transfer with fee returns a tuple of proof data structs. It would be cleaner and more readable to organize the return type using structs instead.

#### Summary of changes
Re-organize the proof data using structs.


Patch:
diff --git a/token/confidential-transfer/proof-generation/src/transfer.rs b/token/confidential-transfer/proof-generation/src/transfer.rs
index 778fe10c8..fbb257a4f 100644
--- a/token/confidential-transfer/proof-generation/src/transfer.rs
+++ b/token/confidential-transfer/proof-generation/src/transfer.rs
@@ -21,6 +21,14 @@ use {
 /// token transfer
 const RANGE_PROOF_PADDING_BIT_LENGTH: usize = 16;
 
+/// The proof data required for a confidential transfer instruction when the
+/// mint is not extended for fees
+pub struct TransferProofData {
+    pub equality_proof_data: CiphertextCommitmentEqualityProofData,
+    pub ciphertext_validity_proof_data: BatchedGroupedCiphertext3HandlesValidityProofData,
+    pub range_proof_data: BatchedRangeProofU128Data,
+}
+
 pub fn transfer_split_proof_data(
     current_available_balance: &ElGamalCiphertext,
     current_decryptable_available_balance: &AeCiphertext,
@@ -29,14 +37,7 @@ pub fn transfer_split_proof_data(
     aes_key: &AeKey,
     destination_elgamal_pubkey: &ElGamalPubkey,
     auditor_elgamal_pubkey: Option<&ElGamalPubkey>,
-) -> Result<
-    (
-        CiphertextCommitmentEqualityProofData,
-        BatchedGroupedCiphertext3HandlesValidityProofData,
-        BatchedRangeProofU128Data,
-    ),
-    TokenProofGenerationError,
-> {
+) -> Result<TransferProofData, TokenProofGenerationError> {
     let default_auditor_pubkey = ElGamalPubkey::default();
     let auditor_elgamal_pubkey = auditor_elgamal_pubkey.unwrap_or(&default_auditor_pubkey);
 
@@ -149,9 +150,9 @@ pub fn transfer_split_proof_data(
     )
     .map_err(TokenProofGenerationError::from)?;
 
-    Ok((
+    Ok(TransferProofData {
         equality_proof_data,
         ciphertext_validity_proof_data,
         range_proof_data,
-    ))
+    })
 }
diff --git a/token/confidential-transfer/proof-generation/src/transfer_with_fee.rs b/token/confidential-transfer/proof-generation/src/transfer_with_fee.rs
index d0705e9f1..f49e1aa00 100644
--- a/token/confidential-transfer/proof-generation/src/transfer_with_fee.rs
+++ b/token/confidential-transfer/proof-generation/src/transfer_with_fee.rs
@@ -30,6 +30,17 @@ const FEE_AMOUNT_HI_BITS: usize = 32;
 const REMAINING_BALANCE_BIT_LENGTH: usize = 64;
 const DELTA_BIT_LENGTH: usize = 48;
 
+/// The proof data required for a confidential transfer instruction when the
+/// mint is extended for fees
+pub struct TransferWithFeeProofData {
+    pub equality_proof_data: CiphertextCommitmentEqualityProofData,
+    pub transfer_amount_ciphertext_validity_proof_data:
+        BatchedGroupedCiphertext3HandlesValidityProofData,
+    pub percentage_with_cap_proof_data: PercentageWithCapProofData,
+    pub fee_ciphertext_validity_proof_data: BatchedGroupedCiphertext2HandlesValidityProofData,
+    pub range_proof_data: BatchedRangeProofU256Data,
+}
+
 #[allow(clippy::too_many_arguments)]
 pub fn transfer_with_fee_split_proof_data(
     current_available_balance: &ElGamalCiphertext,
@@ -42,16 +53,7 @@ pub fn transfer_with_fee_split_proof_data(
     withdraw_withheld_authority_elgamal_pubkey: &ElGamalPubkey,
     fee_rate_basis_points: u16,
     maximum_fee: u64,
-) -> Result<
-    (
-        CiphertextCommitmentEqualityProofData,
-        BatchedGroupedCiphertext3HandlesValidityProofData,
-        PercentageWithCapProofData,
-        BatchedGroupedCiphertext2HandlesValidityProofData,
-        BatchedRangeProofU256Data,
-    ),
-    TokenProofGenerationError,
-> {
+) -> Result<TransferWithFeeProofData, TokenProofGenerationError> {
     let default_auditor_pubkey = ElGamalPubkey::default();
     let auditor_elgamal_pubkey = auditor_elgamal_pubkey.unwrap_or(&default_auditor_pubkey);
 
@@ -294,13 +296,13 @@ pub fn transfer_with_fee_split_proof_data(
     )
     .map_err(TokenProofGenerationError::from)?;
 
-    Ok((
+    Ok(TransferWithFeeProofData {
         equality_proof_data,
         transfer_amount_ciphertext_validity_proof_data,
         percentage_with_cap_proof_data,
         fee_ciphertext_validity_proof_data,
         range_proof_data,
-    ))
+    })
 }
 
 fn calculate_fee(transfer_amount: u64, fee_rate_basis_points: u16) -> Option<(u64, u64)> {


Test patch:
diff --git a/token/confidential-transfer/proof-tests/tests/proof_test.rs b/token/confidential-transfer/proof-tests/tests/proof_test.rs
index da87a3ab8..0796cbb9a 100644
--- a/token/confidential-transfer/proof-tests/tests/proof_test.rs
+++ b/token/confidential-transfer/proof-tests/tests/proof_test.rs
@@ -8,8 +8,8 @@ use {
         withdraw::WithdrawProofContext,
     },
     spl_token_confidential_transfer_proof_generation::{
-        transfer::transfer_split_proof_data,
-        transfer_with_fee::transfer_with_fee_split_proof_data,
+        transfer::{transfer_split_proof_data, TransferProofData},
+        transfer_with_fee::{transfer_with_fee_split_proof_data, TransferWithFeeProofData},
         withdraw::{withdraw_proof_data, WithdrawProofData},
     },
 };
@@ -38,7 +38,11 @@ fn test_transfer_proof_validity(spendable_balance: u64, transfer_amount: u64) {
     let spendable_ciphertext = source_keypair.pubkey().encrypt(spendable_balance);
     let decryptable_balance = aes_key.encrypt(spendable_balance);
 
-    let (equality_proof_data, validity_proof_data, range_proof_data) = transfer_split_proof_data(
+    let TransferProofData {
+        equality_proof_data,
+        ciphertext_validity_proof_data,
+        range_proof_data,
+    } = transfer_split_proof_data(
         &spendable_ciphertext,
         &decryptable_balance,
         transfer_amount,
@@ -50,12 +54,12 @@ fn test_transfer_proof_validity(spendable_balance: u64, transfer_amount: u64) {
     .unwrap();
 
     equality_proof_data.verify_proof().unwrap();
-    validity_proof_data.verify_proof().unwrap();
+    ciphertext_validity_proof_data.verify_proof().unwrap();
     range_proof_data.verify_proof().unwrap();
 
     TransferProofContext::verify_and_extract(
         equality_proof_data.context_data(),
-        validity_proof_data.context_data(),
+        ciphertext_validity_proof_data.context_data(),
         range_proof_data.context_data(),
     )
     .unwrap();
@@ -104,13 +108,13 @@ fn test_transfer_with_fee_proof_validity(
     let spendable_ciphertext = source_keypair.pubkey().encrypt(spendable_balance);
     let decryptable_balance = aes_key.encrypt(spendable_balance);
 
-    let (
+    let TransferWithFeeProofData {
         equality_proof_data,
         transfer_amount_ciphertext_validity_proof_data,
         percentage_with_cap_proof_data,
         fee_ciphertext_validity_proof_data,
         range_proof_data,
-    ) = transfer_with_fee_split_proof_data(
+    } = transfer_with_fee_split_proof_data(
         &spendable_ciphertext,
         &decryptable_balance,
         transfer_amount,