fuel_core_executor/
ports.rs

1use fuel_core_types::{
2    blockchain::{
3        header::ConsensusParametersVersion,
4        primitives::DaBlockHeight,
5    },
6    fuel_tx::{
7        self,
8        field::Expiration,
9        Chargeable,
10        ConsensusParameters,
11        Transaction,
12        TxId,
13        UniqueIdentifier,
14    },
15    fuel_types::{
16        BlockHeight,
17        ChainId,
18    },
19    fuel_vm::checked_transaction::CheckedTransaction,
20    services::{
21        executor::{
22            Error as ExecutorError,
23            Result as ExecutorResult,
24        },
25        relayer::Event,
26    },
27};
28
29#[cfg(feature = "alloc")]
30use alloc::{
31    string::ToString,
32    vec::Vec,
33};
34
35/// The wrapper around either `Transaction` or `CheckedTransaction`.
36#[allow(clippy::large_enum_variant)]
37pub enum MaybeCheckedTransaction {
38    CheckedTransaction(CheckedTransaction, ConsensusParametersVersion),
39    Transaction(fuel_tx::Transaction),
40}
41
42impl MaybeCheckedTransaction {
43    pub fn id(&self, chain_id: &ChainId) -> TxId {
44        match self {
45            MaybeCheckedTransaction::CheckedTransaction(
46                CheckedTransaction::Script(tx),
47                _,
48            ) => tx.id(),
49            MaybeCheckedTransaction::CheckedTransaction(
50                CheckedTransaction::Create(tx),
51                _,
52            ) => tx.id(),
53            MaybeCheckedTransaction::CheckedTransaction(
54                CheckedTransaction::Mint(tx),
55                _,
56            ) => tx.id(),
57            MaybeCheckedTransaction::CheckedTransaction(
58                CheckedTransaction::Upgrade(tx),
59                _,
60            ) => tx.id(),
61            MaybeCheckedTransaction::CheckedTransaction(
62                CheckedTransaction::Upload(tx),
63                _,
64            ) => tx.id(),
65            MaybeCheckedTransaction::CheckedTransaction(
66                CheckedTransaction::Blob(tx),
67                _,
68            ) => tx.id(),
69            MaybeCheckedTransaction::Transaction(tx) => tx.id(chain_id),
70        }
71    }
72
73    pub fn expiration(&self) -> BlockHeight {
74        match self {
75            MaybeCheckedTransaction::CheckedTransaction(
76                CheckedTransaction::Script(tx),
77                _,
78            ) => tx.transaction().expiration(),
79            MaybeCheckedTransaction::CheckedTransaction(
80                CheckedTransaction::Create(tx),
81                _,
82            ) => tx.transaction().expiration(),
83            MaybeCheckedTransaction::CheckedTransaction(
84                CheckedTransaction::Mint(_),
85                _,
86            ) => u32::MAX.into(),
87            MaybeCheckedTransaction::CheckedTransaction(
88                CheckedTransaction::Upgrade(tx),
89                _,
90            ) => tx.transaction().expiration(),
91            MaybeCheckedTransaction::CheckedTransaction(
92                CheckedTransaction::Upload(tx),
93                _,
94            ) => tx.transaction().expiration(),
95            MaybeCheckedTransaction::CheckedTransaction(
96                CheckedTransaction::Blob(tx),
97                _,
98            ) => tx.transaction().expiration(),
99            MaybeCheckedTransaction::Transaction(Transaction::Script(tx)) => {
100                tx.expiration()
101            }
102            MaybeCheckedTransaction::Transaction(Transaction::Create(tx)) => {
103                tx.expiration()
104            }
105            MaybeCheckedTransaction::Transaction(Transaction::Mint(_)) => u32::MAX.into(),
106            MaybeCheckedTransaction::Transaction(Transaction::Upgrade(tx)) => {
107                tx.expiration()
108            }
109            MaybeCheckedTransaction::Transaction(Transaction::Upload(tx)) => {
110                tx.expiration()
111            }
112            MaybeCheckedTransaction::Transaction(Transaction::Blob(tx)) => {
113                tx.expiration()
114            }
115        }
116    }
117}
118
119pub trait TransactionExt {
120    fn max_gas(&self, consensus_params: &ConsensusParameters) -> ExecutorResult<u64>;
121}
122
123impl TransactionExt for Transaction {
124    fn max_gas(&self, consensus_params: &ConsensusParameters) -> ExecutorResult<u64> {
125        let fee_params = consensus_params.fee_params();
126        let gas_costs = consensus_params.gas_costs();
127        match self {
128            Transaction::Script(tx) => Ok(tx.max_gas(gas_costs, fee_params)),
129            Transaction::Create(tx) => Ok(tx.max_gas(gas_costs, fee_params)),
130            Transaction::Mint(_) => Err(ExecutorError::Other(
131                "Mint transaction doesn't have max_gas".to_string(),
132            )),
133            Transaction::Upgrade(tx) => Ok(tx.max_gas(gas_costs, fee_params)),
134            Transaction::Upload(tx) => Ok(tx.max_gas(gas_costs, fee_params)),
135            Transaction::Blob(tx) => Ok(tx.max_gas(gas_costs, fee_params)),
136        }
137    }
138}
139
140impl TransactionExt for CheckedTransaction {
141    fn max_gas(&self, _: &ConsensusParameters) -> ExecutorResult<u64> {
142        match self {
143            CheckedTransaction::Script(tx) => Ok(tx.metadata().max_gas),
144            CheckedTransaction::Create(tx) => Ok(tx.metadata().max_gas),
145            CheckedTransaction::Mint(_) => Err(ExecutorError::Other(
146                "Mint transaction doesn't have max_gas".to_string(),
147            )),
148            CheckedTransaction::Upgrade(tx) => Ok(tx.metadata().max_gas),
149            CheckedTransaction::Upload(tx) => Ok(tx.metadata().max_gas),
150            CheckedTransaction::Blob(tx) => Ok(tx.metadata().max_gas),
151        }
152    }
153}
154
155impl TransactionExt for MaybeCheckedTransaction {
156    fn max_gas(&self, consensus_params: &ConsensusParameters) -> ExecutorResult<u64> {
157        match self {
158            MaybeCheckedTransaction::CheckedTransaction(tx, _) => {
159                tx.max_gas(consensus_params)
160            }
161            MaybeCheckedTransaction::Transaction(tx) => tx.max_gas(consensus_params),
162        }
163    }
164}
165
166pub trait TransactionsSource {
167    /// Returns the next batch of transactions to satisfy the `gas_limit` and `block_transaction_size_limit`.
168    /// The returned batch has at most `tx_count_limit` transactions, none
169    /// of which has a size in bytes greater than `size_limit`.
170    fn next(
171        &self,
172        gas_limit: u64,
173        tx_count_limit: u16,
174        block_transaction_size_limit: u32,
175    ) -> Vec<MaybeCheckedTransaction>;
176}
177
178pub trait RelayerPort {
179    /// Returns `true` if the relayer is enabled.
180    fn enabled(&self) -> bool;
181
182    /// Get events from the relayer at a given da height.
183    fn get_events(&self, da_height: &DaBlockHeight) -> anyhow::Result<Vec<Event>>;
184}