Skip to content

Commit 11e11a1

Browse files
authored
chore: Improvements to RPC handling (#177)
1 parent 7cd1c57 commit 11e11a1

File tree

68 files changed

+2357
-1375
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+2357
-1375
lines changed
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

docs/modules/ROOT/pages/error.adoc

+6
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,12 @@ a|* `NotFound` - Resource not found errors
160160
* `ExecutionError` - Trigger execution failures
161161
* `ConfigurationError` - Trigger configuration issues
162162
* `Other` - Unclassified errors
163+
164+
|Monitor Executor
165+
|`MonitorExecutionError`
166+
a|* `NotFound` - Resource not found errors
167+
* `ExecutionError` - Monitor execution failures
168+
* `Other` - Unclassified errors
163169
|===
164170

165171
== Error Handling Guidelines

docs/modules/ROOT/pages/rpc.adoc

+76-30
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ RPC endpoints are configured in the network configuration files with weights for
3838

3939
[TIP]
4040
====
41-
For high-availability setups, configure at least 3 RPC endpoints with appropriate weights to ensure continuous operation even if multiple endpoints fail.
41+
For high-availability setups, configure at least 3 (private) RPC endpoints with appropriate weights to ensure continuous operation even if multiple endpoints fail.
4242
====
4343

4444
=== Configuration Fields
@@ -92,12 +92,21 @@ pub const ROTATE_ON_ERROR_CODES: [u16; 1] = [429];
9292
Each transport client implements `reqwest-retry` middleware with exponential backoff to handle transient failures in network requests. This is implemented separately from the endpoint rotation mechanism.
9393

9494
* For transient HTTP errors and network failures:
95-
** Retries up to 2 times (configurable via `ExponentialBackoff` builder)
95+
** Retries up to 3 times (configurable via `ExponentialBackoff` builder)
9696
** Applies exponential backoff between retry attempts
9797
** Returns the final error if all retry attempts fail
9898
** Maintains the same URL throughout the retry process
9999
** Independent from the endpoint rotation mechanism
100100

101+
Each blockchain network type has its own specialized transport client that wraps the base `HttpTransportClient`.
102+
This architecture provides common HTTP functionality while allowing customization of network-specific behaviors like connection testing and retry policies.
103+
The transport clients are implemented as:
104+
105+
1. *Base HTTP Transport*: `HttpTransportClient` provides core HTTP functionality
106+
2. *Network-Specific Transports*:
107+
* `EVMTransportClient` for EVM networks
108+
* `StellarTransportClient` for Stellar networks
109+
101110
==== Configuration Options
102111

103112
The retry policy can be customized using the `ExponentialBackoff` builder in the respective transport client. The default retry policy is:
@@ -106,9 +115,9 @@ The retry policy can be customized using the `ExponentialBackoff` builder in the
106115
----
107116
let retry_policy = ExponentialBackoff::builder()
108117
.base(2)
109-
.retry_bounds(Duration::from_millis(100), Duration::from_secs(4))
110-
.jitter(Jitter::None)
111-
.build_with_max_retries(2);
118+
.retry_bounds(Duration::from_millis(250), Duration::from_secs(10))
119+
.jitter(Jitter::Full)
120+
.build_with_max_retries(3);
112121
----
113122

114123
The retry policy can be customized with the following options:
@@ -124,32 +133,68 @@ pub struct ExponentialBackoff {
124133
}
125134
----
126135

127-
The retry mechanism is implemented at two levels:
136+
The retry mechanism is implemented at the transport level using a dual-client approach:
137+
138+
1. A base `reqwest` HTTP client is created with optimized configurations:
139+
* Connection pool settings for efficient resource usage
140+
* Configurable timeouts for request and connection handling
141+
* Shared across all transport operations
142+
143+
2. A cloned instance of this client is enhanced with middleware:
144+
* Wrapped with `reqwest_middleware` for retry capabilities
145+
* Configured with exponential backoff and jitter
146+
* Handles automatic retry logic for failed requests
147+
148+
This architecture ensures:
149+
150+
1. Direct requests (like health checks) use the base client for minimal overhead
151+
2. RPC calls benefit from the middleware's retry capabilities
152+
3. Both clients maintain efficiency by sharing the same connection pool
153+
154+
155+
Each transport client may define its own retry policy:
128156

129-
1. *Transport Level*: Each transport client maintains its own retry policy:
130-
+
131157
[source,rust]
132158
----
133-
pub struct AlloyTransportClient {
134-
client: Arc<RwLock<RpcClient>>,
135-
endpoint_manager: EndpointManager,
136-
retry_policy: ExponentialBackoff,
137-
}
138159
139-
pub struct StellarTransportClient {
140-
pub client: Arc<RwLock<StellarHttpClient>>,
160+
// src/services/transports/http.rs
161+
pub struct HttpTransportClient {
162+
pub client: Arc<RwLock<Client>>,
141163
endpoint_manager: EndpointManager,
142-
retry_policy: ExponentialBackoff,
164+
test_connection_payload: Option<String>,
143165
}
144-
----
145166
146-
2. *Request Level*: The `EndpointManager` applies the retry policy through middleware:
147-
+
148-
[source,rust]
149-
----
150-
let client = ClientBuilder::new(reqwest::Client::new())
151-
.with(RetryTransientMiddleware::new_with_policy(retry_policy))
167+
// Example of client creation with retry mechanism
168+
let http_client = reqwest::ClientBuilder::new()
169+
.pool_idle_timeout(Duration::from_secs(90))
170+
.pool_max_idle_per_host(32)
171+
.timeout(Duration::from_secs(30))
172+
.connect_timeout(Duration::from_secs(20))
173+
.build()?;
174+
175+
// Create middleware client with retry policy
176+
let client = ClientBuilder::new(cloned_http_client)
177+
.with(RetryTransientMiddleware::new_with_policy_and_strategy(
178+
retry_policy,
179+
RetryTransient,
180+
))
152181
.build();
182+
183+
// src/services/transports/evm/http.rs
184+
pub struct EVMTransportClient {
185+
http_client: HttpTransportClient,
186+
}
187+
188+
// override with a custom retry policy and strategy
189+
pub async fn new(network: &Network) -> Result<Self, anyhow::Error> {
190+
let test_connection_payload = Some(r#"{"id":1,"jsonrpc":"2.0","method":"net_version","params":[]}"#.to_string());
191+
let http_client = HttpTransportClient::new(network, test_connection_payload).await?;
192+
http_client.set_retry_policy(
193+
ExponentialBackoff::builder().build_with_total_retry_duration(Duration::from_secs(10)),
194+
Some(DefaultRetryableStrategy),
195+
)?;
196+
Ok(Self { http_client })
197+
}
153198
----
154199

155200
=== Implementation Details
@@ -231,22 +276,23 @@ graph TD
231276

232277
== Best Practices
233278

234-
* Use private RPC providers when possible
235-
* Configure multiple fallback endpoints
236-
* Consider geographic distribution of endpoints
237-
* Monitor endpoint reliability and adjust weights accordingly
279+
* Configure multiple private endpoints with appropriate weights
280+
* Use geographically distributed endpoints when possible
281+
* Monitor endpoint health and adjust weights as needed
282+
* Set appropriate retry policies based on network characteristics
283+
238284

239285
== Troubleshooting
240286

241287
=== Common Issues
242288

243-
* *429 Too Many Requests*: Increase the number of fallback URLs or reduce monitoring frequency
289+
* *429 Too Many Requests*: Increase the number of fallback URLs, adjust weights or reduce monitoring frequency
244290
* *Connection Timeouts*: Check endpoint health and network connectivity
245-
* *Invalid Responses*: Verify RPC endpoint compatibility with your network type
291+
* *Invalid Responses*: Verify endpoint compatibility with your network type
246292

247293
=== Logging
248294

249-
Enable debug logging for detailed RPC client information:
295+
Enable debug logging for detailed transport information:
250296

251297
[source,bash]
252298
----

docs/modules/ROOT/pages/structure.adoc

+3-1
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,15 @@ The main source code directory contains the core implementation files organized
3838
**** `stellar/`: Stellar filter
3939
** `notification/`: Alert handling
4040
** `trigger/`: Trigger evaluation and execution
41+
**** `script/`: Script execution utilities
42+
4143

4244
* `utils/`: Helper functions
4345
** `cron_utils`: Cron schedule utilities
4446
** `expression`: Expression evaluation
4547
** `logging/`: Logging utilities
4648
** `metrics/`: Metrics utilities
47-
** `script/`: Script execution utilities
49+
** `monitor/`: Monitor configuration test utilities
4850

4951
== Configuration and Data
5052

0 commit comments

Comments
 (0)