Skip to content

Commit

Permalink
feat: add p2p crate
Browse files Browse the repository at this point in the history
  • Loading branch information
zsluedem committed Nov 2, 2023
1 parent 3c06de4 commit d806606
Show file tree
Hide file tree
Showing 51 changed files with 5,548 additions and 572 deletions.
2,691 changes: 2,294 additions & 397 deletions Cargo.lock

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ members = [
"crates/bundler",
"crates/contracts",
"crates/grpc",
"crates/p2p",
"crates/primitives",
"crates/rpc",
"crates/uopool",
Expand All @@ -27,14 +28,18 @@ rust-version = "1.73.0"
[workspace.dependencies]
async-stream = "0.3.5"
async-trait = "0.1"
discv5 = { version = "0.3.0", features = ["libp2p"] }
ethers = { git = "https://github.com/gakonst/ethers-rs", rev = "fa3017715a298728d9fb341933818a5d0d84c2dc", features = [
"ws",
] }
expanded-pathbuf = "0.1"
eyre = "0.6.8"
futures-util = "0.3.28"
lazy_static = "1.4.0"
parking_lot = "0.12"
serde_json = "1"
ssz_rs = { git = "https://github.com/ralexstokes/ssz-rs.git", rev = "8640128ec83071094d24fb4511147d6b9dd029bb" }
ssz_rs_derive = { git = "https://github.com/ralexstokes/ssz-rs.git", rev = "8640128ec83071094d24fb4511147d6b9dd029bb" }
tokio = { version = "1.18", features = ["full"] }
tracing = "0.1"

Expand Down
20 changes: 20 additions & 0 deletions P2P.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Prerequirements for building

1. Install rust
2. make fetch-thirdparty
3. make setup-thirdparty

# How to run silius with p2p enabled

## Run silius with bootnodes

```
cargo run -- bundler --eth-client-address http://localhost:8545 --mnemonic-file ./bundler-spec-tests/keys/0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --beneficiary 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --entry-points 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 --http --http.port 4000 --eth-client-proxy-address http://localhost:8545 --p2p-broadcast-address 127.0.0.1 --bootnodes "enr:-Iu4QBh2tesC8BokO61v1w43MnbfHF5H95ZJNHVEQaRq_MjFFuxmeVQnoEXxUDk5qKJCHM944gC72Xg4dYwRkGt9zA4BgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQKRdyIA8OvArCcZbt3hoJHu4nVe6CblqjO0CnrbGACi-IN0Y3CCEPGDdWRwghDx" --enable-p2p --tcp4-port 4338 --udp4-port 4338 --datadir ./.local/data
```


## Run silius as bootnodes

```
cargo run -- bundler --eth-client-address http://localhost:8545 --mnemonic-file ./bundler-spec-tests/keys/0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --beneficiary 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --entry-points 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 --http --http.port 4000 --eth-client-proxy-address http://localhost:8545 --p2p-broadcast-address 127.0.0.1 --enable-p2p
```
2 changes: 2 additions & 0 deletions bin/silius/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ AA (ERC-4337) bundler - Silius
[dependencies]
clap = { version = "4", features = ["derive"] }
dirs = "4.0"
discv5 = { workspace = true }
ethers = { workspace = true }
expanded-pathbuf = { workspace = true }
eyre = { workspace = true }
log = "0.4.19"
pin-utils = "0.1"
silius-bundler = { path = "../../crates/bundler" }
silius-grpc = { path = "../../crates/grpc" }
silius-p2p = { path = "../../crates/p2p" }
silius-primitives = { path = "../../crates/primitives" }
silius-rpc = { path = "../../crates/rpc" }
tokio = { workspace = true }
Expand Down
3 changes: 3 additions & 0 deletions bin/silius/src/bundler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ where
args.min_priority_fee_per_gas,
args.whitelist,
args.uopool_mode,
args.p2p_opts.enable_p2p,
args.p2p_opts.to_config(),
args.p2p_opts.bootnodes,
)
.await?;

