solomka_sdk/transaction/versioned/
sanitized.rs

1use {
2    super::VersionedTransaction,
3    crate::{sanitize::SanitizeError, signature::Signature},
4    solomka_program::message::SanitizedVersionedMessage,
5};
6
7/// Wraps a sanitized `VersionedTransaction` to provide a safe API
8#[derive(Clone, Debug, PartialEq, Eq)]
9pub struct SanitizedVersionedTransaction {
10    /// List of signatures
11    pub(crate) signatures: Vec<Signature>,
12    /// Message to sign.
13    pub(crate) message: SanitizedVersionedMessage,
14}
15
16impl TryFrom<VersionedTransaction> for SanitizedVersionedTransaction {
17    type Error = SanitizeError;
18    fn try_from(tx: VersionedTransaction) -> Result<Self, Self::Error> {
19        Self::try_new(tx)
20    }
21}
22
23impl SanitizedVersionedTransaction {
24    pub fn try_new(tx: VersionedTransaction) -> Result<Self, SanitizeError> {
25        tx.sanitize_signatures()?;
26        Ok(Self {
27            signatures: tx.signatures,
28            message: SanitizedVersionedMessage::try_from(tx.message)?,
29        })
30    }
31
32    pub fn get_message(&self) -> &SanitizedVersionedMessage {
33        &self.message
34    }
35}
36
37#[cfg(test)]
38mod tests {
39    use {
40        super::*,
41        solomka_program::{
42            hash::Hash,
43            message::{v0, VersionedMessage},
44            pubkey::Pubkey,
45        },
46    };
47
48    #[test]
49    fn test_try_new_with_invalid_signatures() {
50        let tx = VersionedTransaction {
51            signatures: vec![],
52            message: VersionedMessage::V0(
53                v0::Message::try_compile(&Pubkey::new_unique(), &[], &[], Hash::default()).unwrap(),
54            ),
55        };
56
57        assert_eq!(
58            SanitizedVersionedTransaction::try_new(tx),
59            Err(SanitizeError::IndexOutOfBounds)
60        );
61    }
62
63    #[test]
64    fn test_try_new() {
65        let mut message =
66            v0::Message::try_compile(&Pubkey::new_unique(), &[], &[], Hash::default()).unwrap();
67        message.header.num_readonly_signed_accounts += 1;
68
69        let tx = VersionedTransaction {
70            signatures: vec![Signature::default()],
71            message: VersionedMessage::V0(message),
72        };
73
74        assert_eq!(
75            SanitizedVersionedTransaction::try_new(tx),
76            Err(SanitizeError::InvalidValue)
77        );
78    }
79}