From 51fde3df29bce3ef3bf5b667f72589312b9b914e Mon Sep 17 00:00:00 2001 From: Trevor Porter Date: Wed, 22 Nov 2023 20:01:36 +0000 Subject: [PATCH 1/9] Use polygon gas oracle --- rust/chains/hyperlane-ethereum/src/tx.rs | 56 +++++++++++++++++++----- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/rust/chains/hyperlane-ethereum/src/tx.rs b/rust/chains/hyperlane-ethereum/src/tx.rs index 2850bf93cc..68c23d5b02 100644 --- a/rust/chains/hyperlane-ethereum/src/tx.rs +++ b/rust/chains/hyperlane-ethereum/src/tx.rs @@ -4,6 +4,7 @@ use std::time::Duration; use ethers::{ abi::Detokenize, + middleware::gas_oracle::{GasCategory, GasOracle, Polygon}, prelude::{NameOrAddress, TransactionReceipt}, types::Eip1559TransactionRequest, }; @@ -87,20 +88,10 @@ where .saturating_add(U256::from(GAS_ESTIMATE_BUFFER).into()) .into() }; - let Ok((max_fee, max_priority_fee)) = provider.estimate_eip1559_fees(None).await else { + let Ok((max_fee, max_priority_fee)) = estimate_eip1559_fees(&provider, domain).await else { // Is not EIP 1559 chain return Ok(tx.gas(gas_limit)); }; - let max_priority_fee = if matches!( - KnownHyperlaneDomain::try_from(domain), - Ok(KnownHyperlaneDomain::Polygon) - ) { - // Polygon needs a max priority fee >= 30 gwei - let min_polygon_fee = U256::from(30_000_000_000u64); - max_priority_fee.max(min_polygon_fee.into()) - } else { - max_priority_fee - }; // Is EIP 1559 chain let mut request = Eip1559TransactionRequest::new(); if let Some(from) = tx.tx.from() { @@ -143,3 +134,46 @@ where Ok(call) } } + +/// Heavily borrowed from: +/// https://github.com/foundry-rs/foundry/blob/fdaed8603fc330cbc94c936f15594bccdc381225/crates/common/src/provider.rs#L254-L290 +/// +/// Estimates EIP1559 fees depending on the chain +/// +/// Uses custom gas oracles for +/// - polygon +/// - mumbai +/// +/// Fallback is the default [`Provider::estimate_eip1559_fees`] implementation +pub async fn estimate_eip1559_fees( + provider: &M, + domain: u32, +) -> ChainResult<(ethers::types::U256, ethers::types::U256)> +where + M::Error: 'static, +{ + if let Ok(domain) = KnownHyperlaneDomain::try_from(domain) { + // handle chains that deviate from `eth_feeHistory` and have their own oracle + match domain { + KnownHyperlaneDomain::Polygon | KnownHyperlaneDomain::Mumbai => { + let chain = match domain { + KnownHyperlaneDomain::Polygon => ethers_core::types::Chain::Polygon, + KnownHyperlaneDomain::Mumbai => ethers_core::types::Chain::PolygonMumbai, + _ => unreachable!(), + }; + let estimator = Polygon::new(chain) + .map_err(ChainCommunicationError::from_other)? + .category(GasCategory::Standard); + return estimator + .estimate_eip1559_fees() + .await + .map_err(ChainCommunicationError::from_other); + } + _ => {} + } + } + provider + .estimate_eip1559_fees(None) + .await + .map_err(ChainCommunicationError::from_other) +} From 178c24ee7f3fb555d5e419479e20362c25759f51 Mon Sep 17 00:00:00 2001 From: Trevor Porter Date: Thu, 23 Nov 2023 11:25:39 +0000 Subject: [PATCH 2/9] :/ --- .../hyperlane-ethereum/src/trait_builder.rs | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/rust/chains/hyperlane-ethereum/src/trait_builder.rs b/rust/chains/hyperlane-ethereum/src/trait_builder.rs index f2242cb162..a6fbf67f60 100644 --- a/rust/chains/hyperlane-ethereum/src/trait_builder.rs +++ b/rust/chains/hyperlane-ethereum/src/trait_builder.rs @@ -3,6 +3,9 @@ use std::sync::Arc; use std::time::Duration; use async_trait::async_trait; +use ethers::middleware::gas_oracle::{ + GasCategory, GasOracle, GasOracleMiddleware, Polygon, ProviderOracle, +}; use ethers::prelude::{ Http, JsonRpcClient, Middleware, NonceManagerMiddleware, Provider, Quorum, QuorumProvider, SignerMiddleware, WeightedProvider, Ws, WsClientError, @@ -17,8 +20,11 @@ use ethers_prometheus::json_rpc_client::{ use ethers_prometheus::middleware::{ MiddlewareMetrics, PrometheusMiddleware, PrometheusMiddlewareConf, }; -use hyperlane_core::{ChainCommunicationError, ChainResult, ContractLocator}; +use hyperlane_core::{ + ChainCommunicationError, ChainResult, ContractLocator, HyperlaneDomain, KnownHyperlaneDomain, +}; +use crate::provider; use crate::{signers::Signers, ConnectionConf, FallbackProvider, RetryingProvider}; // This should be whatever the prometheus scrape interval is @@ -176,6 +182,7 @@ pub trait BuildableWithProvider { /// Wrap the provider creation with metrics if provided; this is the second /// step + /// TODO rename async fn wrap_with_metrics

( &self, client: P, @@ -184,9 +191,35 @@ pub trait BuildableWithProvider { metrics: Option<(MiddlewareMetrics, PrometheusMiddlewareConf)>, ) -> ChainResult where - P: JsonRpcClient + 'static, + P: JsonRpcClient + Clone + 'static, { let provider = Provider::new(client); + + let gas_oracle: Arc = { + match locator.domain { + HyperlaneDomain::Known( + KnownHyperlaneDomain::Polygon | KnownHyperlaneDomain::Mumbai, + ) => { + let chain = match locator.domain { + HyperlaneDomain::Known(KnownHyperlaneDomain::Polygon) => { + ethers_core::types::Chain::Polygon + } + HyperlaneDomain::Known(KnownHyperlaneDomain::Mumbai) => { + ethers_core::types::Chain::PolygonMumbai + } + _ => unreachable!(), + }; + let estimator = Polygon::new(chain) + .map_err(ChainCommunicationError::from_other)? + .category(GasCategory::Standard); + Arc::new(estimator) + } + _ => Arc::new(ProviderOracle::new(provider.clone())), + } + }; + + let provider = Arc::new(GasOracleMiddleware::new(provider, gas_oracle)); + Ok(if let Some(metrics) = metrics { let provider = Arc::new(PrometheusMiddleware::new(provider, metrics.0, metrics.1)); tokio::spawn(provider.start_updating_on_interval(METRICS_SCRAPE_INTERVAL)); From 01b26cee13c70f609a51637914d12bde988e60a3 Mon Sep 17 00:00:00 2001 From: Trevor Porter Date: Thu, 23 Nov 2023 11:37:20 +0000 Subject: [PATCH 3/9] Fix --- .../hyperlane-ethereum/src/trait_builder.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/rust/chains/hyperlane-ethereum/src/trait_builder.rs b/rust/chains/hyperlane-ethereum/src/trait_builder.rs index a6fbf67f60..e3999aefe9 100644 --- a/rust/chains/hyperlane-ethereum/src/trait_builder.rs +++ b/rust/chains/hyperlane-ethereum/src/trait_builder.rs @@ -24,7 +24,6 @@ use hyperlane_core::{ ChainCommunicationError, ChainResult, ContractLocator, HyperlaneDomain, KnownHyperlaneDomain, }; -use crate::provider; use crate::{signers::Signers, ConnectionConf, FallbackProvider, RetryingProvider}; // This should be whatever the prometheus scrape interval is @@ -191,11 +190,14 @@ pub trait BuildableWithProvider { metrics: Option<(MiddlewareMetrics, PrometheusMiddlewareConf)>, ) -> ChainResult where - P: JsonRpcClient + Clone + 'static, + P: JsonRpcClient + 'static, { - let provider = Provider::new(client); + let provider = Arc::new(Provider::new(client)); - let gas_oracle: Arc = { + // Apply a gas oracle. + // Polygon and Mumbai require using the Polygon gas oracle, see discussion here + // https://github.com/foundry-rs/foundry/issues/1703 + let gas_oracle: Box = { match locator.domain { HyperlaneDomain::Known( KnownHyperlaneDomain::Polygon | KnownHyperlaneDomain::Mumbai, @@ -209,16 +211,15 @@ pub trait BuildableWithProvider { } _ => unreachable!(), }; - let estimator = Polygon::new(chain) + let gas_oracle = Polygon::new(chain) .map_err(ChainCommunicationError::from_other)? .category(GasCategory::Standard); - Arc::new(estimator) + Box::new(gas_oracle) } - _ => Arc::new(ProviderOracle::new(provider.clone())), + _ => Box::new(ProviderOracle::new(provider.clone())), } }; - - let provider = Arc::new(GasOracleMiddleware::new(provider, gas_oracle)); + let provider = GasOracleMiddleware::new(provider, gas_oracle); Ok(if let Some(metrics) = metrics { let provider = Arc::new(PrometheusMiddleware::new(provider, metrics.0, metrics.1)); From fb3ddf9cbd13fce0bc09fbfbff5a98905f3f4b31 Mon Sep 17 00:00:00 2001 From: Trevor Porter Date: Thu, 23 Nov 2023 11:39:34 +0000 Subject: [PATCH 4/9] clean up --- rust/chains/hyperlane-ethereum/src/mailbox.rs | 2 +- rust/chains/hyperlane-ethereum/src/tx.rs | 51 +------------------ .../src/validator_announce.rs | 2 +- 3 files changed, 4 insertions(+), 51 deletions(-) diff --git a/rust/chains/hyperlane-ethereum/src/mailbox.rs b/rust/chains/hyperlane-ethereum/src/mailbox.rs index 42fad5d843..60bf35c9d8 100644 --- a/rust/chains/hyperlane-ethereum/src/mailbox.rs +++ b/rust/chains/hyperlane-ethereum/src/mailbox.rs @@ -264,7 +264,7 @@ where metadata.to_vec().into(), RawHyperlaneMessage::from(message).to_vec().into(), ); - fill_tx_gas_params(tx, tx_gas_limit, self.provider.clone(), message.destination).await + fill_tx_gas_params(tx, tx_gas_limit, self.provider.clone()).await } } diff --git a/rust/chains/hyperlane-ethereum/src/tx.rs b/rust/chains/hyperlane-ethereum/src/tx.rs index 68c23d5b02..6919b4a03e 100644 --- a/rust/chains/hyperlane-ethereum/src/tx.rs +++ b/rust/chains/hyperlane-ethereum/src/tx.rs @@ -4,15 +4,12 @@ use std::time::Duration; use ethers::{ abi::Detokenize, - middleware::gas_oracle::{GasCategory, GasOracle, Polygon}, prelude::{NameOrAddress, TransactionReceipt}, types::Eip1559TransactionRequest, }; use ethers_contract::builders::ContractCall; use ethers_core::types::BlockNumber; -use hyperlane_core::{ - utils::fmt_bytes, ChainCommunicationError, ChainResult, KnownHyperlaneDomain, H256, U256, -}; +use hyperlane_core::{utils::fmt_bytes, ChainCommunicationError, ChainResult, H256, U256}; use tracing::{error, info}; use crate::Middleware; @@ -74,7 +71,6 @@ pub(crate) async fn fill_tx_gas_params( tx: ContractCall, tx_gas_limit: Option, provider: Arc, - domain: u32, ) -> ChainResult> where M: Middleware + 'static, @@ -88,7 +84,7 @@ where .saturating_add(U256::from(GAS_ESTIMATE_BUFFER).into()) .into() }; - let Ok((max_fee, max_priority_fee)) = estimate_eip1559_fees(&provider, domain).await else { + let Ok((max_fee, max_priority_fee)) = provider.estimate_eip1559_fees(None).await else { // Is not EIP 1559 chain return Ok(tx.gas(gas_limit)); }; @@ -134,46 +130,3 @@ where Ok(call) } } - -/// Heavily borrowed from: -/// https://github.com/foundry-rs/foundry/blob/fdaed8603fc330cbc94c936f15594bccdc381225/crates/common/src/provider.rs#L254-L290 -/// -/// Estimates EIP1559 fees depending on the chain -/// -/// Uses custom gas oracles for -/// - polygon -/// - mumbai -/// -/// Fallback is the default [`Provider::estimate_eip1559_fees`] implementation -pub async fn estimate_eip1559_fees( - provider: &M, - domain: u32, -) -> ChainResult<(ethers::types::U256, ethers::types::U256)> -where - M::Error: 'static, -{ - if let Ok(domain) = KnownHyperlaneDomain::try_from(domain) { - // handle chains that deviate from `eth_feeHistory` and have their own oracle - match domain { - KnownHyperlaneDomain::Polygon | KnownHyperlaneDomain::Mumbai => { - let chain = match domain { - KnownHyperlaneDomain::Polygon => ethers_core::types::Chain::Polygon, - KnownHyperlaneDomain::Mumbai => ethers_core::types::Chain::PolygonMumbai, - _ => unreachable!(), - }; - let estimator = Polygon::new(chain) - .map_err(ChainCommunicationError::from_other)? - .category(GasCategory::Standard); - return estimator - .estimate_eip1559_fees() - .await - .map_err(ChainCommunicationError::from_other); - } - _ => {} - } - } - provider - .estimate_eip1559_fees(None) - .await - .map_err(ChainCommunicationError::from_other) -} diff --git a/rust/chains/hyperlane-ethereum/src/validator_announce.rs b/rust/chains/hyperlane-ethereum/src/validator_announce.rs index 8bce341c2e..d21348be2f 100644 --- a/rust/chains/hyperlane-ethereum/src/validator_announce.rs +++ b/rust/chains/hyperlane-ethereum/src/validator_announce.rs @@ -86,7 +86,7 @@ where announcement.value.storage_location, serialized_signature.into(), ); - fill_tx_gas_params(tx, tx_gas_limit, self.provider.clone(), self.domain.id()).await + fill_tx_gas_params(tx, tx_gas_limit, self.provider.clone()).await } } From 0ada0c849c60e244913d32075894c9d639852492 Mon Sep 17 00:00:00 2001 From: Trevor Porter Date: Thu, 23 Nov 2023 11:46:20 +0000 Subject: [PATCH 5/9] prettier --- .../hyperlane-ethereum/src/trait_builder.rs | 65 +++++++++++-------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/rust/chains/hyperlane-ethereum/src/trait_builder.rs b/rust/chains/hyperlane-ethereum/src/trait_builder.rs index e3999aefe9..99422d22c2 100644 --- a/rust/chains/hyperlane-ethereum/src/trait_builder.rs +++ b/rust/chains/hyperlane-ethereum/src/trait_builder.rs @@ -192,34 +192,7 @@ pub trait BuildableWithProvider { where P: JsonRpcClient + 'static, { - let provider = Arc::new(Provider::new(client)); - - // Apply a gas oracle. - // Polygon and Mumbai require using the Polygon gas oracle, see discussion here - // https://github.com/foundry-rs/foundry/issues/1703 - let gas_oracle: Box = { - match locator.domain { - HyperlaneDomain::Known( - KnownHyperlaneDomain::Polygon | KnownHyperlaneDomain::Mumbai, - ) => { - let chain = match locator.domain { - HyperlaneDomain::Known(KnownHyperlaneDomain::Polygon) => { - ethers_core::types::Chain::Polygon - } - HyperlaneDomain::Known(KnownHyperlaneDomain::Mumbai) => { - ethers_core::types::Chain::PolygonMumbai - } - _ => unreachable!(), - }; - let gas_oracle = Polygon::new(chain) - .map_err(ChainCommunicationError::from_other)? - .category(GasCategory::Standard); - Box::new(gas_oracle) - } - _ => Box::new(ProviderOracle::new(provider.clone())), - } - }; - let provider = GasOracleMiddleware::new(provider, gas_oracle); + let provider = Self::wrap_with_gas_oracle(Arc::new(Provider::new(client)), locator.domain)?; Ok(if let Some(metrics) = metrics { let provider = Arc::new(PrometheusMiddleware::new(provider, metrics.0, metrics.1)); @@ -252,6 +225,42 @@ pub trait BuildableWithProvider { .await) } + /// Wrap the provider a gas oracle. + /// Polygon and Mumbai require using the Polygon gas oracle, see discussion here + /// https://github.com/foundry-rs/foundry/issues/1703. + /// Defaults to using the provider's gas oracle. + fn wrap_with_gas_oracle( + provider: Arc, + domain: &HyperlaneDomain, + ) -> ChainResult, Box>> + where + M: Middleware + 'static, + { + let gas_oracle: Box = { + match domain { + HyperlaneDomain::Known( + KnownHyperlaneDomain::Polygon | KnownHyperlaneDomain::Mumbai, + ) => { + let chain = match domain { + HyperlaneDomain::Known(KnownHyperlaneDomain::Polygon) => { + ethers_core::types::Chain::Polygon + } + HyperlaneDomain::Known(KnownHyperlaneDomain::Mumbai) => { + ethers_core::types::Chain::PolygonMumbai + } + _ => unreachable!(), + }; + let gas_oracle = Polygon::new(chain) + .map_err(ChainCommunicationError::from_other)? + .category(GasCategory::Standard); + Box::new(gas_oracle) + } + _ => Box::new(ProviderOracle::new(provider.clone())), + } + }; + Ok(GasOracleMiddleware::new(provider, gas_oracle)) + } + /// Construct a new instance of the associated trait using a provider. async fn build_with_provider(&self, provider: M, locator: &ContractLocator) -> Self::Output where From 46eaec1cf30d708bd1f851d956dcd4cfb8c7ce7b Mon Sep 17 00:00:00 2001 From: Trevor Porter Date: Thu, 23 Nov 2023 11:52:02 +0000 Subject: [PATCH 6/9] minor refactor --- .../hyperlane-ethereum/src/trait_builder.rs | 99 +++++++++---------- 1 file changed, 48 insertions(+), 51 deletions(-) diff --git a/rust/chains/hyperlane-ethereum/src/trait_builder.rs b/rust/chains/hyperlane-ethereum/src/trait_builder.rs index 99422d22c2..adbcec117a 100644 --- a/rust/chains/hyperlane-ethereum/src/trait_builder.rs +++ b/rust/chains/hyperlane-ethereum/src/trait_builder.rs @@ -94,7 +94,7 @@ pub trait BuildableWithProvider { builder = builder.add_provider(weighted_provider); } let quorum_provider = builder.build(); - self.wrap_with_metrics(quorum_provider, locator, signer, middleware_metrics) + self.build(quorum_provider, locator, signer, middleware_metrics) .await? } ConnectionConf::HttpFallback { urls } => { @@ -114,7 +114,7 @@ pub trait BuildableWithProvider { builder = builder.add_provider(metrics_provider); } let fallback_provider = builder.build(); - self.wrap_with_metrics(fallback_provider, locator, signer, middleware_metrics) + self.build(fallback_provider, locator, signer, middleware_metrics) .await? } ConnectionConf::Http { url } => { @@ -130,15 +130,14 @@ pub trait BuildableWithProvider { &middleware_metrics, ); let retrying_http_provider = RetryingProvider::new(metrics_provider, None, None); - self.wrap_with_metrics(retrying_http_provider, locator, signer, middleware_metrics) + self.build(retrying_http_provider, locator, signer, middleware_metrics) .await? } ConnectionConf::Ws { url } => { let ws = Ws::connect(url) .await .map_err(EthereumProviderConnectionError::from)?; - self.wrap_with_metrics(ws, locator, signer, middleware_metrics) - .await? + self.build(ws, locator, signer, middleware_metrics).await? } }) } @@ -179,10 +178,8 @@ pub trait BuildableWithProvider { ) } - /// Wrap the provider creation with metrics if provided; this is the second - /// step - /// TODO rename - async fn wrap_with_metrics

( + /// Create the provider, applying any middlewares (e.g. gas oracle, signer, metrics) as needed. + async fn build

( &self, client: P, locator: &ContractLocator, @@ -192,20 +189,20 @@ pub trait BuildableWithProvider { where P: JsonRpcClient + 'static, { - let provider = Self::wrap_with_gas_oracle(Arc::new(Provider::new(client)), locator.domain)?; + let provider = wrap_with_gas_oracle(Arc::new(Provider::new(client)), locator.domain)?; Ok(if let Some(metrics) = metrics { let provider = Arc::new(PrometheusMiddleware::new(provider, metrics.0, metrics.1)); tokio::spawn(provider.start_updating_on_interval(METRICS_SCRAPE_INTERVAL)); - self.wrap_with_signer(provider, locator, signer).await? + self.build_with_signer(provider, locator, signer).await? } else { - self.wrap_with_signer(provider, locator, signer).await? + self.build_with_signer(provider, locator, signer).await? }) } /// Wrap the provider creation with a signing provider if signers were /// provided; this is the third step. - async fn wrap_with_signer( + async fn build_with_signer( &self, provider: M, locator: &ContractLocator, @@ -215,7 +212,7 @@ pub trait BuildableWithProvider { M: Middleware + 'static, { Ok(if let Some(signer) = signer { - let signing_provider = build_signing_provider(provider, signer) + let signing_provider = wrap_with_signer(provider, signer) .await .map_err(ChainCommunicationError::from_other)?; self.build_with_provider(signing_provider, locator) @@ -225,49 +222,13 @@ pub trait BuildableWithProvider { .await) } - /// Wrap the provider a gas oracle. - /// Polygon and Mumbai require using the Polygon gas oracle, see discussion here - /// https://github.com/foundry-rs/foundry/issues/1703. - /// Defaults to using the provider's gas oracle. - fn wrap_with_gas_oracle( - provider: Arc, - domain: &HyperlaneDomain, - ) -> ChainResult, Box>> - where - M: Middleware + 'static, - { - let gas_oracle: Box = { - match domain { - HyperlaneDomain::Known( - KnownHyperlaneDomain::Polygon | KnownHyperlaneDomain::Mumbai, - ) => { - let chain = match domain { - HyperlaneDomain::Known(KnownHyperlaneDomain::Polygon) => { - ethers_core::types::Chain::Polygon - } - HyperlaneDomain::Known(KnownHyperlaneDomain::Mumbai) => { - ethers_core::types::Chain::PolygonMumbai - } - _ => unreachable!(), - }; - let gas_oracle = Polygon::new(chain) - .map_err(ChainCommunicationError::from_other)? - .category(GasCategory::Standard); - Box::new(gas_oracle) - } - _ => Box::new(ProviderOracle::new(provider.clone())), - } - }; - Ok(GasOracleMiddleware::new(provider, gas_oracle)) - } - /// Construct a new instance of the associated trait using a provider. async fn build_with_provider(&self, provider: M, locator: &ContractLocator) -> Self::Output where M: Middleware + 'static; } -async fn build_signing_provider( +async fn wrap_with_signer( provider: M, signer: Signers, ) -> Result, Signers>, M::Error> { @@ -280,3 +241,39 @@ async fn build_signing_provider( let signing_provider = SignerMiddleware::new(provider, signer); Ok(signing_provider) } + +/// Wrap the provider with a gas oracle middleware. +/// Polygon and Mumbai require using the Polygon gas oracle, see discussion here +/// https://github.com/foundry-rs/foundry/issues/1703. +/// Defaults to using the provider's gas oracle. +fn wrap_with_gas_oracle( + provider: Arc, + domain: &HyperlaneDomain, +) -> ChainResult, Box>> +where + M: Middleware + 'static, +{ + let gas_oracle: Box = { + match domain { + HyperlaneDomain::Known( + KnownHyperlaneDomain::Polygon | KnownHyperlaneDomain::Mumbai, + ) => { + let chain = match domain { + HyperlaneDomain::Known(KnownHyperlaneDomain::Polygon) => { + ethers_core::types::Chain::Polygon + } + HyperlaneDomain::Known(KnownHyperlaneDomain::Mumbai) => { + ethers_core::types::Chain::PolygonMumbai + } + _ => unreachable!(), + }; + let gas_oracle = Polygon::new(chain) + .map_err(ChainCommunicationError::from_other)? + .category(GasCategory::Standard); + Box::new(gas_oracle) + } + _ => Box::new(ProviderOracle::new(provider.clone())), + } + }; + Ok(GasOracleMiddleware::new(provider, gas_oracle)) +} From 2a3cee9cc69e54ad683b9e39a0ea3d4010dac9d7 Mon Sep 17 00:00:00 2001 From: Trevor Porter Date: Thu, 23 Nov 2023 11:52:41 +0000 Subject: [PATCH 7/9] nit --- rust/chains/hyperlane-ethereum/src/trait_builder.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rust/chains/hyperlane-ethereum/src/trait_builder.rs b/rust/chains/hyperlane-ethereum/src/trait_builder.rs index adbcec117a..219269fd85 100644 --- a/rust/chains/hyperlane-ethereum/src/trait_builder.rs +++ b/rust/chains/hyperlane-ethereum/src/trait_builder.rs @@ -178,7 +178,8 @@ pub trait BuildableWithProvider { ) } - /// Create the provider, applying any middlewares (e.g. gas oracle, signer, metrics) as needed. + /// Create the provider, applying any middlewares (e.g. gas oracle, signer, metrics) as needed, + /// and then create the associated trait. async fn build

( &self, client: P, From 521137a9204efe08b849edf68357d87ece338202 Mon Sep 17 00:00:00 2001 From: Trevor Porter Date: Thu, 23 Nov 2023 11:54:03 +0000 Subject: [PATCH 8/9] nit --- rust/chains/hyperlane-ethereum/src/trait_builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/chains/hyperlane-ethereum/src/trait_builder.rs b/rust/chains/hyperlane-ethereum/src/trait_builder.rs index 219269fd85..dc92968834 100644 --- a/rust/chains/hyperlane-ethereum/src/trait_builder.rs +++ b/rust/chains/hyperlane-ethereum/src/trait_builder.rs @@ -202,7 +202,7 @@ pub trait BuildableWithProvider { } /// Wrap the provider creation with a signing provider if signers were - /// provided; this is the third step. + /// provided, and then create the associated trait. async fn build_with_signer( &self, provider: M, From dec8238c07412375f9f3f07ac242ab69d41f3e48 Mon Sep 17 00:00:00 2001 From: Trevor Porter Date: Thu, 23 Nov 2023 15:11:16 +0000 Subject: [PATCH 9/9] PR comment --- .../hyperlane-ethereum/src/trait_builder.rs | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/rust/chains/hyperlane-ethereum/src/trait_builder.rs b/rust/chains/hyperlane-ethereum/src/trait_builder.rs index dc92968834..03a33c2fdc 100644 --- a/rust/chains/hyperlane-ethereum/src/trait_builder.rs +++ b/rust/chains/hyperlane-ethereum/src/trait_builder.rs @@ -190,7 +190,7 @@ pub trait BuildableWithProvider { where P: JsonRpcClient + 'static, { - let provider = wrap_with_gas_oracle(Arc::new(Provider::new(client)), locator.domain)?; + let provider = wrap_with_gas_oracle(Provider::new(client), locator.domain)?; Ok(if let Some(metrics) = metrics { let provider = Arc::new(PrometheusMiddleware::new(provider, metrics.0, metrics.1)); @@ -243,35 +243,32 @@ async fn wrap_with_signer( Ok(signing_provider) } +fn build_polygon_gas_oracle(chain: ethers_core::types::Chain) -> ChainResult> { + let gas_oracle = Polygon::new(chain) + .map_err(ChainCommunicationError::from_other)? + .category(GasCategory::Standard); + Ok(Box::new(gas_oracle) as Box) +} + /// Wrap the provider with a gas oracle middleware. /// Polygon and Mumbai require using the Polygon gas oracle, see discussion here /// https://github.com/foundry-rs/foundry/issues/1703. /// Defaults to using the provider's gas oracle. fn wrap_with_gas_oracle( - provider: Arc, + provider: M, domain: &HyperlaneDomain, ) -> ChainResult, Box>> where M: Middleware + 'static, { + let provider = Arc::new(provider); let gas_oracle: Box = { match domain { - HyperlaneDomain::Known( - KnownHyperlaneDomain::Polygon | KnownHyperlaneDomain::Mumbai, - ) => { - let chain = match domain { - HyperlaneDomain::Known(KnownHyperlaneDomain::Polygon) => { - ethers_core::types::Chain::Polygon - } - HyperlaneDomain::Known(KnownHyperlaneDomain::Mumbai) => { - ethers_core::types::Chain::PolygonMumbai - } - _ => unreachable!(), - }; - let gas_oracle = Polygon::new(chain) - .map_err(ChainCommunicationError::from_other)? - .category(GasCategory::Standard); - Box::new(gas_oracle) + HyperlaneDomain::Known(KnownHyperlaneDomain::Polygon) => { + build_polygon_gas_oracle(ethers_core::types::Chain::Polygon)? + } + HyperlaneDomain::Known(KnownHyperlaneDomain::Mumbai) => { + build_polygon_gas_oracle(ethers_core::types::Chain::PolygonMumbai)? } _ => Box::new(ProviderOracle::new(provider.clone())), }