2021-09-21 12:26:05 -07:00
|
|
|
#![forbid(unsafe_code)]
|
|
|
|
|
|
|
|
|
|
use {
|
2021-09-21 19:58:14 -07:00
|
|
|
bytemuck::Pod,
|
2021-10-21 10:49:29 -07:00
|
|
|
solana_program_runtime::{ic_msg, invoke_context::InvokeContext},
|
2022-02-02 16:45:57 -08:00
|
|
|
solana_sdk::instruction::{InstructionError, TRANSACTION_LEVEL_STACK_HEIGHT},
|
2022-01-04 20:44:07 -08:00
|
|
|
solana_zk_token_sdk::zk_token_proof_instruction::*,
|
2021-09-21 12:26:05 -07:00
|
|
|
std::result::Result,
|
|
|
|
|
};
|
|
|
|
|
|
2021-09-21 19:58:14 -07:00
|
|
|
fn verify<T: Pod + Verifiable>(
|
|
|
|
|
input: &[u8],
|
2021-10-21 10:49:29 -07:00
|
|
|
invoke_context: &mut InvokeContext,
|
2021-09-21 19:58:14 -07:00
|
|
|
) -> Result<(), InstructionError> {
|
|
|
|
|
let proof = ProofInstruction::decode_data::<T>(input).ok_or_else(|| {
|
|
|
|
|
ic_msg!(invoke_context, "invalid proof data");
|
|
|
|
|
InstructionError::InvalidInstructionData
|
|
|
|
|
})?;
|
|
|
|
|
|
|
|
|
|
proof.verify().map_err(|err| {
|
|
|
|
|
ic_msg!(invoke_context, "proof verification failed: {:?}", err);
|
|
|
|
|
InstructionError::InvalidInstructionData
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-21 12:26:05 -07:00
|
|
|
pub fn process_instruction(
|
2021-10-21 10:49:29 -07:00
|
|
|
_first_instruction_account: usize,
|
2021-09-21 12:26:05 -07:00
|
|
|
input: &[u8],
|
2021-10-21 10:49:29 -07:00
|
|
|
invoke_context: &mut InvokeContext,
|
2021-09-21 12:26:05 -07:00
|
|
|
) -> Result<(), InstructionError> {
|
2022-02-02 16:45:57 -08:00
|
|
|
if invoke_context.get_stack_height() != TRANSACTION_LEVEL_STACK_HEIGHT {
|
2021-10-04 17:32:10 -07:00
|
|
|
// Not supported as an inner instruction
|
|
|
|
|
return Err(InstructionError::UnsupportedProgramId);
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-04 18:14:26 -07:00
|
|
|
// Consume compute units since proof verification is an expensive operation
|
|
|
|
|
{
|
|
|
|
|
let compute_meter = invoke_context.get_compute_meter();
|
2022-01-04 20:44:07 -08:00
|
|
|
// TODO: Tune the number of units consumed. The current value is just a rough estimate
|
|
|
|
|
compute_meter.borrow_mut().consume(100_000)?;
|
2021-10-04 18:14:26 -07:00
|
|
|
}
|
|
|
|
|
|
2021-10-21 10:49:29 -07:00
|
|
|
match ProofInstruction::decode_type(input).ok_or(InstructionError::InvalidInstructionData)? {
|
2021-09-21 19:58:14 -07:00
|
|
|
ProofInstruction::VerifyCloseAccount => {
|
|
|
|
|
ic_msg!(invoke_context, "VerifyCloseAccount");
|
|
|
|
|
verify::<CloseAccountData>(input, invoke_context)
|
2021-09-21 12:26:05 -07:00
|
|
|
}
|
2021-09-21 20:34:29 -07:00
|
|
|
ProofInstruction::VerifyWithdraw => {
|
|
|
|
|
ic_msg!(invoke_context, "VerifyWithdraw");
|
|
|
|
|
verify::<WithdrawData>(input, invoke_context)
|
|
|
|
|
}
|
2021-10-04 13:14:48 -07:00
|
|
|
ProofInstruction::VerifyTransfer => {
|
|
|
|
|
ic_msg!(invoke_context, "VerifyTransfer");
|
|
|
|
|
verify::<TransferData>(input, invoke_context)
|
2021-09-27 08:21:45 -07:00
|
|
|
}
|
2022-02-04 08:52:49 -05:00
|
|
|
ProofInstruction::VerifyTransferWithFee => {
|
|
|
|
|
ic_msg!(invoke_context, "VerifyTransferWithFee");
|
|
|
|
|
verify::<TransferWithFeeData>(input, invoke_context)
|
|
|
|
|
}
|
2021-09-21 12:26:05 -07:00
|
|
|
}
|
|
|
|
|
}
|