Skip to content
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 changes: 2 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
[alias]
surfpool-install = "install --path crates/cli --locked --force --features supervisor_ui --features version_check"
surfpool-install-dev = "install --path crates/cli --locked --force --features supervisor_ui"
# useful for local builds that point to local txtx crates - prevents conflicts with the supervisor_ui feature
surfpool-install-minimal = "install --path crates/cli --locked --force"
59 changes: 35 additions & 24 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/cli/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ pub struct StartSimnet {
#[clap(long = "features-all", action=ArgAction::SetTrue, default_value = "false")]
pub all_features: bool,
/// A set of inputs to use for the runbook (eg. surfpool start --runbook-input myInputs.json)
#[arg(long = "runbook-input", short = 'i', default_value = "./txtx.yml")]
#[arg(long = "runbook-input", short = 'i')]
pub runbook_input: Vec<String>,
}

Expand Down
12 changes: 7 additions & 5 deletions crates/cli/src/cli/simnet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use std::{
atomic::{AtomicBool, Ordering},
mpsc,
},
thread::sleep,
time::Duration,
};

Expand Down Expand Up @@ -137,6 +136,7 @@ pub async fn handle_start_local_surfnet_command(
let simnet_commands_tx_copy = simnet_commands_tx.clone();
let config_copy = config.clone();

let simnet_events_tx_for_thread = simnet_events_tx.clone();
let _handle = hiro_system_kit::thread_named("simnet")
.spawn(move || {
let future = start_local_surfnet(
Expand All @@ -148,17 +148,19 @@ pub async fn handle_start_local_surfnet_command(
geyser_events_rx,
);
if let Err(e) = hiro_system_kit::nestable_block_on(future) {
error!("Simnet exited with error: {e}");
sleep(Duration::from_millis(500));
std::process::exit(1);
// Send the error through the event channel so the main thread can handle it
let _ = simnet_events_tx_for_thread.send(SimnetEvent::Aborted(e.to_string()));
}
Ok::<(), String>(())
})
.map_err(|e| format!("{}", e))?;

loop {
match simnet_events_rx.recv() {
Ok(SimnetEvent::Aborted(error)) => return Err(error),
Ok(SimnetEvent::Aborted(error)) => {
eprintln!("Error: {}", error);
return Err(error);
}
Ok(SimnetEvent::Shutdown) => return Ok(()),
Ok(SimnetEvent::Ready) => break,
_other => continue,
Expand Down
38 changes: 35 additions & 3 deletions crates/core/src/runloops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,27 @@ use crate::{

const BLOCKHASH_SLOT_TTL: u64 = 75;

/// Checks if a port is available for binding.
fn check_port_availability(addr: SocketAddr, server_type: &str) -> Result<(), String> {
match std::net::TcpListener::bind(addr) {
Ok(_listener) => Ok(()),
Err(e) if e.kind() == std::io::ErrorKind::AddrInUse => {
let msg = format!(
"{} port {} is already in use. Try --port or --ws-port to use a different port.",
server_type,
addr.port()
);
eprintln!("Error: {}", msg);
Err(msg)
}
Err(e) => {
let msg = format!("Failed to bind {} server to {}: {}", server_type, addr, e);
eprintln!("Error: {}", msg);
Err(msg)
}
}
}

pub async fn start_local_surfnet_runloop(
svm_locker: SurfnetSvmLocker,
config: SurfpoolConfig,
Expand Down Expand Up @@ -721,6 +742,20 @@ async fn start_rpc_servers_runloop(
),
String,
> {
let rpc_addr: SocketAddr = config
.rpc
.get_rpc_base_url()
.parse()
.map_err(|e: std::net::AddrParseError| e.to_string())?;
let ws_addr: SocketAddr = config
.rpc
.get_ws_base_url()
.parse()
.map_err(|e: std::net::AddrParseError| e.to_string())?;

check_port_availability(rpc_addr, "RPC")?;
check_port_availability(ws_addr, "WebSocket")?;

let (plugin_manager_commands_tx, plugin_manager_commands_rx) = unbounded();
let simnet_events_tx = svm_locker.simnet_events_tx();

Expand Down Expand Up @@ -762,9 +797,6 @@ async fn start_http_rpc_server_runloop(
io.extend_with(rpc::admin::SurfpoolAdminRpc.to_delegate());
}

let _ = std::net::TcpListener::bind(server_bind)
.map_err(|e| format!("Failed to start RPC server: {}", e))?;

let _handle = hiro_system_kit::thread_named("RPC Handler")
.spawn(move || {
let server = match ServerBuilder::new(io)
Expand Down
Loading