penumbra_sdk_shielded_pool/component/action_handler/
output.rs

1use 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}