2. Make evm_provider mutable so we can update and cache latest working client
pub struct RelayerContext {
.
.
/// Evm Providers Cache.
evm_providers: Arc<Mutex<HashMap<types::U256, Arc<EthersClient>>>>,
}
pub async fn evm_provider<I: Into<types::U256>>(
&self,
chain_id: I,
) -> webb_relayer_utils::Result<Arc<EthersClient>> {
let chain_id: types::U256 = chain_id.into();
// Check if the provider is already in the cache or else create new provider from http_endpoint array.
// If the provider is not working, try creating a new provider from http_endpoint array.
if let Some(provider) = self.evm_providers.lock().await.get(&chain_id) {
// get gas price to check if the provider is working
let response = provider.get_gas_price().await;
match response {
Ok(_) => Ok(provider.clone()),
Err(e) => {
tracing::error!(
"EVM Provider for chain {} is not working: {}.Try Connecting with other http_endpoints, if any.",
chain_id,
e
);
self.create_evm_provider(chain_id).await
}
}
} else {
self.create_evm_provider(chain_id).await
}
}
3. Update retry count for RetryClient.
Since we want to switch between RPC providers, we should define a smaller limit for retires like ~50. Once retry limit exceeds the current client is dropped and a new client is created by iterating over available rpc endpoints.
This will happen in the event_watcher::run() method
The evm_provider method will check the provider cache for the client and will do a sanity check for connection by making an API call. If the connection fails it will try to create a new evm_provider from the set of RPC endpoints in the loop.
let task = || async {
let step = contract.max_blocks_per_step().as_u64();
let provider = ctx.evm_provider(chain_id).await?;
let client = Arc::new(TimeLag::new(
provider,
chain_config.block_confirmations,
));
// drop client if retries exceed and create new clients after some back off time
}
Summary of changes
1. Update EvmChainConfig to take multiple http-endpoints
2. Make evm_provider mutable so we can update and cache latest working client
3. Update retry count for RetryClient.
Since we want to switch between RPC providers, we should define a smaller limit for retires like ~50. Once retry limit exceeds the current client is dropped and a new client is created by iterating over available rpc endpoints. This will happen in the event_watcher::run() method
The
evm_provider
method will check the provider cache for the client and will do a sanity check for connection by making an API call. If the connection fails it will try to create a new evm_provider from the set of RPC endpoints in the loop.Reference issue to close (if applicable)
Code Checklist