diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 01b49772c..4f2caa9ce 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -17,7 +17,7 @@ jobs: uses: dtolnay/rust-toolchain@stable with: components: clippy - toolchain: 1.75.0 + toolchain: 1.79.0 - name: Install toolchain (nightly) run: rustup toolchain add nightly --component rustfmt --profile minimal - uses: Swatinem/rust-cache@v2 diff --git a/.github/workflows/docker-release.yaml b/.github/workflows/docker-release.yaml index ddf8bb61d..99aed36d7 100644 --- a/.github/workflows/docker-release.yaml +++ b/.github/workflows/docker-release.yaml @@ -31,7 +31,7 @@ jobs: uses: dtolnay/rust-toolchain@stable with: components: clippy - toolchain: 1.75.0 + toolchain: 1.79.0 - name: Install toolchain (nightly) run: rustup toolchain add nightly --component rustfmt --profile minimal diff --git a/Cargo.toml b/Cargo.toml index 4d58c48cb..31d6f3244 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ resolver = "2" [workspace.package] version = "0.3.0" edition = "2021" -rust-version = "1.75" +rust-version = "1.79" license = "MIT OR Apache-2.0" repository = "https://github.com/alchemyplatform/rundler" diff --git a/Dockerfile b/Dockerfile index 095574321..f257e999f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # Adapted from https://github.com/paradigmxyz/reth/blob/main/Dockerfile # syntax=docker/dockerfile:1.4 -FROM --platform=$TARGETPLATFORM rust:1.75.0 AS chef-builder +FROM --platform=$TARGETPLATFORM rust:1.79.0 AS chef-builder # Install system dependencies RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list diff --git a/bin/rundler/src/cli/node/events.rs b/bin/rundler/src/cli/node/events.rs index 21af478f7..8066acd9d 100644 --- a/bin/rundler/src/cli/node/events.rs +++ b/bin/rundler/src/cli/node/events.rs @@ -13,7 +13,6 @@ use std::fmt::Display; -use ethers::types::Address; use rundler_builder::BuilderEvent; use rundler_pool::PoolEvent; @@ -23,12 +22,6 @@ pub enum Event { BuilderEvent(BuilderEvent), } -#[derive(Clone, Debug)] -pub struct WithEntryPoint { - pub entry_point: Address, - pub event: T, -} - impl From for Event { fn from(event: PoolEvent) -> Self { Self::PoolEvent(event) diff --git a/crates/builder/src/sender/bloxroute.rs b/crates/builder/src/sender/bloxroute.rs index 66a8807b3..7137a4c6b 100644 --- a/crates/builder/src/sender/bloxroute.rs +++ b/crates/builder/src/sender/bloxroute.rs @@ -11,16 +11,13 @@ // You should have received a copy of the GNU General Public License along with Rundler. // If not, see https://www.gnu.org/licenses/. -use std::{sync::Arc, time::Duration}; +use std::sync::Arc; use anyhow::Context; use ethers::{ middleware::SignerMiddleware, providers::{JsonRpcClient, Middleware, Provider}, - types::{ - transaction::eip2718::TypedTransaction, Address, Bytes, TransactionReceipt, TxHash, H256, - U256, - }, + types::{transaction::eip2718::TypedTransaction, Address, Bytes, TxHash, H256, U256}, utils::hex, }; use ethers_signers::Signer; @@ -32,7 +29,6 @@ use rundler_sim::ExpectedStorage; use rundler_types::GasFees; use serde::{Deserialize, Serialize}; use serde_json::value::RawValue; -use tokio::time; use tonic::async_trait; use super::{ @@ -46,9 +42,7 @@ where S: Signer + 'static, { provider: SignerMiddleware>, S>, - raw_provider: Arc>, client: PolygonBloxrouteClient, - poll_interval: Duration, } #[async_trait] @@ -107,15 +101,6 @@ where .unwrap_or(TxStatus::Pending)) } - async fn wait_until_mined(&self, tx_hash: H256) -> Result> { - Ok(Self::wait_until_mined_no_drop( - tx_hash, - Arc::clone(&self.raw_provider), - self.poll_interval, - ) - .await?) - } - fn address(&self) -> Address { self.provider.address() } @@ -126,45 +111,12 @@ where C: JsonRpcClient + 'static, S: Signer + 'static, { - pub(crate) fn new( - provider: Arc>, - signer: S, - poll_interval: Duration, - auth_header: &str, - ) -> Result { + pub(crate) fn new(provider: Arc>, signer: S, auth_header: &str) -> Result { Ok(Self { provider: SignerMiddleware::new(Arc::clone(&provider), signer), - raw_provider: provider, client: PolygonBloxrouteClient::new(auth_header)?, - poll_interval, }) } - - async fn wait_until_mined_no_drop( - tx_hash: H256, - provider: Arc>, - poll_interval: Duration, - ) -> Result> { - loop { - let tx = provider - .get_transaction(tx_hash) - .await - .context("provider should return transaction status")?; - - match tx.and_then(|tx| tx.block_number) { - None => {} - Some(_) => { - let receipt = provider - .get_transaction_receipt(tx_hash) - .await - .context("provider should return transaction receipt")?; - return Ok(receipt); - } - } - - time::sleep(poll_interval).await; - } - } } struct PolygonBloxrouteClient { diff --git a/crates/builder/src/sender/flashbots.rs b/crates/builder/src/sender/flashbots.rs index eecaf1144..d1e44272f 100644 --- a/crates/builder/src/sender/flashbots.rs +++ b/crates/builder/src/sender/flashbots.rs @@ -13,27 +13,16 @@ // Adapted from https://github.com/onbjerg/ethers-flashbots and // https://github.com/gakonst/ethers-rs/blob/master/ethers-providers/src/toolbox/pending_transaction.rs -use std::{ - future::Future, - pin::Pin, - str::FromStr, - sync::Arc, - task::{Context as TaskContext, Poll}, -}; +use std::{str::FromStr, sync::Arc}; use anyhow::{anyhow, Context}; use ethers::{ middleware::SignerMiddleware, - providers::{interval, JsonRpcClient, Middleware, Provider}, - types::{ - transaction::eip2718::TypedTransaction, Address, Bytes, TransactionReceipt, H256, U256, U64, - }, + providers::{JsonRpcClient, Middleware, Provider}, + types::{transaction::eip2718::TypedTransaction, Address, Bytes, H256, U256, U64}, utils, }; use ethers_signers::Signer; -use futures_timer::Delay; -use futures_util::{Stream, StreamExt, TryFutureExt}; -use pin_project::pin_project; use reqwest::{ header::{HeaderMap, HeaderValue, CONTENT_TYPE}, Client, Response, @@ -131,17 +120,6 @@ where }) } - async fn wait_until_mined(&self, tx_hash: H256) -> Result> { - Ok( - PendingFlashbotsTransaction::new( - tx_hash, - self.provider.inner(), - &self.flashbots_client, - ) - .await?, - ) - } - fn address(&self) -> Address { self.provider.address() } @@ -384,118 +362,6 @@ where } } -type PinBoxFut<'a, T> = Pin> + Send + 'a>>; - -enum PendingFlashbotsTxState<'a> { - InitialDelay(Pin>), - PausedGettingTx, - GettingTx(PinBoxFut<'a, FlashbotsAPIResponse>), - PausedGettingReceipt, - GettingReceipt(PinBoxFut<'a, Option>), - Completed, -} - -#[pin_project] -struct PendingFlashbotsTransaction<'a, P, S> { - tx_hash: H256, - provider: &'a Provider

