Skip to content

Commit 77d5d3d

Browse files
committed
papyrus_base_layer: extract check and cycle URLs into a helper function with logging
1 parent 4565ed8 commit 77d5d3d

File tree

1 file changed

+63
-30
lines changed

1 file changed

+63
-30
lines changed

crates/papyrus_base_layer/src/cyclic_base_layer_wrapper.rs

Lines changed: 63 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::ops::RangeInclusive;
22

33
use async_trait::async_trait;
44
use starknet_api::block::BlockHashAndNumber;
5+
use tracing::info;
56
use url::Url;
67

78
use crate::{BaseLayerContract, L1BlockHeader, L1BlockNumber, L1BlockReference, L1Event};
@@ -18,6 +19,53 @@ impl<B: BaseLayerContract + Send + Sync> CyclicBaseLayerWrapper<B> {
1819
pub fn new(base_layer: B) -> Self {
1920
Self { base_layer }
2021
}
22+
23+
// Check the result of a function call to the base layer. If it fails, cycle the URL and signal
24+
// the caller that we should try again (by returning None).
25+
async fn cycle_url_on_error<ReturnType>(
26+
&mut self,
27+
start_url: &Url,
28+
result: Result<ReturnType, B::Error>,
29+
) -> Option<Result<ReturnType, B::Error>> {
30+
// In case we succeed, just return the (successful) result.
31+
if result.is_ok() {
32+
return Some(result);
33+
}
34+
// Get the current URL (return error in case it fails to get it).
35+
let current_url = match self.base_layer.get_url().await {
36+
Ok(url) => url,
37+
Err(e) => return Some(Err(e)),
38+
};
39+
// Otherwise, cycle the URL so we can try again. Return error in case it fails to cycle.
40+
match self.base_layer.cycle_provider_url().await {
41+
Ok(()) => (),
42+
Err(e) => return Some(Err(e)),
43+
};
44+
// Get the new URL (return error in case it fails to get it).
45+
let new_url = match self.base_layer.get_url().await {
46+
Ok(url) => url,
47+
Err(e) => return Some(Err(e)),
48+
};
49+
info!(
50+
"Cycling URL from {:?} to {:?}",
51+
to_safe_string(&current_url),
52+
to_safe_string(&new_url)
53+
);
54+
55+
// If we've cycled back to the start URL, we need to return the last error we got.
56+
if &new_url == start_url {
57+
let error_value = result.err().expect("result is checked at start of function");
58+
info!(
59+
"Cycled back to start URL {:?}, returning error {:?}.",
60+
to_safe_string(start_url),
61+
error_value
62+
);
63+
return Some(Err(error_value));
64+
}
65+
// If we cycled but still haven't reached the start URL, we return None to signal that we
66+
// should try again with the new URL.
67+
None
68+
}
2169
}
2270

2371
#[async_trait]
@@ -31,12 +79,8 @@ impl<B: BaseLayerContract + Send + Sync> BaseLayerContract for CyclicBaseLayerWr
3179
let start_url = self.base_layer.get_url().await?;
3280
loop {
3381
let result = self.base_layer.get_proved_block_at(l1_block).await;
34-
if result.is_ok() {
35-
return result;
36-
}
37-
self.base_layer.cycle_provider_url().await?;
38-
if self.base_layer.get_url().await? == start_url {
39-
return result;
82+
if let Some(result) = self.cycle_url_on_error(&start_url, result).await {
83+
return result; // Could return a success or an error.
4084
}
4185
}
4286
}
@@ -45,12 +89,8 @@ impl<B: BaseLayerContract + Send + Sync> BaseLayerContract for CyclicBaseLayerWr
4589
let start_url = self.base_layer.get_url().await?;
4690
loop {
4791
let result = self.base_layer.latest_l1_block_number().await;
48-
if result.is_ok() {
49-
return result;
50-
}
51-
self.base_layer.cycle_provider_url().await?;
52-
if self.base_layer.get_url().await? == start_url {
53-
return result;
92+
if let Some(result) = self.cycle_url_on_error(&start_url, result).await {
93+
return result; // Could return a success or an error.
5494
}
5595
}
5696
}
@@ -62,12 +102,8 @@ impl<B: BaseLayerContract + Send + Sync> BaseLayerContract for CyclicBaseLayerWr
62102
let start_url = self.base_layer.get_url().await?;
63103
loop {
64104
let result = self.base_layer.l1_block_at(block_number).await;
65-
if result.is_ok() {
66-
return result;
67-
}
68-
self.base_layer.cycle_provider_url().await?;
69-
if self.base_layer.get_url().await? == start_url {
70-
return result;
105+
if let Some(result) = self.cycle_url_on_error(&start_url, result).await {
106+
return result; // Could return a success or an error.
71107
}
72108
}
73109
}
@@ -80,12 +116,8 @@ impl<B: BaseLayerContract + Send + Sync> BaseLayerContract for CyclicBaseLayerWr
80116
let start_url = self.base_layer.get_url().await?;
81117
loop {
82118
let result = self.base_layer.events(block_range.clone(), event_identifiers).await;
83-
if result.is_ok() {
84-
return result;
85-
}
86-
self.base_layer.cycle_provider_url().await?;
87-
if self.base_layer.get_url().await? == start_url {
88-
return result;
119+
if let Some(result) = self.cycle_url_on_error(&start_url, result).await {
120+
return result; // Could return a success or an error.
89121
}
90122
}
91123
}
@@ -97,12 +129,8 @@ impl<B: BaseLayerContract + Send + Sync> BaseLayerContract for CyclicBaseLayerWr
97129
let start_url = self.base_layer.get_url().await?;
98130
loop {
99131
let result = self.base_layer.get_block_header(block_number).await;
100-
if result.is_ok() {
101-
return result;
102-
}
103-
self.base_layer.cycle_provider_url().await?;
104-
if self.base_layer.get_url().await? == start_url {
105-
return result;
132+
if let Some(result) = self.cycle_url_on_error(&start_url, result).await {
133+
return result; // Could return a success or an error.
106134
}
107135
}
108136
}
@@ -126,3 +154,8 @@ impl<B: BaseLayerContract + Send + Sync> BaseLayerContract for CyclicBaseLayerWr
126154
self.base_layer.cycle_provider_url().await
127155
}
128156
}
157+
158+
fn to_safe_string(url: &Url) -> String {
159+
// We print only the hostnames to avoid leaking the API keys.
160+
url.host().map_or_else(|| "no host in url!".to_string(), |host| host.to_string())
161+
}

0 commit comments

Comments
 (0)