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

Add p2p crate #151

Merged
merged 1 commit into from
Nov 2, 2023
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
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
Loading