fuels_types/
transaction.rs

1use std::fmt::Debug;
2
3use fuel_tx::{
4    field::{
5        GasLimit, GasPrice, Inputs, Maturity, Outputs, Script as ScriptField, ScriptData, Witnesses,
6    },
7    Bytes32, Chargeable, ConsensusParameters, Create, FormatValidityChecks, Input as FuelInput,
8    Output, Salt as FuelSalt, Script, StorageSlot, Transaction as FuelTransaction, TransactionFee,
9    UniqueIdentifier, Witness,
10};
11
12use crate::{
13    constants::{DEFAULT_GAS_LIMIT, DEFAULT_GAS_PRICE, DEFAULT_MATURITY},
14    errors::Error,
15};
16
17#[derive(Debug, Copy, Clone)]
18pub struct TxParameters {
19    gas_price: u64,
20    gas_limit: u64,
21    maturity: u32,
22}
23
24macro_rules! impl_setter_getter {
25    ($setter_name: ident, $field: ident, $ty: ty) => {
26        pub fn $setter_name(mut self, $field: $ty) -> Self {
27            self.$field = $field;
28            self
29        }
30
31        pub fn $field(&self) -> $ty {
32            self.$field
33        }
34    };
35}
36
37impl TxParameters {
38    pub fn new(gas_price: u64, gas_limit: u64, maturity: u32) -> Self {
39        Self {
40            gas_price,
41            gas_limit,
42            maturity,
43        }
44    }
45
46    impl_setter_getter!(set_gas_price, gas_price, u64);
47    impl_setter_getter!(set_gas_limit, gas_limit, u64);
48    impl_setter_getter!(set_maturity, maturity, u32);
49}
50
51impl Default for TxParameters {
52    fn default() -> Self {
53        Self {
54            gas_price: DEFAULT_GAS_PRICE,
55            gas_limit: DEFAULT_GAS_LIMIT,
56            // By default, transaction is immediately valid
57            maturity: DEFAULT_MATURITY,
58        }
59    }
60}
61use fuel_tx::field::{BytecodeLength, BytecodeWitnessIndex, Salt, StorageSlots};
62
63pub trait Transaction: Into<FuelTransaction> + Send {
64    fn fee_checked_from_tx(&self, params: &ConsensusParameters) -> Option<TransactionFee>;
65
66    fn check_without_signatures(
67        &self,
68        block_height: u32,
69        parameters: &ConsensusParameters,
70    ) -> Result<(), Error>;
71
72    fn id(&self, params: &ConsensusParameters) -> Bytes32;
73
74    fn maturity(&self) -> u32;
75
76    fn with_maturity(self, maturity: u32) -> Self;
77
78    fn gas_price(&self) -> u64;
79
80    fn with_gas_price(self, gas_price: u64) -> Self;
81
82    fn gas_limit(&self) -> u64;
83
84    fn with_gas_limit(self, gas_price: u64) -> Self;
85
86    fn with_tx_params(self, tx_params: TxParameters) -> Self;
87
88    fn metered_bytes_size(&self) -> usize;
89
90    fn inputs(&self) -> &Vec<FuelInput>;
91
92    fn outputs(&self) -> &Vec<Output>;
93
94    fn witnesses(&self) -> &Vec<Witness>;
95
96    fn witnesses_mut(&mut self) -> &mut Vec<Witness>;
97
98    fn with_witnesses(self, witnesses: Vec<Witness>) -> Self;
99}
100
101macro_rules! impl_tx_wrapper {
102    ($wrapper: ident, $wrapped: ident) => {
103        #[derive(Debug, Clone)]
104        pub struct $wrapper {
105            pub tx: $wrapped,
106        }
107
108        impl From<$wrapped> for $wrapper {
109            fn from(tx: $wrapped) -> Self {
110                $wrapper { tx }
111            }
112        }
113
114        impl Default for $wrapper {
115            fn default() -> Self {
116                $wrapped::default().into()
117            }
118        }
119
120        impl From<$wrapper> for $wrapped {
121            fn from(tx: $wrapper) -> Self {
122                tx.tx
123            }
124        }
125
126        impl From<$wrapper> for FuelTransaction {
127            fn from(tx: $wrapper) -> Self {
128                tx.tx.into()
129            }
130        }
131
132        impl Transaction for $wrapper {
133            fn fee_checked_from_tx(&self, params: &ConsensusParameters) -> Option<TransactionFee> {
134                TransactionFee::checked_from_tx(params, &self.tx)
135            }
136
137            fn check_without_signatures(
138                &self,
139                block_height: u32,
140                parameters: &ConsensusParameters,
141            ) -> Result<(), Error> {
142                Ok(self
143                    .tx
144                    .check_without_signatures(block_height.into(), parameters)?)
145            }
146
147            fn id(&self, params: &ConsensusParameters) -> Bytes32 {
148                self.tx.id(params)
149            }
150
151            fn maturity(&self) -> u32 {
152                (*self.tx.maturity()).into()
153            }
154
155            fn with_maturity(mut self, maturity: u32) -> Self {
156                *self.tx.maturity_mut() = maturity.into();
157                self
158            }
159
160            fn gas_price(&self) -> u64 {
161                *self.tx.gas_price()
162            }
163
164            fn with_gas_price(mut self, gas_price: u64) -> Self {
165                *self.tx.gas_price_mut() = gas_price;
166                self
167            }
168
169            fn gas_limit(&self) -> u64 {
170                *self.tx.gas_limit()
171            }
172
173            fn with_gas_limit(mut self, gas_limit: u64) -> Self {
174                *self.tx.gas_limit_mut() = gas_limit;
175                self
176            }
177
178            fn with_tx_params(self, tx_params: TxParameters) -> Self {
179                self.with_gas_limit(tx_params.gas_limit)
180                    .with_gas_price(tx_params.gas_price)
181                    .with_maturity(tx_params.maturity)
182            }
183
184            fn metered_bytes_size(&self) -> usize {
185                self.tx.metered_bytes_size()
186            }
187
188            fn inputs(&self) -> &Vec<FuelInput> {
189                self.tx.inputs()
190            }
191
192            fn outputs(&self) -> &Vec<Output> {
193                self.tx.outputs()
194            }
195
196            fn witnesses(&self) -> &Vec<Witness> {
197                self.tx.witnesses()
198            }
199
200            fn witnesses_mut(&mut self) -> &mut Vec<Witness> {
201                self.tx.witnesses_mut()
202            }
203
204            fn with_witnesses(mut self, witnesses: Vec<Witness>) -> Self {
205                *self.tx.witnesses_mut() = witnesses;
206                self
207            }
208        }
209    };
210}
211
212impl_tx_wrapper!(ScriptTransaction, Script);
213impl_tx_wrapper!(CreateTransaction, Create);
214
215impl CreateTransaction {
216    pub fn salt(&self) -> &FuelSalt {
217        self.tx.salt()
218    }
219
220    pub fn bytecode_witness_index(&self) -> u8 {
221        *self.tx.bytecode_witness_index()
222    }
223
224    pub fn storage_slots(&self) -> &Vec<StorageSlot> {
225        self.tx.storage_slots()
226    }
227
228    pub fn bytecode_length(&self) -> u64 {
229        *self.tx.bytecode_length()
230    }
231}
232
233impl ScriptTransaction {
234    pub fn script(&self) -> &Vec<u8> {
235        self.tx.script()
236    }
237    pub fn script_data(&self) -> &Vec<u8> {
238        self.tx.script_data()
239    }
240}