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