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)]
28pub struct TxSkeleton {
29 pub root: BlsScalar,
32 pub nullifiers: Vec<BlsScalar>,
34 pub outputs: [Note; OUTPUT_NOTES],
36 pub max_fee: u64,
38 pub deposit: u64,
40}
41
42impl TxSkeleton {
43 #[must_use]
45 pub fn to_hash_input_bytes(&self) -> Vec<u8> {
46 let mut bytes = Vec::new();
47
48 bytes.extend(self.root.to_bytes());
49
50 for nullifier in &self.nullifiers {
51 bytes.extend(nullifier.to_bytes());
52 }
53 for note in &self.outputs {
54 bytes.extend(note.to_bytes());
55 }
56
57 bytes.extend(self.max_fee.to_bytes());
58 bytes.extend(self.deposit.to_bytes());
59
60 bytes
61 }
62
63 #[allow(unused_must_use)]
65 pub fn to_var_bytes(&self) -> Vec<u8> {
66 let mut bytes = Vec::new();
67
68 bytes.extend(self.root.to_bytes());
69
70 let num_nullifiers = self.nullifiers.len() as u64;
71 bytes.extend(num_nullifiers.to_bytes());
72 self.nullifiers.iter().for_each(|nullifier| {
73 bytes.extend(nullifier.to_bytes());
74 });
75
76 self.outputs.iter().for_each(|note| {
77 bytes.extend(note.to_bytes());
78 });
79
80 bytes.extend(self.max_fee.to_bytes());
81 bytes.extend(self.deposit.to_bytes());
82
83 bytes
84 }
85
86 pub fn from_slice(buf: &[u8]) -> Result<Self, BytesError> {
88 let mut buffer = buf;
89 let root = BlsScalar::from_reader(&mut buffer)?;
90
91 let num_nullifiers = u64::from_reader(&mut buffer)?;
92 let mut nullifiers = Vec::with_capacity(num_nullifiers as usize);
93 for _ in 0..num_nullifiers {
94 nullifiers.push(BlsScalar::from_reader(&mut buffer)?);
95 }
96
97 let mut outputs = Vec::with_capacity(OUTPUT_NOTES);
98 for _ in 0..OUTPUT_NOTES {
99 outputs.push(Note::from_reader(&mut buffer)?);
100 }
101 let outputs: [Note; OUTPUT_NOTES] =
102 outputs.try_into().map_err(|_| BytesError::InvalidData)?;
103
104 let max_fee = u64::from_reader(&mut buffer)?;
105 let deposit = u64::from_reader(&mut buffer)?;
106
107 Ok(Self {
108 root,
109 nullifiers,
110 outputs,
111 max_fee,
112 deposit,
113 })
114 }
115
116 pub fn nullifiers(&self) -> &[BlsScalar] {
118 &self.nullifiers
119 }
120
121 pub fn outputs(&self) -> &[Note] {
123 &self.outputs
124 }
125
126 pub fn max_fee(&self) -> u64 {
128 self.max_fee
129 }
130
131 pub fn deposit(&self) -> u64 {
133 self.deposit
134 }
135}