From 64803be90b411db97d7b1c6706dbd707eed74d37 Mon Sep 17 00:00:00 2001 From: Daniel Savu <23065004+daniel-savu@users.noreply.github.com> Date: Mon, 27 May 2024 18:07:42 +0100 Subject: [PATCH] feat(hyp-ethereum): gas escalator middleware --- rust/Cargo.lock | 20 ++++++++-------- rust/Cargo.toml | 10 ++++---- .../src/rpc_clients/trait_builder.rs | 23 ++++++++++++++++++- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index f29c2c80e..e38be6559 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -2715,7 +2715,7 @@ dependencies = [ [[package]] name = "ethers" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-05-27#950dd3480ce9c4aeca6ebcbb1eb0d735b9908676" dependencies = [ "ethers-addressbook", "ethers-contract", @@ -2729,7 +2729,7 @@ dependencies = [ [[package]] name = "ethers-addressbook" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-05-27#950dd3480ce9c4aeca6ebcbb1eb0d735b9908676" dependencies = [ "ethers-core", "once_cell", @@ -2740,7 +2740,7 @@ dependencies = [ [[package]] name = "ethers-contract" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-05-27#950dd3480ce9c4aeca6ebcbb1eb0d735b9908676" dependencies = [ "ethers-contract-abigen", "ethers-contract-derive", @@ -2758,7 +2758,7 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-05-27#950dd3480ce9c4aeca6ebcbb1eb0d735b9908676" dependencies = [ "Inflector", "cfg-if", @@ -2782,7 +2782,7 @@ dependencies = [ [[package]] name = "ethers-contract-derive" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-05-27#950dd3480ce9c4aeca6ebcbb1eb0d735b9908676" dependencies = [ "ethers-contract-abigen", "ethers-core", @@ -2796,7 +2796,7 @@ dependencies = [ [[package]] name = "ethers-core" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-05-27#950dd3480ce9c4aeca6ebcbb1eb0d735b9908676" dependencies = [ "arrayvec", "bytes", @@ -2826,7 +2826,7 @@ dependencies = [ [[package]] name = "ethers-etherscan" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-05-27#950dd3480ce9c4aeca6ebcbb1eb0d735b9908676" dependencies = [ "ethers-core", "getrandom 0.2.12", @@ -2842,7 +2842,7 @@ dependencies = [ [[package]] name = "ethers-middleware" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-05-27#950dd3480ce9c4aeca6ebcbb1eb0d735b9908676" dependencies = [ "async-trait", "auto_impl 0.5.0", @@ -2890,7 +2890,7 @@ dependencies = [ [[package]] name = "ethers-providers" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-05-27#950dd3480ce9c4aeca6ebcbb1eb0d735b9908676" dependencies = [ "async-trait", "auto_impl 1.1.0", @@ -2926,7 +2926,7 @@ dependencies = [ [[package]] name = "ethers-signers" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-05-27#950dd3480ce9c4aeca6ebcbb1eb0d735b9908676" dependencies = [ "async-trait", "coins-bip32", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 5909e10bc..7663bd774 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -195,27 +195,27 @@ cosmwasm-schema = "1.2.7" [workspace.dependencies.ethers] features = [] git = "https://github.com/hyperlane-xyz/ethers-rs" -tag = "2024-04-25" +tag = "2024-05-27" [workspace.dependencies.ethers-contract] features = ["legacy"] git = "https://github.com/hyperlane-xyz/ethers-rs" -tag = "2024-04-25" +tag = "2024-05-27" [workspace.dependencies.ethers-core] features = [] git = "https://github.com/hyperlane-xyz/ethers-rs" -tag = "2024-04-25" +tag = "2024-05-27" [workspace.dependencies.ethers-providers] features = [] git = "https://github.com/hyperlane-xyz/ethers-rs" -tag = "2024-04-25" +tag = "2024-05-27" [workspace.dependencies.ethers-signers] features = ["aws"] git = "https://github.com/hyperlane-xyz/ethers-rs" -tag = "2024-04-25" +tag = "2024-05-27" [patch.crates-io.curve25519-dalek] branch = "v3.2.2-relax-zeroize" diff --git a/rust/chains/hyperlane-ethereum/src/rpc_clients/trait_builder.rs b/rust/chains/hyperlane-ethereum/src/rpc_clients/trait_builder.rs index 04894aa49..bb98355cf 100644 --- a/rust/chains/hyperlane-ethereum/src/rpc_clients/trait_builder.rs +++ b/rust/chains/hyperlane-ethereum/src/rpc_clients/trait_builder.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use std::time::Duration; use async_trait::async_trait; +use ethers::middleware::gas_escalator::{Frequency, GasEscalatorMiddleware, GeometricGasPrice}; use ethers::middleware::gas_oracle::{ GasCategory, GasOracle, GasOracleMiddleware, Polygon, ProviderOracle, }; @@ -210,7 +211,12 @@ pub trait BuildableWithProvider { M: Middleware + 'static, { Ok(if let Some(signer) = signer { - let signing_provider = wrap_with_signer(provider, signer) + // - The signing provider is used for sending txs, which may end up stuck in the mempool due to + // gas pricing issues. So we first wrap the provider in a gas escalator middleware. + // - When txs reach the gas escalator, they will already have been signed by the signer middleware, + // so they are ready to be retried + let gas_escalator_provider = wrap_with_gas_escalator(provider); + let signing_provider = wrap_with_signer(gas_escalator_provider, signer) .await .map_err(ChainCommunicationError::from_other)?; self.build_with_provider(signing_provider, conn, locator) @@ -274,3 +280,18 @@ where }; Ok(GasOracleMiddleware::new(provider, gas_oracle)) } + +fn wrap_with_gas_escalator(provider: M) -> GasEscalatorMiddleware +where + M: Middleware + 'static, +{ + // Increase the gas price by 12.5% every 60 seconds + // (These are the default values from ethers doc comments) + let coefficient = 1.125; + let every_secs = 60u64; + let escalator = GeometricGasPrice::new(coefficient, every_secs, None::); + // Check the status of sent txs every eth block or so. The alternative is to subscribe to new blocks and check then, + // which adds unnecessary load on the provider. + let frequency = Frequency::Duration(Duration::from_secs(12).as_millis() as _); + GasEscalatorMiddleware::new(provider, escalator, frequency) +}