-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[zk-token-sdk] Add option to create proof context state in the proof verification program #29996
[zk-token-sdk] Add option to create proof context state in the proof verification program #29996
Conversation
These proof program changes break downstream projects in SPL token. If the changes look reasonable, then I can temporarily disable proof verification in SPL and figure out a way to get the ci tests to accept. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The guts are looking great! Just some bits to clarify / test a bit more
The changes should be ready for another review. One issue that came up is that the
However,
|
The changes look great overall! Regarding:
This would be pretty slick. How about just decoding as a different type? Ie:
Then you can decode the struct from the data, make sure there's a valid proof type, and assume that Maybe someone else will have a stronger opinion than me. I'll let you / them decide. Side note: feel free to go with a better name! |
Great! I was able to remove the proof type from I ended up creating |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking really close! Just one last question
/// If `true`, the proof ocntext account is already initialized | ||
pub is_initialized: PodBool, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I may be missing something obvious, but what's the reason for having this bool and also the proof type? you could probably just move the proof type to here, and then make sure that it's not uninitialized during closing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that should definitely work and it will save a byte. I just thought about what is the most natural in terms of the literal interpretation of a "proof context". ProofType
is context information for a proof, so it is natural inside proof_context: T
. On the other hand, is_initialized
is state information for the state account.
But thinking about it now, maybe it is worth using proof_type
for is_initialized
since that gives the most efficiency...
Codecov Report
@@ Coverage Diff @@
## master #29996 +/- ##
=========================================
- Coverage 81.7% 81.4% -0.3%
=========================================
Files 723 724 +1
Lines 201802 202471 +669
=========================================
- Hits 164891 164854 -37
- Misses 36911 37617 +706 |
The downstream CI tests finally passes. I apologize for the long delay in this PR. If anyone can have a quick sanity check to approve this, then it would be great 🙏 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one more question, then this should be good to go! Thanks for your patience
zk-token-sdk/src/instruction/mod.rs
Outdated
@@ -51,7 +50,7 @@ pub trait ZkProofData: Pod { | |||
} | |||
|
|||
pub trait ZkProofContext: Pod { | |||
fn proof_type(&self) -> Result<ProofType, InstructionError>; | |||
const PROOF_TYPE: ProofType; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that I'm reading back through this, do we need ZkProofContext
at all? I think we can generalize and simplify this a bit if we have:
pub trait ZkProofData<T: Pod> {
const PROOF_TYPE: ProofType;
fn context_data(&self) -> &T;
#[cfg(not(target_os = "solana"))]
fn verify_proof(&self) -> Result<(), ProofError>;
}
Alternatively, you can remove the proof_type
parameter from ProofContextState::encode
since it can be fetched directly from T
, but I would lean towards the first option to keep things simpler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this is a good point. I was initially a little torn with this because there should technically be one ZkProofContext
type for each ZkProofData
type. Even if ZkProofContext
is an empty market trait, having it as an associated type in ZkProofData
naturally enforces this. For example, implementing CloseProofContext
inside TransferProofData
would not really make sense.
But in the end, I decided to go with removing ZkProofContext
because it does simplify the instruction implementations a bit. Thanks for the suggestion!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Thanks for all of your patience during that long back and forth
…verification program (#29996) * extend verifiable trait * add PodBool * implement ZkProofData trait * add proof context program to zk-token-proof program * update tests for close account * add close account instruction * reorganize tests * complete tests * clean up and add docs * clean up pod * add proof program state * update tests * move proof program tests as separate module * clippy * cargo sort * cargo fmt * re-organize visibility * add context state description * update maintainer reference * change `VerifyProofData` and `ProofContextState` to pod * add tests for mixing proof types * add tests for self owned context state accounts * cargo fmt * remove unnecessary scoping and add comments on scopes * re-organize proof instructions * clippy * update zk-token-proof-test to 1.16.0 * upgrade spl-token-2022 to 0.6.1 * reoganize proof type * cargo lock * remove ZkProofContext trait (cherry picked from commit 2d58bb2) # Conflicts: # Cargo.lock # Cargo.toml # programs/bpf/Cargo.lock # zk-token-sdk/src/instruction/transfer.rs
…verification program (solana-labs#29996) * extend verifiable trait * add PodBool * implement ZkProofData trait * add proof context program to zk-token-proof program * update tests for close account * add close account instruction * reorganize tests * complete tests * clean up and add docs * clean up pod * add proof program state * update tests * move proof program tests as separate module * clippy * cargo sort * cargo fmt * re-organize visibility * add context state description * update maintainer reference * change `VerifyProofData` and `ProofContextState` to pod * add tests for mixing proof types * add tests for self owned context state accounts * cargo fmt * remove unnecessary scoping and add comments on scopes * re-organize proof instructions * clippy * update zk-token-proof-test to 1.16.0 * upgrade spl-token-2022 to 0.6.1 * reoganize proof type * cargo lock * remove ZkProofContext trait
…verification program (solana-labs#29996) * extend verifiable trait * add PodBool * implement ZkProofData trait * add proof context program to zk-token-proof program * update tests for close account * add close account instruction * reorganize tests * complete tests * clean up and add docs * clean up pod * add proof program state * update tests * move proof program tests as separate module * clippy * cargo sort * cargo fmt * re-organize visibility * add context state description * update maintainer reference * change `VerifyProofData` and `ProofContextState` to pod * add tests for mixing proof types * add tests for self owned context state accounts * cargo fmt * remove unnecessary scoping and add comments on scopes * re-organize proof instructions * clippy * update zk-token-proof-test to 1.16.0 * upgrade spl-token-2022 to 0.6.1 * reoganize proof type * cargo lock * remove ZkProofContext trait
…verification program (#29996) * extend verifiable trait * add PodBool * implement ZkProofData trait * add proof context program to zk-token-proof program * update tests for close account * add close account instruction * reorganize tests * complete tests * clean up and add docs * clean up pod * add proof program state * update tests * move proof program tests as separate module * clippy * cargo sort * cargo fmt * re-organize visibility * add context state description * update maintainer reference * change `VerifyProofData` and `ProofContextState` to pod * add tests for mixing proof types * add tests for self owned context state accounts * cargo fmt * remove unnecessary scoping and add comments on scopes * re-organize proof instructions * clippy * update zk-token-proof-test to 1.16.0 * upgrade spl-token-2022 to 0.6.1 * reoganize proof type * cargo lock * remove ZkProofContext trait (cherry picked from commit 2d58bb2) # Conflicts: # Cargo.lock # Cargo.toml # programs/bpf/Cargo.lock # zk-token-sdk/src/instruction/transfer.rs
… proof verification program (backport of #29996) (#30739) * [zk-token-sdk] Add option to create proof context state in the proof verification program (#29996) * extend verifiable trait * add PodBool * implement ZkProofData trait * add proof context program to zk-token-proof program * update tests for close account * add close account instruction * reorganize tests * complete tests * clean up and add docs * clean up pod * add proof program state * update tests * move proof program tests as separate module * clippy * cargo sort * cargo fmt * re-organize visibility * add context state description * update maintainer reference * change `VerifyProofData` and `ProofContextState` to pod * add tests for mixing proof types * add tests for self owned context state accounts * cargo fmt * remove unnecessary scoping and add comments on scopes * re-organize proof instructions * clippy * update zk-token-proof-test to 1.16.0 * upgrade spl-token-2022 to 0.6.1 * reoganize proof type * cargo lock * remove ZkProofContext trait (cherry picked from commit 2d58bb2) # Conflicts: # Cargo.lock # Cargo.toml # programs/bpf/Cargo.lock # zk-token-sdk/src/instruction/transfer.rs * resolve conflicts * update zk-token-proof-tests version * adjust for update in transaction context run time * update spl-token to 0.6.1 * update ata to v1.1.3 --------- Co-authored-by: samkim-crypto <[email protected]>
Problem
Programs such as token-2022 depends on the zkp proof verification by the
ZkTokenProof
program. A token-2022 instruction such as the confidential transfer requires that the token-2022 instruction be accompanied by aZkTokenProof
program instruction that certifies that the token-2022 instruction data is valid.This setting can be quite limiting for certain use caes such as when a PDA must make a confidential transfer. A PDA cannot own an ElGamal private key, which is needed to create a zkp and submit a proof instruction.
For example, applications like a private escrow as specified in the SPL issue is not currently possible.
Summary of Changes
Extend the proof program so that users can optionally create a "zkp context state account".
ZkTokenProof
program, add the option to store the proof context information in an account. This account can only be created if the zero-knowledge proof verifies.ZkTokenProof
program, add aCloseContextState
instruction that closes the context state account by an authority.Token-22 Invocation by PDAs
The token-22 program should be updated so that for instructions such as a confidential transfer is accepted by the processor if one of the following conditions are met:
ZkTokenProof::Transfer
instruction is attached in the same transaction (as before)ZkTokenProof
TransferProofContext
account is specified in the set of instruction addressesThese changes allow a
ZkTokenProof
instruction to be processed in a separate transaction before a token-2022 instruction. This enables applications that require PDAs to invoke the token-2022 program by supplying a proof context state account.For example, consider the private escrow as specified in the SPL issue.
ZkTokenProof::Transfer
instruction to create a proof context state intended for the transfer of the tokens in the confidential extension account to the swap recipient (Bob) beforehand.ZkTokenProof
instruction itself, it will specify the proof context account that Alice previously created for the PDA.Processing Large Zkps by Chunks
The option to create proof context states also enables large zkps that can't fit into a single transaction to be processed in multiple instructions. For example, a confidential transfer proof is a combination of range proof, equality proof, and validity proof. Currently, these individual proofs are not exposed in the
ZkTokenProof
program, but if the program is updated to do so, then users can submit and create context accounts for smallerZkTokenProof::RangeProof
,ZkTokenProof::EqualityProof
, andZkTokenProof::ValidityProof
instructions. Then the token-22 could check the existence of these context state accounts and then approve the transfer.This may not be the fastest or the most UI friendly, but it could be one way to use the token-22 instructions before the transaction size limit is increased.