fuel_core_executor/
ports.rs

1use fuel_core_types::{
2    blockchain::{
3        header::ConsensusParametersVersion,
4        primitives::DaBlockHeight,
5        transaction::TransactionExt,
6    },
7    fuel_tx::{
8        self,
9        ConsensusParameters,
10        Input,
11        Output,
12        Transaction,
13        TxId,
14        UniqueIdentifier,
15        field::Expiration,
16    },
17    fuel_types::{
18        BlockHeight,
19        ChainId,
20    },
21    fuel_vm::checked_transaction::CheckedTransaction,
22    services::{
23        executor::Result as ExecutorResult,
24        preconfirmation::Preconfirmation,
25        relayer::Event,
26    },
27};
28
29use crate::executor::WaitNewTransactionsResult;
30
31#[cfg(all(feature = "alloc", not(feature = "std")))]
32use alloc::{
33    borrow::Cow,
34    vec::Vec,
35};
36
37#[cfg(feature = "std")]
38use std::borrow::Cow;
39
40use core::future::Future;
41
42/// The wrapper around either `Transaction` or `CheckedTransaction`.
43#[allow(clippy::large_enum_variant)]
44#[derive(Debug)]
45pub enum MaybeCheckedTransaction {
46    CheckedTransaction(CheckedTransaction, ConsensusParametersVersion),
47    Transaction(fuel_tx::Transaction),
48}
49
50impl MaybeCheckedTransaction {
51    pub fn id(&self, chain_id: &ChainId) -> TxId {
52        match self {
53            MaybeCheckedTransaction::CheckedTransaction(
54                CheckedTransaction::Script(tx),
55                _,
56            ) => tx.id(),
57            MaybeCheckedTransaction::CheckedTransaction(
58                CheckedTransaction::Create(tx),
59                _,
60            ) => tx.id(),
61            MaybeCheckedTransaction::CheckedTransaction(
62                CheckedTransaction::Mint(tx),
63                _,
64            ) => tx.id(),
65            MaybeCheckedTransaction::CheckedTransaction(
66                CheckedTransaction::Upgrade(tx),
67                _,
68            ) => tx.id(),
69            MaybeCheckedTransaction::CheckedTransaction(
70                CheckedTransaction::Upload(tx),
71                _,
72            ) => tx.id(),
73            MaybeCheckedTransaction::CheckedTransaction(
74                CheckedTransaction::Blob(tx),
75                _,
76            ) => tx.id(),
77            MaybeCheckedTransaction::Transaction(tx) => tx.id(chain_id),
78        }
79    }
80
81    pub fn expiration(&self) -> BlockHeight {
82        match self {
83            MaybeCheckedTransaction::CheckedTransaction(
84                CheckedTransaction::Script(tx),
85                _,
86            ) => tx.transaction().expiration(),
87            MaybeCheckedTransaction::CheckedTransaction(
88                CheckedTransaction::Create(tx),
89                _,
90            ) => tx.transaction().expiration(),
91            MaybeCheckedTransaction::CheckedTransaction(
92                CheckedTransaction::Mint(_),
93                _,
94            ) => u32::MAX.into(),
95            MaybeCheckedTransaction::CheckedTransaction(
96                CheckedTransaction::Upgrade(tx),
97                _,
98            ) => tx.transaction().expiration(),
99            MaybeCheckedTransaction::CheckedTransaction(
100                CheckedTransaction::Upload(tx),
101                _,
102            ) => tx.transaction().expiration(),
103            MaybeCheckedTransaction::CheckedTransaction(
104                CheckedTransaction::Blob(tx),
105                _,
106            ) => tx.transaction().expiration(),
107            MaybeCheckedTransaction::Transaction(Transaction::Script(tx)) => {
108                tx.expiration()
109            }
110            MaybeCheckedTransaction::Transaction(Transaction::Create(tx)) => {
111                tx.expiration()
112            }
113            MaybeCheckedTransaction::Transaction(Transaction::Mint(_)) => u32::MAX.into(),
114            MaybeCheckedTransaction::Transaction(Transaction::Upgrade(tx)) => {
115                tx.expiration()
116            }
117            MaybeCheckedTransaction::Transaction(Transaction::Upload(tx)) => {
118                tx.expiration()
119            }
120            MaybeCheckedTransaction::Transaction(Transaction::Blob(tx)) => {
121                tx.expiration()
122            }
123        }
124    }
125}
126
127impl TransactionExt for MaybeCheckedTransaction {
128    fn inputs(&self) -> Cow<'_, [Input]> {
129        match self {
130            MaybeCheckedTransaction::CheckedTransaction(tx, _) => tx.inputs(),
131            MaybeCheckedTransaction::Transaction(tx) => tx.inputs(),
132        }
133    }
134
135    fn outputs(&self) -> Cow<'_, [Output]> {
136        match self {
137            MaybeCheckedTransaction::CheckedTransaction(tx, _) => tx.outputs(),
138            MaybeCheckedTransaction::Transaction(tx) => tx.outputs(),
139        }
140    }
141
142    fn max_gas(&self, consensus_params: &ConsensusParameters) -> ExecutorResult<u64> {
143        match self {
144            MaybeCheckedTransaction::CheckedTransaction(tx, _) => {
145                tx.max_gas(consensus_params)
146            }
147            MaybeCheckedTransaction::Transaction(tx) => tx.max_gas(consensus_params),
148        }
149    }
150}
151
152pub trait TransactionsSource {
153    /// Returns the next batch of transactions to satisfy the `gas_limit` and `block_transaction_size_limit`.
154    /// The returned batch has at most `tx_count_limit` transactions, none
155    /// of which has a size in bytes greater than `size_limit`.
156    fn next(
157        &self,
158        gas_limit: u64,
159        tx_count_limit: u16,
160        block_transaction_size_limit: u32,
161    ) -> Vec<MaybeCheckedTransaction>;
162}
163
164pub trait RelayerPort {
165    /// Returns `true` if the relayer is enabled.
166    fn enabled(&self) -> bool;
167
168    /// Get events from the relayer at a given da height.
169    fn get_events(&self, da_height: &DaBlockHeight) -> anyhow::Result<Vec<Event>>;
170}
171
172/// Send to the block executor to know if there is new transactions available
173/// to include in the block or if we are good to end the block execution.
174pub trait NewTxWaiterPort: Send {
175    /// Wait for new transactions to be available or timeout.
176    fn wait_for_new_transactions(
177        &mut self,
178    ) -> impl Future<Output = WaitNewTransactionsResult> + Send;
179}
180
181/// Sending preconfirmation of transactions executed to other services.
182pub trait PreconfirmationSenderPort {
183    /// Try to send a batch of pre-confirmations. Will succeed only if
184    /// it can be directly sent. Otherwise it will return the batch.
185    fn try_send(&self, preconfirmations: Vec<Preconfirmation>) -> Vec<Preconfirmation>;
186
187    /// Send a batch of pre-confirmations, awaiting for the send to be successful.
188    fn send(
189        &self,
190        preconfirmations: Vec<Preconfirmation>,
191    ) -> impl Future<Output = ()> + Send;
192}