phoenix_core/
transaction.rs1extern crate alloc;
11use alloc::vec::Vec;
12
13#[cfg(feature = "rkyv-impl")]
14use rkyv::{Archive, Deserialize, Serialize};
15
16use dusk_bls12_381::BlsScalar;
17use dusk_bytes::{DeserializableSlice, Error as BytesError, Serializable};
18
19use crate::{Note, OUTPUT_NOTES};
20
21#[derive(Debug, Clone, PartialEq, Eq)]
23#[cfg_attr(
24 feature = "rkyv-impl",
25 derive(Archive, Serialize, Deserialize),
26 archive_attr(derive(bytecheck::CheckBytes))
27)]
28#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
29pub struct TxSkeleton {
30 pub root: BlsScalar,
33 pub nullifiers: Vec<BlsScalar>,
35 pub outputs: [Note; OUTPUT_NOTES],
37 #[cfg_attr(
39 feature = "serde",
40 serde(with = "serde_with::As::<serde_with::DisplayFromStr>")
41 )]
42 pub max_fee: u64,
43 #[cfg_attr(
45 feature = "serde",
46 serde(with = "serde_with::As::<serde_with::DisplayFromStr>")
47 )]
48 pub deposit: u64,
49}
50
51impl TxSkeleton {
52 #[must_use]
54 pub fn to_hash_input_bytes(&self) -> Vec<u8> {
55 let mut bytes = Vec::new();
56
57 bytes.extend(self.root.to_bytes());
58
59 for nullifier in &self.nullifiers {
60 bytes.extend(nullifier.to_bytes());
61 }
62 for note in &self.outputs {
63 bytes.extend(note.to_bytes());
64 }
65
66 bytes.extend(self.max_fee.to_bytes());
67 bytes.extend(self.deposit.to_bytes());
68
69 bytes
70 }
71
72 #[allow(unused_must_use)]
74 pub fn to_var_bytes(&self) -> Vec<u8> {
75 let mut bytes = Vec::new();
76
77 bytes.extend(self.root.to_bytes());
78
79 let num_nullifiers = self.nullifiers.len() as u64;
80 bytes.extend(num_nullifiers.to_bytes());
81 self.nullifiers.iter().for_each(|nullifier| {
82 bytes.extend(nullifier.to_bytes());
83 });
84
85 self.outputs.iter().for_each(|note| {
86 bytes.extend(note.to_bytes());
87 });
88
89 bytes.extend(self.max_fee.to_bytes());
90 bytes.extend(self.deposit.to_bytes());
91
92 bytes
93 }
94
95 pub fn from_slice(buf: &[u8]) -> Result<Self, BytesError> {
97 let mut buffer = buf;
98 let root = BlsScalar::from_reader(&mut buffer)?;
99
100 let num_nullifiers = u64::from_reader(&mut buffer)?;
101 let mut nullifiers = Vec::with_capacity(num_nullifiers as usize);
102 for _ in 0..num_nullifiers {
103 nullifiers.push(BlsScalar::from_reader(&mut buffer)?);
104 }
105
106 let mut outputs = Vec::with_capacity(OUTPUT_NOTES);
107 for _ in 0..OUTPUT_NOTES {
108 outputs.push(Note::from_reader(&mut buffer)?);
109 }
110 let outputs: [Note; OUTPUT_NOTES] =
111 outputs.try_into().map_err(|_| BytesError::InvalidData)?;
112
113 let max_fee = u64::from_reader(&mut buffer)?;
114 let deposit = u64::from_reader(&mut buffer)?;
115
116 Ok(Self {
117 root,
118 nullifiers,
119 outputs,
120 max_fee,
121 deposit,
122 })
123 }
124
125 pub fn nullifiers(&self) -> &[BlsScalar] {
127 &self.nullifiers
128 }
129
130 pub fn outputs(&self) -> &[Note] {
132 &self.outputs
133 }
134
135 pub fn max_fee(&self) -> u64 {
137 self.max_fee
138 }
139
140 pub fn deposit(&self) -> u64 {
142 self.deposit
143 }
144}