Skip to content

Commit db2a662

Browse files
committed
improve resiliency of validator
1 parent 535e0c3 commit db2a662

File tree

3 files changed

+78
-43
lines changed

3 files changed

+78
-43
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

validator/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ edition.workspace = true
66
[dependencies]
77
actix-web = "4.9.0"
88
alloy = { version = "0.9.2", features = ["full"] }
9+
anyhow = "1.0.95"
910
clap = { version = "4.5.26", features = ["derive"] }
1011
env_logger = "0.11.6"
1112
log = "0.4.25"

validator/src/main.rs

+76-43
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use actix_web::{web, App, HttpResponse, HttpServer, Responder};
22
use alloy::primitives::{hex, Address};
33
use alloy::signers::Signer;
4+
use anyhow::{Context, Result};
45
use clap::Parser;
56
use log::LevelFilter;
67
use log::{error, info};
@@ -64,71 +65,103 @@ fn main() {
6465
.with_compute_pool()
6566
.build()
6667
.unwrap();
67-
6868
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> {
7370
let signature = wallet
7471
.signer
7572
.sign_message(message.as_bytes())
76-
.await?
73+
.await
74+
.context("Failed to sign message")?
7775
.as_bytes();
7876
Ok(format!("0x{}", hex::encode(signature)))
7977
}
8078

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+
};
112133

113-
Ok(parsed_response.data)
114-
});
115134
let non_validated_nodes: Vec<DiscoveryNode> = nodes
116135
.iter()
117-
.flatten()
118136
.filter(|node| !node.is_validated)
119137
.cloned()
120138
.collect();
121139

122140
info!("Non validated nodes: {:?}", non_validated_nodes);
123141

124142
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+
};
126150

127-
let provider_address = node
151+
let provider_address = match node
128152
.provider_address
129153
.trim_start_matches("0x")
130154
.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+
};
132165

133166
if let Err(e) = runtime.block_on(
134167
contracts

0 commit comments

Comments
 (0)