light_system_program/invoke/
verify_signer.rs

1use anchor_lang::{
2    err,
3    solana_program::{msg, pubkey::Pubkey},
4    Result,
5};
6
7use crate::{
8    errors::SystemProgramError, sdk::compressed_account::PackedCompressedAccountWithMerkleContext,
9};
10
11pub fn input_compressed_accounts_signer_check(
12    input_compressed_accounts_with_merkle_context: &[PackedCompressedAccountWithMerkleContext],
13    authority: &Pubkey,
14) -> Result<()> {
15    input_compressed_accounts_with_merkle_context
16        .iter()
17        .try_for_each(
18            |compressed_account_with_context: &PackedCompressedAccountWithMerkleContext| {
19                if compressed_account_with_context.compressed_account.owner == *authority
20                    && compressed_account_with_context
21                        .compressed_account
22                        .data
23                        .is_none()
24                {
25                    Ok(())
26                } else {
27                    msg!(
28                        "signer check failed compressed account owner {} != authority {} or data is not none {} (only programs can own compressed accounts with data)",
29                        compressed_account_with_context.compressed_account.owner,
30                        authority,
31                        compressed_account_with_context.compressed_account.data.is_none()
32                    );
33                    err!(SystemProgramError::SignerCheckFailed)
34                }
35            },
36        )
37}
38
39#[cfg(test)]
40mod test {
41    use super::*;
42    use crate::sdk::compressed_account::CompressedAccount;
43
44    #[test]
45    fn test_input_compressed_accounts_signer_check() {
46        let authority = Pubkey::new_unique();
47        let compressed_account_with_context = PackedCompressedAccountWithMerkleContext {
48            compressed_account: CompressedAccount {
49                owner: authority,
50                ..CompressedAccount::default()
51            },
52            ..PackedCompressedAccountWithMerkleContext::default()
53        };
54
55        assert_eq!(
56            input_compressed_accounts_signer_check(
57                &vec![compressed_account_with_context.clone()],
58                &authority
59            ),
60            Ok(())
61        );
62        let invalid_compressed_account_with_context = PackedCompressedAccountWithMerkleContext {
63            compressed_account: CompressedAccount {
64                owner: Pubkey::new_unique(),
65                ..CompressedAccount::default()
66            },
67            ..PackedCompressedAccountWithMerkleContext::default()
68        };
69        assert_eq!(
70            input_compressed_accounts_signer_check(
71                &vec![
72                    compressed_account_with_context,
73                    invalid_compressed_account_with_context
74                ],
75                &authority
76            ),
77            Err(SystemProgramError::SignerCheckFailed.into())
78        );
79    }
80}