penumbra_sdk_app/action_handler/transaction/
stateless.rs

1use anyhow::{Context, Result};
2use penumbra_sdk_transaction::Transaction;
3use penumbra_sdk_txhash::AuthorizingData;
4
5#[tracing::instrument(skip(tx))]
6pub(super) fn valid_binding_signature(tx: &Transaction) -> Result<()> {
7    let auth_hash = tx.auth_hash();
8
9    tracing::debug!(bvk = ?tx.binding_verification_key(), ?auth_hash);
10
11    // Check binding signature.
12    tx.binding_verification_key()
13        .verify(auth_hash.as_bytes(), tx.binding_sig())
14        .context("binding signature failed to verify")
15}
16
17pub fn num_clues_equal_to_num_outputs(tx: &Transaction) -> anyhow::Result<()> {
18    if tx
19        .transaction_body()
20        .detection_data
21        .unwrap_or_default()
22        .fmd_clues
23        .len()
24        != tx.outputs().count()
25    {
26        Err(anyhow::anyhow!(
27            "consensus rule violated: must have equal number of outputs and FMD clues"
28        ))
29    } else {
30        Ok(())
31    }
32}
33
34#[allow(clippy::if_same_then_else)]
35pub fn check_memo_exists_if_outputs_absent_if_not(tx: &Transaction) -> anyhow::Result<()> {
36    let num_outputs = tx.outputs().count();
37    if num_outputs > 0 && tx.transaction_body().memo.is_none() {
38        Err(anyhow::anyhow!(
39            "consensus rule violated: must have memo if outputs present"
40        ))
41    } else if num_outputs > 0 && tx.transaction_body().memo.is_some() {
42        Ok(())
43    } else if num_outputs == 0 && tx.transaction_body().memo.is_none() {
44        Ok(())
45    } else {
46        Err(anyhow::anyhow!(
47            "consensus rule violated: cannot have memo if no outputs present"
48        ))
49    }
50}
51
52pub fn check_non_empty_transaction(tx: &Transaction) -> anyhow::Result<()> {
53    let num_actions = tx.actions().count();
54    if num_actions > 0 {
55        Ok(())
56    } else {
57        Err(anyhow::anyhow!(
58            "consensus rule violated: transaction must have more than 0 actions"
59        ))
60    }
61}