Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
10 changes: 8 additions & 2 deletions anvil/src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,14 @@ pub struct NodeArgs {
pub no_mining: bool,

/// The host the server will listen on.
Comment thread
0xZerohero marked this conversation as resolved.
Outdated
#[clap(long, value_name = "IP_ADDR", env = "ANVIL_IP_ADDR", help_heading = "Server options")]
pub host: Option<IpAddr>,
#[clap(
long,
value_name = "IP_ADDR",
env = "ANVIL_IP_ADDR",
default_value = "127.0.0.1",
help_heading = "Server options"
)]
pub host: Vec<IpAddr>,
Comment thread
0xZerohero marked this conversation as resolved.

/// How transactions are sorted in the mempool.
#[clap(long, default_value = "fees")]
Expand Down
13 changes: 9 additions & 4 deletions anvil/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,12 @@ use foundry_evm::{
use parking_lot::RwLock;
use serde_json::{json, to_writer, Value};
use std::{
collections::HashMap, fmt::Write as FmtWrite, fs::File, net::IpAddr, path::PathBuf, sync::Arc,
collections::HashMap,
fmt::Write as FmtWrite,
fs::File,
net::{IpAddr, Ipv4Addr},
path::PathBuf,
sync::Arc,
time::Duration,
};
use yansi::Paint;
Expand Down Expand Up @@ -128,7 +133,7 @@ pub struct NodeConfig {
/// How to configure the server
pub server_config: ServerConfig,
/// The host the server will listen on
pub host: Option<IpAddr>,
pub host: Vec<IpAddr>,
/// How transactions are sorted in the mempool
pub transaction_order: TransactionOrder,
/// Filename to write anvil output as json
Expand Down Expand Up @@ -376,7 +381,7 @@ impl Default for NodeConfig {
enable_steps_tracing: false,
no_storage_caching: false,
server_config: Default::default(),
host: None,
host: vec![IpAddr::V4(Ipv4Addr::LOCALHOST)],
transaction_order: Default::default(),
config_out: None,
genesis: None,
Expand Down Expand Up @@ -707,7 +712,7 @@ impl NodeConfig {

/// Sets the host the server will listen on
#[must_use]
pub fn with_host(mut self, host: Option<IpAddr>) -> Self {
pub fn with_host(mut self, host: Vec<IpAddr>) -> Self {
self.host = host;
self
}
Expand Down
48 changes: 33 additions & 15 deletions anvil/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use parking_lot::Mutex;
use std::{
future::Future,
io,
net::{IpAddr, Ipv4Addr, SocketAddr},
net::SocketAddr,
pin::Pin,
sync::Arc,
task::{Context, Poll},
Expand Down Expand Up @@ -162,15 +162,19 @@ pub async fn spawn(mut config: NodeConfig) -> (EthApi, NodeHandle) {
let node_service =
tokio::task::spawn(NodeService::new(pool, backend, miner, fee_history_service, filters));

let host = config.host.unwrap_or(IpAddr::V4(Ipv4Addr::LOCALHOST));
let mut addr = SocketAddr::new(host, port);
let mut servers = Vec::new();
let mut addresses = Vec::new();

// configure the rpc server and use its actual local address
let server = server::serve(addr, api.clone(), server_config);
addr = server.local_addr();
for addr in config.host.iter() {
Comment thread
0xZerohero marked this conversation as resolved.
let sock_addr = SocketAddr::new(addr.to_owned(), port);
let srv = server::serve(sock_addr, api.clone(), server_config.clone());

// spawn the server on a new task
let serve = tokio::task::spawn(server.map_err(NodeError::from));
addresses.push(srv.local_addr());

// spawn the server on a new task
let srv = tokio::task::spawn(srv.map_err(NodeError::from));
servers.push(srv);
}

let tokio_handle = Handle::current();
let (signal, on_shutdown) = shutdown::signal();
Expand All @@ -181,9 +185,9 @@ pub async fn spawn(mut config: NodeConfig) -> (EthApi, NodeHandle) {
let handle = NodeHandle {
config,
node_service,
server: serve,
servers,
ipc_task,
address: addr,
addresses,
_signal: Some(signal),
task_manager,
};
Expand All @@ -201,11 +205,11 @@ type IpcTask = JoinHandle<io::Result<()>>;
pub struct NodeHandle {
config: NodeConfig,
/// The address of the running rpc server
address: SocketAddr,
addresses: Vec<SocketAddr>,
/// Join handle for the Node Service
pub node_service: JoinHandle<Result<(), NodeError>>,
/// Join handle for the Anvil server
pub server: JoinHandle<Result<(), NodeError>>,
pub servers: Vec<JoinHandle<Result<(), NodeError>>>,
Comment thread
0xZerohero marked this conversation as resolved.
// The future that joins the ipc server, if any
ipc_task: Option<IpcTask>,
/// A signal that fires the shutdown, fired on drop.
Expand All @@ -224,7 +228,14 @@ impl NodeHandle {
pub(crate) fn print(&self, fork: Option<&ClientFork>) {
self.config.print(fork);
if !self.config.silent {
println!("Listening on {}", self.socket_address())
println!(
"Listening on {}",
self.addresses
.iter()
.map(|addr| { addr.to_string() })
.collect::<Vec<String>>()
.join(", ")
)
}
}

Expand All @@ -233,7 +244,7 @@ impl NodeHandle {
/// **N.B.** this may not necessarily be the same `host + port` as configured in the
/// `NodeConfig`, if port was set to 0, then the OS auto picks an available port
pub fn socket_address(&self) -> &SocketAddr {
&self.address
&self.addresses[0]
}

/// Returns the http endpoint
Expand Down Expand Up @@ -352,7 +363,14 @@ impl Future for NodeHandle {
return Poll::Ready(res)
}

pin.server.poll_unpin(cx)
// poll the axum server handles
for server in pin.servers.iter_mut() {
if let Poll::Ready(res) = server.poll_unpin(cx) {
return Poll::Ready(res)
}
}

Poll::Pending
}
}

Expand Down