, - client: &'a FlashbotsClient, - state: PendingFlashbotsTxState<'a>, - interval: Box + Send + Unpin>, -} - -impl<'a, P: JsonRpcClient, S> PendingFlashbotsTransaction<'a, P, S> { - fn new(tx_hash: H256, provider: &'a Provider

, client: &'a FlashbotsClient) -> Self { - let delay = Box::pin(Delay::new(provider.get_interval())); - - Self { - tx_hash, - provider, - client, - state: PendingFlashbotsTxState::InitialDelay(delay), - interval: Box::new(interval(provider.get_interval())), - } - } -} - -impl<'a, P: JsonRpcClient, S: Send + Sync> Future for PendingFlashbotsTransaction<'a, P, S> { - type Output = anyhow::Result>; - - fn poll(self: Pin<&mut Self>, ctx: &mut TaskContext<'_>) -> Poll { - let this = self.project(); - - match this.state { - PendingFlashbotsTxState::InitialDelay(fut) => { - futures_util::ready!(fut.as_mut().poll(ctx)); - let status_fut = Box::pin(this.client.status(*this.tx_hash)); - *this.state = PendingFlashbotsTxState::GettingTx(status_fut); - ctx.waker().wake_by_ref(); - return Poll::Pending; - } - PendingFlashbotsTxState::PausedGettingTx => { - let _ready = futures_util::ready!(this.interval.poll_next_unpin(ctx)); - let status_fut = Box::pin(this.client.status(*this.tx_hash)); - *this.state = PendingFlashbotsTxState::GettingTx(status_fut); - ctx.waker().wake_by_ref(); - return Poll::Pending; - } - PendingFlashbotsTxState::GettingTx(fut) => { - let status = futures_util::ready!(fut.as_mut().poll(ctx))?; - tracing::debug!("Transaction:status {:?}:{:?}", *this.tx_hash, status.status); - match status.status { - FlashbotsAPITransactionStatus::Pending => { - *this.state = PendingFlashbotsTxState::PausedGettingTx; - ctx.waker().wake_by_ref(); - } - FlashbotsAPITransactionStatus::Included => { - let receipt_fut = Box::pin( - this.provider - .get_transaction_receipt(*this.tx_hash) - .map_err(|e| anyhow::anyhow!("failed to get receipt: {:?}", e)), - ); - *this.state = PendingFlashbotsTxState::GettingReceipt(receipt_fut); - ctx.waker().wake_by_ref(); - } - FlashbotsAPITransactionStatus::Cancelled => { - return Poll::Ready(Ok(None)); - } - FlashbotsAPITransactionStatus::Failed - | FlashbotsAPITransactionStatus::Unknown => { - return Poll::Ready(Err(anyhow::anyhow!( - "transaction failed with status {:?}", - status.status - ))); - } - } - } - PendingFlashbotsTxState::PausedGettingReceipt => { - let _ready = futures_util::ready!(this.interval.poll_next_unpin(ctx)); - let fut = Box::pin( - this.provider - .get_transaction_receipt(*this.tx_hash) - .map_err(|e| anyhow::anyhow!("failed to get receipt: {:?}", e)), - ); - *this.state = PendingFlashbotsTxState::GettingReceipt(fut); - ctx.waker().wake_by_ref(); - } - PendingFlashbotsTxState::GettingReceipt(fut) => { - if let Some(receipt) = futures_util::ready!(fut.as_mut().poll(ctx))? { - *this.state = PendingFlashbotsTxState::Completed; - return Poll::Ready(Ok(Some(receipt))); - } else { - *this.state = PendingFlashbotsTxState::PausedGettingReceipt; - ctx.waker().wake_by_ref(); - } - } - PendingFlashbotsTxState::Completed => { - panic!("polled pending flashbots transaction future after completion") - } - } - - Poll::Pending - } -} - fn deserialize_u64<'de, D>(deserializer: D) -> std::result::Result where D: de::Deserializer<'de>, diff --git a/crates/builder/src/sender/mod.rs b/crates/builder/src/sender/mod.rs index fcc0ed70d..9d5445cec 100644 --- a/crates/builder/src/sender/mod.rs +++ b/crates/builder/src/sender/mod.rs @@ -14,7 +14,7 @@ mod bloxroute; mod flashbots; mod raw; -use std::{sync::Arc, time::Duration}; +use std::sync::Arc; use anyhow::Context; use async_trait::async_trait; @@ -24,8 +24,8 @@ use ethers::{ prelude::SignerMiddleware, providers::{JsonRpcClient, Middleware, Provider, ProviderError}, types::{ - transaction::eip2718::TypedTransaction, Address, Bytes, Eip1559TransactionRequest, - TransactionReceipt, H256, U256, + transaction::eip2718::TypedTransaction, Address, Bytes, Eip1559TransactionRequest, H256, + U256, }, }; use ethers_signers::{LocalWallet, Signer}; @@ -99,8 +99,6 @@ pub(crate) trait TransactionSender: Send + Sync + 'static { async fn get_transaction_status(&self, tx_hash: H256) -> Result; - async fn wait_until_mined(&self, tx_hash: H256) -> Result>; - fn address(&self) -> Address; } @@ -178,7 +176,6 @@ impl TransactionSenderArgs { rpc_provider: Arc>, submit_provider: Option>>, signer: S, - eth_poll_interval: Duration, ) -> std::result::Result, SenderConstructorErrors> { let sender = match self { @@ -213,14 +210,9 @@ impl TransactionSenderArgs { args.status_url, )?) } - Self::Bloxroute(args) => { - TransactionSenderEnum::PolygonBloxroute(PolygonBloxrouteTransactionSender::new( - rpc_provider, - signer, - eth_poll_interval, - &args.header, - )?) - } + Self::Bloxroute(args) => TransactionSenderEnum::PolygonBloxroute( + PolygonBloxrouteTransactionSender::new(rpc_provider, signer, &args.header)?, + ), }; Ok(sender) } diff --git a/crates/builder/src/sender/raw.rs b/crates/builder/src/sender/raw.rs index 3e23f454f..429b4f570 100644 --- a/crates/builder/src/sender/raw.rs +++ b/crates/builder/src/sender/raw.rs @@ -17,8 +17,8 @@ use anyhow::Context; use async_trait::async_trait; use ethers::{ middleware::SignerMiddleware, - providers::{JsonRpcClient, Middleware, PendingTransaction, Provider}, - types::{transaction::eip2718::TypedTransaction, Address, TransactionReceipt, H256, U256}, + providers::{JsonRpcClient, Middleware, Provider}, + types::{transaction::eip2718::TypedTransaction, Address, H256, U256}, }; use ethers_signers::Signer; use rundler_sim::ExpectedStorage; @@ -122,12 +122,6 @@ where }) } - async fn wait_until_mined(&self, tx_hash: H256) -> Result> { - Ok(PendingTransaction::new(tx_hash, self.provider.inner()) - .await - .context("should wait for transaction to be mined or dropped")?) - } - fn address(&self) -> Address { self.submitter.address() } diff --git a/crates/builder/src/task.rs b/crates/builder/src/task.rs index 6d4ffe5eb..c0ec6d939 100644 --- a/crates/builder/src/task.rs +++ b/crates/builder/src/task.rs @@ -442,7 +442,6 @@ where Arc::clone(&provider), submit_provider, signer, - self.args.eth_poll_interval, )?; let tracker_settings = transaction_tracker::Settings { diff --git a/crates/provider/src/ethers/metrics_middleware.rs b/crates/provider/src/ethers/metrics_middleware.rs index cea8bde1f..00c3eefd4 100644 --- a/crates/provider/src/ethers/metrics_middleware.rs +++ b/crates/provider/src/ethers/metrics_middleware.rs @@ -91,12 +91,12 @@ where }; let rpc = match rpc_code { - x if x == -32000 => RpcCode::ExecutionFailed, - x if x == -32700 => RpcCode::ParseError, - x if x == -32600 => RpcCode::InvalidRequest, - x if x == -32601 => RpcCode::MethodNotFound, - x if x == -32602 => RpcCode::InvalidParams, - x if x == -32603 => RpcCode::InternalError, + -32700 => RpcCode::ParseError, + -32000 => RpcCode::ExecutionFailed, + -32600 => RpcCode::InvalidRequest, + -32601 => RpcCode::MethodNotFound, + -32602 => RpcCode::InvalidParams, + -32603 => RpcCode::InternalError, x if (-32099..=-32000).contains(&x) => RpcCode::ServerError, x if x >= 0 => RpcCode::Success, _ => RpcCode::Other,