openzeppelin_relayer/queues/
swap_filter.rs1use crate::models::{RelayerNetworkPolicy, RelayerRepoModel};
2use tracing::debug;
3
4pub fn filter_relayers_for_swap(relayers: Vec<RelayerRepoModel>) -> Vec<RelayerRepoModel> {
6 relayers
7 .into_iter()
8 .filter(|relayer| match &relayer.policies {
9 RelayerNetworkPolicy::Solana(policy) => {
10 let swap_config = match policy.get_swap_config() {
11 Some(config) => config,
12 None => {
13 debug!(relayer_id = %relayer.id, "No Solana swap configuration specified; skipping");
14 return false;
15 }
16 };
17
18 if swap_config.cron_schedule.is_none() {
19 debug!(relayer_id = %relayer.id, "No cron schedule specified; skipping");
20 return false;
21 }
22 true
23 }
24 RelayerNetworkPolicy::Stellar(policy) => {
25 let swap_config = match policy.get_swap_config() {
26 Some(config) => config,
27 None => {
28 debug!(relayer_id = %relayer.id, "No Stellar swap configuration specified; skipping");
29 return false;
30 }
31 };
32
33 if swap_config.cron_schedule.is_none() {
34 debug!(relayer_id = %relayer.id, "No cron schedule specified; skipping");
35 return false;
36 }
37 true
38 }
39 _ => {
40 debug!(relayer_id = %relayer.id, "Network type does not support swap; skipping");
41 false
42 }
43 })
44 .collect()
45}
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50 use crate::models::{
51 RelayerSolanaPolicy, RelayerSolanaSwapConfig, RelayerStellarPolicy,
52 RelayerStellarSwapConfig,
53 };
54
55 fn solana_relayer_with_swap(id: &str, cron: Option<&str>) -> RelayerRepoModel {
56 RelayerRepoModel {
57 id: id.to_string(),
58 policies: RelayerNetworkPolicy::Solana(RelayerSolanaPolicy {
59 swap_config: Some(RelayerSolanaSwapConfig {
60 strategy: None,
61 cron_schedule: cron.map(String::from),
62 min_balance_threshold: None,
63 jupiter_swap_options: None,
64 }),
65 ..Default::default()
66 }),
67 ..Default::default()
68 }
69 }
70
71 fn solana_relayer_no_swap(id: &str) -> RelayerRepoModel {
72 RelayerRepoModel {
73 id: id.to_string(),
74 policies: RelayerNetworkPolicy::Solana(RelayerSolanaPolicy::default()),
75 ..Default::default()
76 }
77 }
78
79 fn stellar_relayer_with_swap(id: &str, cron: Option<&str>) -> RelayerRepoModel {
80 RelayerRepoModel {
81 id: id.to_string(),
82 policies: RelayerNetworkPolicy::Stellar(RelayerStellarPolicy {
83 swap_config: Some(RelayerStellarSwapConfig {
84 strategies: vec![],
85 cron_schedule: cron.map(String::from),
86 min_balance_threshold: None,
87 }),
88 ..Default::default()
89 }),
90 ..Default::default()
91 }
92 }
93
94 fn stellar_relayer_no_swap(id: &str) -> RelayerRepoModel {
95 RelayerRepoModel {
96 id: id.to_string(),
97 policies: RelayerNetworkPolicy::Stellar(RelayerStellarPolicy::default()),
98 ..Default::default()
99 }
100 }
101
102 fn evm_relayer(id: &str) -> RelayerRepoModel {
103 RelayerRepoModel {
104 id: id.to_string(),
105 ..Default::default() }
107 }
108
109 #[test]
110 fn test_empty_list_returns_empty() {
111 assert!(filter_relayers_for_swap(vec![]).is_empty());
112 }
113
114 #[test]
115 fn test_solana_with_swap_and_cron_included() {
116 let relayers = vec![solana_relayer_with_swap("sol-1", Some("0 0 * * * *"))];
117 let result = filter_relayers_for_swap(relayers);
118 assert_eq!(result.len(), 1);
119 assert_eq!(result[0].id, "sol-1");
120 }
121
122 #[test]
123 fn test_solana_with_swap_but_no_cron_excluded() {
124 let relayers = vec![solana_relayer_with_swap("sol-1", None)];
125 assert!(filter_relayers_for_swap(relayers).is_empty());
126 }
127
128 #[test]
129 fn test_solana_without_swap_config_excluded() {
130 let relayers = vec![solana_relayer_no_swap("sol-1")];
131 assert!(filter_relayers_for_swap(relayers).is_empty());
132 }
133
134 #[test]
135 fn test_stellar_with_swap_and_cron_included() {
136 let relayers = vec![stellar_relayer_with_swap("xlm-1", Some("0 */5 * * * *"))];
137 let result = filter_relayers_for_swap(relayers);
138 assert_eq!(result.len(), 1);
139 assert_eq!(result[0].id, "xlm-1");
140 }
141
142 #[test]
143 fn test_stellar_with_swap_but_no_cron_excluded() {
144 let relayers = vec![stellar_relayer_with_swap("xlm-1", None)];
145 assert!(filter_relayers_for_swap(relayers).is_empty());
146 }
147
148 #[test]
149 fn test_stellar_without_swap_config_excluded() {
150 let relayers = vec![stellar_relayer_no_swap("xlm-1")];
151 assert!(filter_relayers_for_swap(relayers).is_empty());
152 }
153
154 #[test]
155 fn test_evm_relayer_excluded() {
156 let relayers = vec![evm_relayer("evm-1")];
157 assert!(filter_relayers_for_swap(relayers).is_empty());
158 }
159
160 #[test]
161 fn test_mixed_list_filters_correctly() {
162 let relayers = vec![
163 solana_relayer_with_swap("sol-ok", Some("0 0 * * * *")),
164 solana_relayer_with_swap("sol-no-cron", None),
165 solana_relayer_no_swap("sol-no-swap"),
166 stellar_relayer_with_swap("xlm-ok", Some("0 0 * * * *")),
167 stellar_relayer_no_swap("xlm-no-swap"),
168 evm_relayer("evm-1"),
169 ];
170 let result = filter_relayers_for_swap(relayers);
171 let ids: Vec<&str> = result.iter().map(|r| r.id.as_str()).collect();
172 assert_eq!(ids, vec!["sol-ok", "xlm-ok"]);
173 }
174}