penumbra_sdk_shielded_pool/component/action_handler/
output.rs1use anyhow::Result;
2use async_trait::async_trait;
3use cnidarium::StateWrite;
4use cnidarium_component::ActionHandler;
5use penumbra_sdk_proof_params::OUTPUT_PROOF_VERIFICATION_KEY;
6use penumbra_sdk_proto::{DomainType as _, StateWriteProto as _};
7use penumbra_sdk_sct::component::source::SourceContext;
8
9use crate::{component::NoteManager, event, output::OutputProofPublic, Output};
10
11#[async_trait]
12impl ActionHandler for Output {
13 type CheckStatelessContext = ();
14 async fn check_stateless(&self, _context: ()) -> Result<()> {
15 let output = self;
16
17 output.proof.verify(
18 &OUTPUT_PROOF_VERIFICATION_KEY,
19 OutputProofPublic {
20 balance_commitment: output.body.balance_commitment,
21 note_commitment: output.body.note_payload.note_commitment,
22 },
23 )?;
24
25 Ok(())
26 }
27
28 async fn check_and_execute<S: StateWrite>(&self, mut state: S) -> Result<()> {
29 let source = state
30 .get_current_source()
31 .expect("source should be set during execution");
32
33 state
34 .add_note_payload(self.body.note_payload.clone(), source)
35 .await;
36
37 state.record_proto(
38 event::EventOutput {
39 note_commitment: self.body.note_payload.note_commitment,
40 }
41 .to_proto(),
42 );
43
44 Ok(())
45 }
46}