Expand Down
91 changes: 90 additions & 1 deletion bin/silius/src/cli/args.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use crate::utils::{parse_address, parse_send_bundle_mode, parse_u256, parse_uopool_mode};
use crate::utils::{
parse_address, parse_enr, parse_send_bundle_mode, parse_u256, parse_uopool_mode,
};
use clap::Parser;
use discv5::Enr;
use ethers::types::{Address, U256};
use expanded_pathbuf::ExpandedPathBuf;
use silius_p2p::config::{Config, ListenAddr};
use silius_primitives::{
bundler::SendBundleMode,
chain::SUPPORTED_CHAINS,
Expand Down Expand Up @@ -88,6 +92,9 @@ pub struct UoPoolArgs {
/// User operation mempool mode
#[clap(long, default_value = "standard", value_parser=parse_uopool_mode)]
pub uopool_mode: UoPoolMode,

#[clap(flatten)]
pub p2p_opts: P2POpts,
}

/// Common CLI args for bundler and uopool
Expand Down Expand Up @@ -211,8 +218,53 @@ pub struct CreateWalletArgs {
pub flashbots_key: bool,
}

#[derive(Clone, Debug, Parser, PartialEq)]
pub struct P2POpts {
/// enable p2p
#[clap(long)]
pub enable_p2p: bool,

/// Sets the p2p listen address.
#[clap(long, default_value = "0.0.0.0")]
pub p2p_listen_address: Ipv4Addr,

/// The ipv4 address to broadcast to peers about which address we are listening on.
#[clap(long)]
pub p2p_broadcast_address: Option<Ipv4Addr>,

/// The udp4 port to broadcast to peers in order to reach back for discovery.
#[clap(long, default_value = "4337")]
pub udp4_port: u16,

#[clap(long, default_value = "4337")]
pub tcp4_port: u16,

#[clap(long, value_delimiter = ',', value_parser=parse_enr)]
pub bootnodes: Vec<Enr>,
}

impl P2POpts {
pub fn to_config(&self) -> Config {
// TODO: support ipv6
Config {
listen_addr: silius_p2p::config::ListenAddress::Ipv4(ListenAddr {
addr: self.p2p_listen_address,
udp_port: self.udp4_port,
tcp_port: self.tcp4_port,
}),
ipv4_addr: self.p2p_broadcast_address,
ipv6_addr: None,
enr_udp4_port: Some(self.udp4_port),
enr_tcp4_port: Some(self.tcp4_port),
enr_udp6_port: None,
enr_tcp6_port: None,
}
}
}
#[cfg(test)]
mod tests {
use discv5::enr::{CombinedKey, EnrBuilder};

use super::*;
use std::{
net::{IpAddr, Ipv4Addr},
Expand Down Expand Up @@ -512,4 +564,41 @@ mod tests {
false
);
}

#[test]
fn p2p_opts() {
let key = CombinedKey::secp256k1_from_bytes([1; 32].as_mut()).unwrap();
let enr = EnrBuilder::new("v4")
.ip4(Ipv4Addr::new(8, 8, 8, 8))
.tcp4(4337)
.udp4(4337)
.build(&key)
.unwrap();
let binding = enr.clone().to_base64();
let args = vec![
"p2popts",
"--enable-p2p",
"--p2p-listen-address",
"0.0.0.0",
"--p2p-broadcast-address",
"127.0.0.1",
"--tcp4-port",
"4337",
"--udp4-port",
"4337",
"--bootnodes",
&binding,
];
assert_eq!(
P2POpts {
enable_p2p: true,
p2p_listen_address: Ipv4Addr::new(0, 0, 0, 0),
p2p_broadcast_address: Some(Ipv4Addr::new(127, 0, 0, 1)),
tcp4_port: 4337,
udp4_port: 4337,
bootnodes: vec![enr]
},
P2POpts::try_parse_from(args).unwrap()
)
}
}
12 changes: 4 additions & 8 deletions bin/silius/src/cli/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ impl BundlerCommand {
pub async fn execute(self) -> eyre::Result<()> {
if self.common.eth_client_address.clone().starts_with("http") {
let eth_client = Arc::new(create_http_provider(&self.common.eth_client_address).await?);
let block_streams =
create_http_block_streams(eth_client.clone(), self.common.entry_points.len()).await;
let block_streams = create_http_block_streams(eth_client.clone(), 1).await;
launch_bundler(
self.bundler,
self.uopool,
Expand All @@ -44,8 +43,7 @@ impl BundlerCommand {
.await?;
} else {
let eth_client = Arc::new(create_ws_provider(&self.common.eth_client_address).await?);
let block_streams =
create_ws_block_streams(eth_client.clone(), self.common.entry_points.len()).await;
let block_streams = create_ws_block_streams(eth_client.clone(), 1).await;
launch_bundler(
self.bundler,
self.uopool,
Expand Down Expand Up @@ -123,8 +121,7 @@ impl UoPoolCommand {
pub async fn execute(self) -> eyre::Result<()> {
if self.common.eth_client_address.clone().starts_with("http") {
let eth_client = Arc::new(create_http_provider(&self.common.eth_client_address).await?);
let block_streams =
create_http_block_streams(eth_client.clone(), self.common.entry_points.len()).await;
let block_streams = create_http_block_streams(eth_client.clone(), 1).await;
launch_uopool(
self.uopool,
eth_client,
Expand All @@ -135,8 +132,7 @@ impl UoPoolCommand {
.await?;
} else {
let eth_client = Arc::new(create_ws_provider(&self.common.eth_client_address).await?);
let block_streams =
create_ws_block_streams(eth_client.clone(), self.common.entry_points.len()).await;
let block_streams = create_ws_block_streams(eth_client.clone(), 1).await;
launch_uopool(
self.uopool,
eth_client,
Expand Down
6 changes: 6 additions & 0 deletions bin/silius/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use dirs::home_dir;
use discv5::Enr;
use ethers::types::{Address, U256};
use expanded_pathbuf::ExpandedPathBuf;
use pin_utils::pin_mut;
Expand Down Expand Up @@ -38,6 +39,11 @@ pub fn parse_uopool_mode(s: &str) -> Result<UoPoolMode, String> {
UoPoolMode::from_str(s).map_err(|_| format!("String {s} is not a valid UoPoolMode"))
}

/// Parse ENR record
pub fn parse_enr(enr: &str) -> Result<Enr, String> {
Enr::from_str(enr).map_err(|_| format!("Enr {enr} is not a valid enr."))
}

/// Runs the future to completion or until:
/// - `ctrl-c` is received.
/// - `SIGTERM` is received (unix only).
Expand Down
3 changes: 2 additions & 1 deletion crates/contracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ AA (ERC-4337) bundler smart contract interfaces
"""

[dependencies]

ethers = { workspace = true }
eyre = { workspace = true }
lazy_static = "1.4.0"
lazy_static = { workspace = true }
regex = "1.9.6"
serde = "1"
serde_json = "1"
Expand Down
8 changes: 8 additions & 0 deletions crates/contracts/src/entry_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,4 +451,12 @@ mod tests {
);
Ok(())
}

#[test]
fn deserialize_failedop() -> eyre::Result<()> {
let err_msg = Bytes::from_str("0x220266b600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e41413430206f76657220766572696669636174696f6e4761734c696d69740000")?;
let res = EntryPointAPIErrors::decode(err_msg)?;
println!("res: {:?}", res);
Ok(())
}
}
4 changes: 2 additions & 2 deletions crates/contracts/src/tracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ impl TryFrom<GethTrace> for JsTracerFrame {
fn try_from(val: GethTrace) -> Result<Self, Self::Error> {
match val {
GethTrace::Known(val) => Err(format_err!("Invalid geth trace: {val:?}")),
GethTrace::Unknown(val) => serde_json::from_value(val)
.map_err(|error| format_err!("Failed to parse geth trace: {error}")),
GethTrace::Unknown(val) => serde_json::from_value(val.clone())
.map_err(|error| format_err!("Failed to parse geth trace: {error}, {val:#}")),
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions crates/grpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@ AA (ERC-4337) bundler gRPC interfaces
arrayref = "0.3"
async-trait = { workspace = true }
dashmap = "5.4.0"
discv5 = { workspace = true }
ethers = { workspace = true }
expanded-pathbuf = { workspace = true }
eyre = { workspace = true }
futures = "0.3.28"
libp2p-identity = "0.2.3"
parking_lot = { workspace = true }
prost = "0.11"
serde_json = { workspace = true }
silius-bundler = { path = "../bundler" }
silius-contracts = { path = "../contracts" }
silius-p2p = { path = "../p2p" }
silius-primitives = { path = "../primitives" }
silius-uopool = { path = "../uopool" }
tokio = { workspace = true }
Expand Down
31 changes: 31 additions & 0 deletions crates/grpc/src/network.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use ethers::providers::Middleware;
use silius_p2p::network::Network;
use silius_primitives::reputation::ReputationEntry;
use silius_uopool::{Mempool, Reputation, VecCh, VecUo};

use crate::builder::UoPoolBuilder;

/// The Integrator is for the integrations between p2p network and the uopool
pub struct NetworkIntegrator<M, P, R, E>
where
M: Middleware + Clone + 'static,
P: Mempool<UserOperations = VecUo, CodeHashes = VecCh, Error = E> + Send + Sync,
R: Reputation<ReputationEntries = Vec<ReputationEntry>, Error = E> + Send + Sync,
{
network: Network,
uopool_builder: UoPoolBuilder<M, P, R, E>,
}

impl<M, P, R, E> NetworkIntegrator<M, P, R, E>
where
M: Middleware + Clone + 'static,
P: Mempool<UserOperations = VecUo, CodeHashes = VecCh, Error = E> + Send + Sync,
R: Reputation<ReputationEntries = Vec<ReputationEntry>, Error = E> + Send + Sync,
{
pub fn new(network: Network, uopool_builder: UoPoolBuilder<M, P, R, E>) -> Self {
Self {
network,
uopool_builder,
}
}
}
Loading

0 comments on commit d806606

Please sign in to comment.