1use std::{
2 collections::HashSet,
3 time::Duration,
4};
5
6use fuel_core_types::{
7 fuel_tx::{
8 Address,
9 ContractId,
10 Input,
11 UtxoId,
12 input::{
13 coin::{
14 CoinPredicate,
15 CoinSigned,
16 },
17 message::{
18 MessageCoinPredicate,
19 MessageCoinSigned,
20 MessageDataPredicate,
21 MessageDataSigned,
22 },
23 },
24 },
25 fuel_types::Nonce,
26 services::txpool::PoolTransaction,
27};
28
29use crate::error::BlacklistedError;
30
31#[derive(Default, Debug, Clone, PartialEq, Eq)]
32pub struct BlackList {
33 pub owners: HashSet<Address>,
35 pub coins: HashSet<UtxoId>,
37 pub messages: HashSet<Nonce>,
39 pub contracts: HashSet<ContractId>,
41}
42
43impl BlackList {
44 pub fn new(
46 owners: Vec<Address>,
47 utxo_ids: Vec<UtxoId>,
48 messages: Vec<Nonce>,
49 contracts: Vec<ContractId>,
50 ) -> Self {
51 Self {
52 owners: owners.into_iter().collect(),
53 coins: utxo_ids.into_iter().collect(),
54 messages: messages.into_iter().collect(),
55 contracts: contracts.into_iter().collect(),
56 }
57 }
58
59 pub fn check_blacklisting(
61 &self,
62 tx: &PoolTransaction,
63 ) -> Result<(), BlacklistedError> {
64 for input in tx.inputs() {
65 match input {
66 Input::CoinSigned(CoinSigned { utxo_id, owner, .. })
67 | Input::CoinPredicate(CoinPredicate { utxo_id, owner, .. }) => {
68 if self.coins.contains(utxo_id) {
69 return Err(BlacklistedError::BlacklistedUTXO(*utxo_id));
70 }
71 if self.owners.contains(owner) {
72 return Err(BlacklistedError::BlacklistedOwner(*owner));
73 }
74 }
75 Input::Contract(contract) => {
76 if self.contracts.contains(&contract.contract_id) {
77 return Err(BlacklistedError::BlacklistedContract(
78 contract.contract_id,
79 ));
80 }
81 }
82 Input::MessageCoinSigned(MessageCoinSigned {
83 nonce,
84 sender,
85 recipient,
86 ..
87 })
88 | Input::MessageCoinPredicate(MessageCoinPredicate {
89 nonce,
90 sender,
91 recipient,
92 ..
93 })
94 | Input::MessageDataSigned(MessageDataSigned {
95 nonce,
96 sender,
97 recipient,
98 ..
99 })
100 | Input::MessageDataPredicate(MessageDataPredicate {
101 nonce,
102 sender,
103 recipient,
104 ..
105 }) => {
106 if self.messages.contains(nonce) {
107 return Err(BlacklistedError::BlacklistedMessage(*nonce));
108 }
109 if self.owners.contains(sender) {
110 return Err(BlacklistedError::BlacklistedOwner(*sender));
111 }
112 if self.owners.contains(recipient) {
113 return Err(BlacklistedError::BlacklistedOwner(*recipient));
114 }
115 }
116 }
117 }
118
119 Ok(())
120 }
121}
122
123#[derive(Clone, Debug)]
124pub struct Config {
125 pub utxo_validation: bool,
127 pub allow_syscall: bool,
129 pub max_txs_chain_count: usize,
131 pub pool_limits: PoolLimits,
133 pub service_channel_limits: ServiceChannelLimits,
135 pub ttl_check_interval: Duration,
137 pub max_txs_ttl: Duration,
139 pub heavy_work: HeavyWorkConfig,
141 pub black_list: BlackList,
143 pub pending_pool_tx_ttl: Duration,
145 pub max_pending_pool_size_percentage: u16,
147 pub metrics: bool,
149}
150
151#[derive(Clone, Debug)]
152pub struct PoolLimits {
153 pub max_txs: usize,
155 pub max_gas: u64,
157 pub max_bytes_size: usize,
159}
160
161#[derive(Clone, Copy, Debug)]
162pub struct ServiceChannelLimits {
163 pub max_pending_write_pool_requests: usize,
165 pub max_pending_read_pool_requests: usize,
167}
168
169#[derive(Clone, Debug)]
170pub struct HeavyWorkConfig {
171 pub number_threads_to_verify_transactions: usize,
173 pub size_of_verification_queue: usize,
175 pub number_threads_p2p_sync: usize,
177 pub size_of_p2p_sync_queue: usize,
179}
180
181#[cfg(feature = "test-helpers")]
182impl Default for Config {
183 fn default() -> Self {
184 Self {
185 utxo_validation: true,
186 allow_syscall: true,
187 max_txs_chain_count: 50,
188 ttl_check_interval: Duration::from_secs(60),
189 max_txs_ttl: Duration::from_secs(60 * 10),
190 black_list: BlackList::default(),
191 pool_limits: PoolLimits {
192 max_txs: 10000,
193 max_gas: 100_000_000_000,
194 max_bytes_size: 1_000_000_000,
195 },
196 heavy_work: HeavyWorkConfig {
197 number_threads_to_verify_transactions: 0,
200 size_of_verification_queue: 100,
201 number_threads_p2p_sync: 0,
202 size_of_p2p_sync_queue: 100,
203 },
204 service_channel_limits: ServiceChannelLimits {
205 max_pending_write_pool_requests: 1000,
206 max_pending_read_pool_requests: 1000,
207 },
208 pending_pool_tx_ttl: Duration::from_secs(3),
209 max_pending_pool_size_percentage: 50,
210 metrics: false,
211 }
212 }
213}