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

feat: eth_sendRawTransactionConditional #301

Merged
merged 1 commit into from
Apr 13, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
1,295 changes: 598 additions & 697 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ silius-tests = { version = "0.4.0-alpha", path = "tests", default-features = fal
# eth
alloy-chains = "0.1.14"
discv5 = { version = "0.4.0", features = ["libp2p"] }
ethers = { git = "https://github.com/gakonst/ethers-rs", rev = "fa3017715a298728d9fb341933818a5d0d84c2dc", features = [
ethers = { git = "https://github.com/gakonst/ethers-rs", rev = "5394d899adca736a602e316e6f0c06fdb5aa64b9", features = [
"ws",
] }
ssz_rs = { git = "https://github.com/ralexstokes/ssz-rs.git", rev = "8640128ec83071094d24fb4511147d6b9dd029bb" }
Expand Down Expand Up @@ -82,4 +82,4 @@ tracing = "0.1.40"
[patch.crates-io]
revm-primitives = { git = "https://github.com/bluealloy/revm", rev = "3d8ca6641d2e72448c23f4596f769c8fd1c784d1" }
[patch."https://github.com/gakonst/ethers-rs"]
ethers = { git = "https://github.com/Vid201/ethers-rs", branch = "chore/ws" }
ethers = { git = "https://github.com/Vid201/ethers-rs", branch = "feat/patch" }
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ run-silius-p2p-bootnode:
cargo run --release -- node --eth-client-address http://127.0.0.1:8545 --mnemonic-file ./bundler-spec-tests/keys/0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --beneficiary 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --entry-points 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 --http --http.port 4000 --eth-client-proxy-address http://127.0.0.1:8545 --p2p.baddr 127.0.0.1 --enable-p2p

run-silius-p2p-peer:
cargo run --release -- node --eth-client-address http://127.0.0.1:8545 --mnemonic-file ./bundler-spec-tests/keys/0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --beneficiary 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --entry-points 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 --http --http.port 4000 --eth-client-proxy-address http://127.0.0.1:8545 --p2p.baddr 127.0.0.1 --bootnodes "enr:-J24QFyIGX9IG6_4WO6F40-BXH0b4gChUm3zTOkYNoYBOWX5LTq7ubqm5oaFjwcg5r1YesmllbqNvKAapeM2JK8fkKoBiGNoYWluX2lkiDkFAAAAAAAAgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQMm_tiGzC78d2_BvxJAUX9hRzBQv9QUmgU4OB4Pv1eVE4N0Y3CCIyiDdWRwgiMo" --enable-p2p --discovery.port 4338 --p2p.port 4338 --datadir ./.local/node1
cargo run --release -- node --eth-client-address http://127.0.0.1:8545 --mnemonic-file ./bundler-spec-tests/keys/0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --beneficiary 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --entry-points 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 --http --http.port 4000 --eth-client-proxy-address http://127.0.0.1:8545 --p2p.baddr 127.0.0.1 --bootnodes "enr:-J24QMMKCYqEBAs659G2f4MtvjI8wp3dbAvrvRbTxIEaapZfb9Pi0La0QOs6HoGfVeGk8fsFvZF7WiM_arx43rxSHwQBiGNoYWluX2lkiDkFAAAAAAAAgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQLigwYFOcf1lit2x918h4_6upE1lZ1kK3tD029ZZioW0IN0Y3CCIyiDdWRwgiMo" --enable-p2p --discovery.port 4338 --p2p.port 4338 --datadir ./.local/node1

run-silius-debug:
cargo run --release -- node --eth-client-address ws://127.0.0.1:8546 --mnemonic-file ${HOME}/.silius/0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --beneficiary 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --entry-points 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 --http --ws --http.api eth,debug,web3 --ws.api eth,debug,web3
Expand Down
19 changes: 18 additions & 1 deletion bin/silius/src/bundler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
use alloy_chains::{Chain, NamedChain};
use ethers::{providers::Middleware, types::Address};
use parking_lot::RwLock;
use silius_bundler::{EthereumClient, FlashbotsClient};
use silius_bundler::{ConditionalClient, EthereumClient, FlashbotsClient};
use silius_contracts::EntryPoint;
use silius_grpc::{
bundler_client::BundlerClient, bundler_service_run, uo_pool_client::UoPoolClient,
Expand Down Expand Up @@ -154,6 +154,23 @@ where
args.enable_access_list,
);
}
SendStrategy::Conditional => {
let client = Arc::new(ConditionalClient::new(eth_client.clone(), wallet.clone()));
bundler_service_run(
SocketAddr::new(args.bundler_addr, args.bundler_port),
wallet,
entry_points,
chain_conn,
args.beneficiary,
args.min_balance,
args.bundle_interval,
eth_client,
client,
uopool_grpc_client,
metrics_args.enable_metrics,
args.enable_access_list,
);
}
SendStrategy::Flashbots => {
let relay_endpoints: Vec<String> = match chain_conn
.named()
Expand Down
1 change: 0 additions & 1 deletion crates/bundler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ tokio = { workspace = true }
bytes = "1.5.0"
eyre = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
tracing = { workspace = true }
url = "2.5.0"

Expand Down
18 changes: 14 additions & 4 deletions crates/bundler/src/bundler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use ethers::{
},
};
use silius_contracts::entry_point::EntryPointAPI;
use silius_primitives::{UserOperation, UserOperationHash, Wallet};
use silius_primitives::{simulation::StorageMap, UserOperation, UserOperationHash, Wallet};
use std::sync::Arc;
use tracing::{info, trace};

Expand All @@ -18,10 +18,15 @@ pub trait SendBundleOp: Send + Sync + 'static {
///
/// # Arguments
/// * `bundle` - Bundle of [UserOperations](UserOperation)
/// * 'storage_map' - Storage map
///
/// # Returns
/// * `H256` - The hash
async fn send_bundle(&self, bundle: TypedTransaction) -> eyre::Result<H256>;
async fn send_bundle(
&self,
bundle: TypedTransaction,
storage_map: StorageMap,
) -> eyre::Result<H256>;
}

/// The `Bundler` struct is used to represent a bundler with necessary properties
Expand Down Expand Up @@ -140,10 +145,15 @@ where
///
/// # Arguments
/// * `uos` - An array of [UserOperations](UserOperation)
/// * `storage_map` - Storage map
///
/// # Returns
/// * `H256` - The hash
pub async fn send_bundle(&self, uos: &Vec<UserOperation>) -> eyre::Result<Option<H256>> {
pub async fn send_bundle(
&self,
uos: &Vec<UserOperation>,
storage_map: StorageMap,
) -> eyre::Result<Option<H256>> {
if uos.is_empty() {
info!("Skipping creating a new bundle, no user operations");
return Ok(None);
Expand All @@ -157,7 +167,7 @@ where
trace!("Bundle content: {uos:?}");

let bundle = self.create_bundle(uos).await?;
let hash = self.client.send_bundle(bundle).await?;
let hash = self.client.send_bundle(bundle, storage_map).await?;

info!(
"Bundle successfully sent, hash: {:?}, account: {:?}, entry point: {:?}, beneficiary: {:?}",
Expand Down
89 changes: 89 additions & 0 deletions crates/bundler/src/conditional.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use crate::bundler::SendBundleOp;
use ethers::{
middleware::SignerMiddleware,
providers::Middleware,
signers::LocalWallet,
types::{
transaction::{
conditional::{AccountStorage, ConditionalOptions},
eip2718::TypedTransaction,
},
Address, H256,
},
};
use silius_primitives::{simulation::StorageMap, Wallet};
use std::{collections::HashMap, sync::Arc, time::Duration};
use tracing::trace;

/// A type alias for the Ethereum Conditional Signer client
#[derive(Clone)]
pub struct ConditionalClient<M>(pub SignerMiddleware<Arc<M>, LocalWallet>);

#[async_trait::async_trait]
impl<M> SendBundleOp for ConditionalClient<M>
where
M: Middleware + 'static,
{
/// Send a bundle of [UserOperations](UserOperation) to the Ethereum execution client
/// over conditional RPC method.
///
/// # Arguments
/// * `bundle` - Bundle of [UserOperations](UserOperation)
/// * 'storage_map' - Storage map
///
/// # Returns
/// * `H256` - The transaction hash
async fn send_bundle(
&self,
bundle: TypedTransaction,
storage_map: StorageMap,
) -> eyre::Result<H256> {
trace!("Sending transaction to the conditional endpoint: {bundle:?}");

let mut known_accounts: HashMap<Address, AccountStorage> = HashMap::default();

for (k, v) in storage_map.root_hashes {
known_accounts.insert(k, AccountStorage::RootHash(v));
}

for (k, v) in storage_map.slots {
known_accounts.insert(k, AccountStorage::SlotValues(v));
}

let signed_tx = self.0.sign_transaction(bundle).await?;

let tx = self
.0
.send_raw_transaction_conditional(
signed_tx,
ConditionalOptions { known_accounts, ..Default::default() },
)
.await?
.interval(Duration::from_millis(75));
let tx_hash = tx.tx_hash();

let tx_receipt = tx.await?;

trace!("Transaction receipt: {tx_receipt:?}");

Ok(tx_hash)
}
}

impl<M> ConditionalClient<M>
where
M: Middleware + 'static,
{
/// Create an Conditional client
///
/// # Arguments
/// * `eth_client` - Connection to the Ethereum execution client
/// * `wallet` - A [Wallet](Wallet) instance
///
/// # Returns
/// * `ConditionalClient` - A [Ethereum Signer Middleware](ConditionalClient)
pub fn new(eth_client: Arc<M>, wallet: Wallet) -> Self {
let signer = SignerMiddleware::new(eth_client, wallet.signer);
Self(signer)
}
}
13 changes: 9 additions & 4 deletions crates/bundler/src/ethereum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ use ethers::{
signers::LocalWallet,
types::{transaction::eip2718::TypedTransaction, H256},
};
use silius_primitives::Wallet;
use silius_primitives::{simulation::StorageMap, Wallet};
use std::{sync::Arc, time::Duration};
use tracing::trace;

/// A type alias for the Ethereum Signer client
#[derive(Clone)]
pub struct EthereumClient<M>(pub Arc<SignerMiddleware<Arc<M>, LocalWallet>>);
pub struct EthereumClient<M>(pub SignerMiddleware<Arc<M>, LocalWallet>);

#[async_trait::async_trait]
impl<M> SendBundleOp for EthereumClient<M>
Expand All @@ -22,10 +22,15 @@ where
///
/// # Arguments
/// * `bundle` - Bundle of [UserOperations](UserOperation)
/// * 'storage_map' - Storage map
///
/// # Returns
/// * `H256` - The transaction hash
async fn send_bundle(&self, bundle: TypedTransaction) -> eyre::Result<H256> {
async fn send_bundle(
&self,
bundle: TypedTransaction,
_storage_map: StorageMap,
) -> eyre::Result<H256> {
trace!("Sending transaction to the execution client: {bundle:?}");

let tx = self.0.send_transaction(bundle, None).await?.interval(Duration::from_millis(75));
Expand Down Expand Up @@ -53,6 +58,6 @@ where
/// * `EthereumClient` - A [Ethereum Signer Middleware](EthereumClient)
pub fn new(eth_client: Arc<M>, wallet: Wallet) -> Self {
let signer = SignerMiddleware::new(eth_client, wallet.signer);
Self(Arc::new(signer))
Self(signer)
}
}
9 changes: 7 additions & 2 deletions crates/bundler/src/flashbots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use ethers::{
types::{transaction::eip2718::TypedTransaction, H256},
};
use ethers_flashbots::{BundleRequest, FlashbotsMiddleware, PendingBundleError, SimulatedBundle};
use silius_primitives::Wallet;
use silius_primitives::{simulation::StorageMap, Wallet};
use std::sync::Arc;
use tracing::{info, trace};
use url::Url;
Expand All @@ -27,10 +27,15 @@ where
///
/// # Arguments
/// * `uos` - Bundler of [UserOperations](UserOperation)
/// * 'storage_map' - Storage map
///
/// # Returns
/// * `H256` - The transaction hash of the bundle
async fn send_bundle(&self, bundle: TypedTransaction) -> eyre::Result<H256> {
async fn send_bundle(
&self,
bundle: TypedTransaction,
_storage_map: StorageMap,
) -> eyre::Result<H256> {
let bundle_req = self.generate_bundle_req(vec![bundle], false).await?;

match self.simulate_flashbots_bundle(&bundle_req).await {
Expand Down
2 changes: 2 additions & 0 deletions crates/bundler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
#![allow(dead_code)]

mod bundler;
mod conditional;
mod ethereum;
mod flashbots;

pub use bundler::{Bundler, SendBundleOp};
pub use conditional::ConditionalClient;
pub use ethereum::EthereumClient;
pub use flashbots::FlashbotsClient;
4 changes: 2 additions & 2 deletions crates/contracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ eyre = { workspace = true }
lazy_static = { workspace = true }
regex = "1.10.2"
serde = { workspace = true }
serde_json ={ workspace = true }
serde_json = { workspace = true }
thiserror = { workspace = true }

[dev-dependencies]
Expand All @@ -33,7 +33,7 @@ tokio = { workspace = true }
[build-dependencies]
# eth
ethers = { workspace = true, features = ["solc-full"] }
ethers-solc = "2.0.8"
ethers-solc = "2.0.14"

# misc
eyre = { workspace = true }
2 changes: 2 additions & 0 deletions crates/contracts/src/entry_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ impl<M: Middleware + 'static> EntryPoint<M> {
timeout: None,
},
state_overrides: None,
block_overrides: None,
},
)
.await
Expand Down Expand Up @@ -162,6 +163,7 @@ impl<M: Middleware + 'static> EntryPoint<M> {
timeout: None,
},
state_overrides: Some(spoof::balance(Address::zero(), UINT96_MAX.into())),
block_overrides: None,
},
)
.await
Expand Down
23 changes: 15 additions & 8 deletions crates/grpc/src/bundler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use ethers::{
use parking_lot::Mutex;
use silius_bundler::{Bundler, SendBundleOp};
use silius_metrics::grpc::MetricsLayer;
use silius_primitives::{UserOperation, Wallet};
use silius_primitives::{simulation::StorageMap, UserOperation, Wallet};
use std::{net::SocketAddr, sync::Arc, time::Duration};
use tonic::{Request, Response, Status};
use tracing::{error, info};
Expand Down Expand Up @@ -49,22 +49,29 @@ where
async fn get_user_operations(
uopool_grpc_client: &UoPoolClient<tonic::transport::Channel>,
ep: &Address,
) -> eyre::Result<Vec<UserOperation>> {
) -> eyre::Result<(Vec<UserOperation>, StorageMap)> {
let req = Request::new(GetSortedRequest { ep: Some((*ep).into()) });
let res = uopool_grpc_client.clone().get_sorted_user_operations(req).await?;

let uos: Vec<UserOperation> = res.into_inner().uos.into_iter().map(|u| u.into()).collect();
Ok(uos)
let res = res.into_inner();

let uos: Vec<UserOperation> = res.uos.into_iter().map(|u| u.into()).collect();
let map = match res.storage_map {
Some(map) => map.into(),
None => StorageMap::default(),
};

Ok((uos, map))
}

pub async fn send_bundles(&self) -> eyre::Result<(Vec<UserOperation>, Option<H256>)> {
let mut tx_hashes: Vec<Option<H256>> = vec![];
let mut user_operations: Vec<Vec<UserOperation>> = vec![];

for bundler in self.bundlers.iter() {
let uos =
let (uos, map) =
Self::get_user_operations(&self.uopool_grpc_client, &bundler.entry_point).await?;
let tx_hash = bundler.send_bundle(&uos).await?;
let tx_hash = bundler.send_bundle(&uos, map).await?;

tx_hashes.push(tx_hash);
user_operations.push(uos);
Expand Down Expand Up @@ -117,8 +124,8 @@ where
)
.await
{
Ok(bundle) => {
if let Err(e) = bundler_own.send_bundle(&bundle).await {
Ok((bundle, map)) => {
if let Err(e) = bundler_own.send_bundle(&bundle, map).await {
error!("Error while sending bundle: {e:?}");
}
}
Expand Down
Loading
Loading