Skip to content
This repository has been archived by the owner on Jan 10, 2025. It is now read-only.

[token-2022] Add support for record program for Transfer and TransferWithFee instructions #7127

Merged
merged 9 commits into from
Aug 11, 2024

Conversation

samkim-crypto
Copy link
Contributor

@samkim-crypto samkim-crypto commented Aug 9, 2024

Problem

  • The confidential transfer instruction with split proofs does not yet support proofs from record program.
  • The new zk-sdk does not have support for the VerifyTransfer and VerifyTransferWithFee proofs any more

Summary of Changes

3dc64b0: I first realized that there are a lot of repetitive logic in the verify_*_proof functions, so I refactored the logic into a verify_and_extract_context function. In the end, this turned out quite nicely with the use of generics and traits.

c4cbfa9: I made each of the individual proofs in the TransferWithSplitProofs instruction to be read either from instruction data, record account, or context state account. Previously, the proofs could only be read from context accounts. In the process (after a bit of wrestling), I ended up removing the custom logic for parallel execution and auto-close. These custom logic does not really make much sense any more with the added flexibility of instruction data and record account and were over-complicating the logic. In this commit, I made some changes in the verification function lifetimes, but these changes are undone in the next commit 🙏 .

e7a08d7: Since zk-sdk does not support VerifyTransfer and VerifyTransferWithFee any more, the original confidential Transfer instruction is to be removed. Instead, now I made the original Transfer instruction the TransferWithSplitProof without fee (but still with the name Transfer) and the TransferWithSplitProof instruction to be TransferWithFee instruction now that these two instructions require different instruction data. In the process, I updated the transfer amount ciphertext validity proof in transfer instructions to be BatchedGroupedCiphertext3HandlesValidityProof instead of for 2 handles.

ca8b1ad: This is a smaller commit. I ended up just removing verify_*_proof functions and using verify_and_extract_context function directly.

46a180b: I updated the client according to the new updates in the program interface. Since the parallel execution logics were removed, I ended up removing the relevant functions in the client.

4c8c53b: Updated the tests to test for all three possible ways to include zk proofs in the instruction (instruction data, record account, context state account).

b9343d9: Updated token-cli for the newly changes interface in the token-client. Right now, the confidential transfer logic uses context state accounts to include proofs. I'll update these to use record program instead in a follow-up PR.

@samkim-crypto samkim-crypto requested a review from joncinque August 9, 2024 10:15
@samkim-crypto samkim-crypto marked this pull request as ready for review August 9, 2024 10:15
joncinque
joncinque previously approved these changes Aug 9, 2024
Copy link
Contributor

@joncinque joncinque left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really excellent work! I didn't think it would simplify the code so much -- despite the big line count, this was an easy read. My comments are all minor, and don't stop this from going in as is

ciphertext_validity_proof_data_location
{
let proof_instruction_offset: i8 = proof_instruction_offset.into();
if proof_instruction_offset != 2 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since all of the proof instructions are optional, should this start at 1 and then get added for each proof that isn't a context state account? For example, if I use a context state account for the first proof, and then a record account for this one, then the proof instruction would actually be 1, and not 2.

Feel free to do this in follow-up work btw, since it's fine to say that this works all-or-nothing right now.

equality_proof_data_location
{
let proof_instruction_offset: i8 = proof_instruction_offset.into();
if proof_instruction_offset != 1 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment over here, but again, it can be done in follow-up work

Comment on lines +2227 to +2243
let equality_proof_location = Self::confidential_transfer_create_proof_location(
equality_proof_data.as_ref(),
equality_proof_account,
1,
)
.unwrap();
let ciphertext_validity_proof_location = Self::confidential_transfer_create_proof_location(
ciphertext_validity_proof_data.as_ref(),
ciphertext_validity_proof_account,
2,
)
.unwrap();
let range_proof_location = Self::confidential_transfer_create_proof_location(
range_proof_data.as_ref(),
range_proof_account,
3,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, should the offset only get incremented if it's using a context state account?

Comment on lines +2631 to +2662
let equality_proof_location = Self::confidential_transfer_create_proof_location(
equality_proof_data.as_ref(),
equality_proof_account,
1,
)
.unwrap();
let transfer_amount_ciphertext_validity_proof_location =
Self::confidential_transfer_create_proof_location(
transfer_amount_ciphertext_validity_proof_data.as_ref(),
transfer_amount_ciphertext_validity_proof_account,
2,
)
.unwrap();
let fee_sigma_proof_location = Self::confidential_transfer_create_proof_location(
fee_sigma_proof_data.as_ref(),
fee_sigma_proof_account,
3,
)
.unwrap();
let fee_ciphertext_validity_proof_location =
Self::confidential_transfer_create_proof_location(
fee_ciphertext_validity_proof_data.as_ref(),
fee_ciphertext_validity_proof_account,
4,
)
.unwrap();
let range_proof_location = Self::confidential_transfer_create_proof_location(
range_proof_data.as_ref(),
range_proof_account,
5,
)
.unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same with these -- only increment the offset if needed?

@mergify mergify bot dismissed joncinque’s stale review August 11, 2024 02:21

Pull request has been modified.

@samkim-crypto
Copy link
Contributor Author

Thanks for the review! I'll address the increment on a follow-up PR as you suggested 🙏

@samkim-crypto samkim-crypto merged commit d0eff43 into solana-labs:master Aug 11, 2024
35 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants