|
1 | 1 | use actix_web::{web, App, HttpResponse, HttpServer, Responder};
|
2 | 2 | use alloy::primitives::{hex, Address};
|
3 | 3 | use alloy::signers::Signer;
|
| 4 | +use anyhow::{Context, Result}; |
4 | 5 | use clap::Parser;
|
5 | 6 | use log::LevelFilter;
|
6 | 7 | use log::{error, info};
|
@@ -64,71 +65,103 @@ fn main() {
|
64 | 65 | .with_compute_pool()
|
65 | 66 | .build()
|
66 | 67 | .unwrap();
|
67 |
| - |
68 | 68 | loop {
|
69 |
| - async fn _generate_signature( |
70 |
| - wallet: &Wallet, |
71 |
| - message: &str, |
72 |
| - ) -> Result<String, Box<dyn std::error::Error>> { |
| 69 | + async fn _generate_signature(wallet: &Wallet, message: &str) -> Result<String> { |
73 | 70 | let signature = wallet
|
74 | 71 | .signer
|
75 | 72 | .sign_message(message.as_bytes())
|
76 |
| - .await? |
| 73 | + .await |
| 74 | + .context("Failed to sign message")? |
77 | 75 | .as_bytes();
|
78 | 76 | Ok(format!("0x{}", hex::encode(signature)))
|
79 | 77 | }
|
80 | 78 |
|
81 |
| - let nodes: Result<Vec<DiscoveryNode>, Box<dyn std::error::Error>> = |
82 |
| - runtime.block_on(async { |
83 |
| - let discovery_route = "/api/validator"; |
84 |
| - let address = validator_wallet |
85 |
| - .wallet |
86 |
| - .default_signer() |
87 |
| - .address() |
88 |
| - .to_string(); |
89 |
| - let signature = _generate_signature(&validator_wallet, discovery_route) |
90 |
| - .await |
91 |
| - .unwrap(); |
92 |
| - |
93 |
| - let mut headers = reqwest::header::HeaderMap::new(); |
94 |
| - headers.insert("x-address", address.parse().unwrap()); |
95 |
| - headers.insert("x-signature", signature.parse().unwrap()); |
96 |
| - |
97 |
| - info!("Fetching nodes from: {}{}", discovery_url, discovery_route); |
98 |
| - let response = reqwest::Client::new() |
99 |
| - .get(format!("{}{}", discovery_url, discovery_route)) |
100 |
| - .headers(headers) |
101 |
| - .send() |
102 |
| - .await?; |
103 |
| - |
104 |
| - let response_text = response.text().await?; |
105 |
| - let parsed_response: ApiResponse<Vec<DiscoveryNode>> = |
106 |
| - serde_json::from_str(&response_text)?; |
107 |
| - |
108 |
| - if !parsed_response.success { |
109 |
| - error!("Failed to fetch nodes: {:?}", parsed_response); |
110 |
| - return Ok(vec![]); |
111 |
| - } |
| 79 | + let nodes = match runtime.block_on(async { |
| 80 | + let discovery_route = "/api/validator"; |
| 81 | + let address = validator_wallet |
| 82 | + .wallet |
| 83 | + .default_signer() |
| 84 | + .address() |
| 85 | + .to_string(); |
| 86 | + |
| 87 | + let signature = _generate_signature(&validator_wallet, discovery_route) |
| 88 | + .await |
| 89 | + .context("Failed to generate signature")?; |
| 90 | + |
| 91 | + let mut headers = reqwest::header::HeaderMap::new(); |
| 92 | + headers.insert( |
| 93 | + "x-address", |
| 94 | + reqwest::header::HeaderValue::from_str(&address) |
| 95 | + .context("Failed to create address header")?, |
| 96 | + ); |
| 97 | + headers.insert( |
| 98 | + "x-signature", |
| 99 | + reqwest::header::HeaderValue::from_str(&signature) |
| 100 | + .context("Failed to create signature header")?, |
| 101 | + ); |
| 102 | + |
| 103 | + info!("Fetching nodes from: {}{}", discovery_url, discovery_route); |
| 104 | + let response = reqwest::Client::new() |
| 105 | + .get(format!("{}{}", discovery_url, discovery_route)) |
| 106 | + .headers(headers) |
| 107 | + .send() |
| 108 | + .await |
| 109 | + .context("Failed to fetch nodes")?; |
| 110 | + |
| 111 | + let response_text = response |
| 112 | + .text() |
| 113 | + .await |
| 114 | + .context("Failed to get response text")?; |
| 115 | + |
| 116 | + let parsed_response: ApiResponse<Vec<DiscoveryNode>> = |
| 117 | + serde_json::from_str(&response_text).context("Failed to parse response")?; |
| 118 | + |
| 119 | + if !parsed_response.success { |
| 120 | + error!("Failed to fetch nodes: {:?}", parsed_response); |
| 121 | + return Ok::<Vec<DiscoveryNode>, anyhow::Error>(vec![]); |
| 122 | + } |
| 123 | + |
| 124 | + Ok(parsed_response.data) |
| 125 | + }) { |
| 126 | + Ok(n) => n, |
| 127 | + Err(e) => { |
| 128 | + error!("Error in node fetching loop: {:#}", e); |
| 129 | + std::thread::sleep(std::time::Duration::from_secs(10)); |
| 130 | + continue; |
| 131 | + } |
| 132 | + }; |
112 | 133 |
|
113 |
| - Ok(parsed_response.data) |
114 |
| - }); |
115 | 134 | let non_validated_nodes: Vec<DiscoveryNode> = nodes
|
116 | 135 | .iter()
|
117 |
| - .flatten() |
118 | 136 | .filter(|node| !node.is_validated)
|
119 | 137 | .cloned()
|
120 | 138 | .collect();
|
121 | 139 |
|
122 | 140 | info!("Non validated nodes: {:?}", non_validated_nodes);
|
123 | 141 |
|
124 | 142 | for node in non_validated_nodes {
|
125 |
| - let node_address = node.id.trim_start_matches("0x").parse::<Address>().unwrap(); |
| 143 | + let node_address = match node.id.trim_start_matches("0x").parse::<Address>() { |
| 144 | + Ok(addr) => addr, |
| 145 | + Err(e) => { |
| 146 | + error!("Failed to parse node address {}: {}", node.id, e); |
| 147 | + continue; |
| 148 | + } |
| 149 | + }; |
126 | 150 |
|
127 |
| - let provider_address = node |
| 151 | + let provider_address = match node |
128 | 152 | .provider_address
|
129 | 153 | .trim_start_matches("0x")
|
130 | 154 | .parse::<Address>()
|
131 |
| - .unwrap(); |
| 155 | + { |
| 156 | + Ok(addr) => addr, |
| 157 | + Err(e) => { |
| 158 | + error!( |
| 159 | + "Failed to parse provider address {}: {}", |
| 160 | + node.provider_address, e |
| 161 | + ); |
| 162 | + continue; |
| 163 | + } |
| 164 | + }; |
132 | 165 |
|
133 | 166 | if let Err(e) = runtime.block_on(
|
134 | 167 | contracts
|
|
0 commit comments