Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Polygon gas oracle #2965

Merged
merged 9 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion rust/chains/hyperlane-ethereum/src/mailbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down
73 changes: 57 additions & 16 deletions rust/chains/hyperlane-ethereum/src/trait_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -17,7 +20,9 @@ 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::{signers::Signers, ConnectionConf, FallbackProvider, RetryingProvider};

Expand Down Expand Up @@ -89,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 } => {
Expand All @@ -109,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 } => {
Expand All @@ -125,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?
}
})
}
Expand Down Expand Up @@ -174,9 +178,9 @@ pub trait BuildableWithProvider {
)
}

/// Wrap the provider creation with metrics if provided; this is the second
/// step
async fn wrap_with_metrics<P>(
/// Create the provider, applying any middlewares (e.g. gas oracle, signer, metrics) as needed,
/// and then create the associated trait.
async fn build<P>(
&self,
client: P,
locator: &ContractLocator,
Expand All @@ -186,19 +190,20 @@ pub trait BuildableWithProvider {
where
P: JsonRpcClient + 'static,
{
let provider = Provider::new(client);
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<M>(
/// provided, and then create the associated trait.
async fn build_with_signer<M>(
&self,
provider: M,
locator: &ContractLocator,
Expand All @@ -208,7 +213,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)
Expand All @@ -224,7 +229,7 @@ pub trait BuildableWithProvider {
M: Middleware + 'static;
}

async fn build_signing_provider<M: Middleware>(
async fn wrap_with_signer<M: Middleware>(
provider: M,
signer: Signers,
) -> Result<SignerMiddleware<NonceManagerMiddleware<M>, Signers>, M::Error> {
Expand All @@ -237,3 +242,39 @@ async fn build_signing_provider<M: Middleware>(
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<M>(
provider: Arc<M>,
tkporter marked this conversation as resolved.
Show resolved Hide resolved
domain: &HyperlaneDomain,
) -> ChainResult<GasOracleMiddleware<Arc<M>, Box<dyn GasOracle>>>
where
M: Middleware + 'static,
{
let gas_oracle: Box<dyn GasOracle> = {
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))
}
tkporter marked this conversation as resolved.
Show resolved Hide resolved
15 changes: 1 addition & 14 deletions rust/chains/hyperlane-ethereum/src/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ use ethers::{
};
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;
Expand Down Expand Up @@ -73,7 +71,6 @@ pub(crate) async fn fill_tx_gas_params<M, D>(
tx: ContractCall<M, D>,
tx_gas_limit: Option<U256>,
provider: Arc<M>,
domain: u32,
) -> ChainResult<ContractCall<M, D>>
where
M: Middleware + 'static,
Expand All @@ -91,16 +88,6 @@ where
// 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() {
Expand Down
2 changes: 1 addition & 1 deletion rust/chains/hyperlane-ethereum/src/validator_announce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down
Loading