Skip to content
5 changes: 1 addition & 4 deletions crates/sui-indexer-alt-reader/src/consistent_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,7 @@ impl ConsistentReader {
endpoint = endpoint.timeout(timeout);
}

let channel = endpoint
.connect()
.await
.context("Failed to connect to gRPC endpoint")?;
let channel = endpoint.connect_lazy();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to connect lazily, as otherwise the grpc server might not be ready and the whole system errors due to being unable to connect to server.


Some(ConsistentServiceClient::new(channel))
} else {
Expand Down
4 changes: 1 addition & 3 deletions crates/sui-indexer-alt-reader/src/fullnode_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,7 @@ impl FullnodeClient {
let execution_client = if let Some(url) = &args.fullnode_rpc_url {
let channel = Channel::from_shared(url.clone())
.context("Failed to create channel for gRPC endpoint")?
.connect()
.await
.context("Failed to connect to gRPC endpoint")?;
.connect_lazy();

Some(TransactionExecutionServiceClient::new(channel))
} else {
Expand Down
6 changes: 1 addition & 5 deletions crates/sui-indexer-alt-reader/src/ledger_grpc_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,7 @@ impl LedgerGrpcReader {
if let Some(timeout) = args.statement_timeout() {
endpoint = endpoint.timeout(timeout);
}
let channel = endpoint
.tls_config(tls_config)?
.connect()
.await
.context("Failed to connect to gRPC endpoint")?;
let channel = endpoint.tls_config(tls_config)?.connect_lazy();

let client = LedgerServiceClient::new(channel.clone());
Ok(Self(client))
Expand Down
10 changes: 5 additions & 5 deletions crates/sui-keys/src/keystore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ impl FileBasedKeystore {
});

let reader =
BufReader::new(std::fs::File::open(path).with_context(|| {
BufReader::new(fs::File::open(path).with_context(|| {
format!("Cannot open the keystore file: {}", path.display())
})?);
let kp_strings: Vec<String> = serde_json::from_reader(reader).with_context(|| {
Expand All @@ -430,7 +430,7 @@ impl FileBasedKeystore {
aliases_path.set_extension(ALIASES_FILE_EXTENSION);

let aliases = if aliases_path.exists() {
let reader = BufReader::new(std::fs::File::open(&aliases_path).with_context(|| {
let reader = BufReader::new(fs::File::open(&aliases_path).with_context(|| {
format!(
"Cannot open aliases file in keystore: {}",
aliases_path.display()
Expand Down Expand Up @@ -484,7 +484,7 @@ impl FileBasedKeystore {
)
})?;

std::fs::write(aliases_path, aliases_store)?;
fs::write(aliases_path, aliases_store)?;
aliases
};

Expand Down Expand Up @@ -513,7 +513,7 @@ impl FileBasedKeystore {
let mut aliases_path = path.clone();
aliases_path.set_extension(ALIASES_FILE_EXTENSION);
// no reactor for tokio::fs::write in simtest, so we use spawn_blocking
tokio::task::spawn_blocking(move || std::fs::write(aliases_path, aliases_store))
tokio::task::spawn_blocking(move || fs::write(aliases_path, aliases_store))
.await?
.with_context(|| format!("Cannot write aliases to file: {}", path.display()))?;
}
Expand All @@ -536,7 +536,7 @@ impl FileBasedKeystore {
let keystore_path = path.clone();
// no reactor for tokio::fs::write in simtest, so we use spawn_blocking
tokio::task::spawn_blocking(move || {
let ret = std::fs::write(&keystore_path, store);
let ret = fs::write(&keystore_path, store);
#[cfg(unix)]
if ret.is_ok() {
let _ = set_reduced_file_permissions(&keystore_path).inspect_err(|error| {
Expand Down
55 changes: 33 additions & 22 deletions crates/sui/src/sui_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use prometheus::Registry;
use rand::rngs::OsRng;
use std::collections::BTreeMap;
use std::io::{Write, stdout};
use std::net::{AddrParseError, IpAddr, Ipv4Addr, SocketAddr};
use std::net::{AddrParseError, IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
use std::num::NonZeroUsize;
use std::ops::Deref;
use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -1049,7 +1049,8 @@ async fn start(
tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
info!("Cluster started");

let fullnode_rpc_url = format!("http://{fullnode_rpc_address}");
let fullnode_rpc_ip = normalize_bind_addr(fullnode_rpc_address);
let fullnode_rpc_url = format!("http://{fullnode_rpc_ip}:{}", fullnode_rpc_address.port());
info!("Fullnode RPC URL: {fullnode_rpc_url}");

let prometheus_registry = Registry::new();
Expand Down Expand Up @@ -1151,7 +1152,7 @@ async fn start(
rpc_services.push(handle);

info!("Consistent Store started at {address}");
Some(format!("http://{address}"))
Some(address)
} else {
None
};
Expand All @@ -1167,12 +1168,9 @@ async fn start(
no_ide: false,
};

let consistent_store_url = consistent_store_url.map(socket_addr_to_url).transpose()?;
let consistent_reader_args = ConsistentReaderArgs {
consistent_store_url: consistent_store_url
.as_ref()
.map(|url| Url::parse(url))
.transpose()
.context("Failed to parse consistent store URL")?,
consistent_store_url,
..Default::default()
};

Expand Down Expand Up @@ -1223,6 +1221,7 @@ async fn start(
if let Some(input) = with_faucet {
let faucet_address = parse_host_port(input, DEFAULT_FAUCET_PORT)
.map_err(|_| anyhow!("Invalid faucet host and port"))?;

info!("Starting the faucet service at {faucet_address}");

let host_ip = match faucet_address {
Expand All @@ -1247,12 +1246,13 @@ async fn start(
.import(None, SuiKeyPair::Ed25519(kp))
.await
.unwrap();

SuiClientConfig {
keystore,
external_keys: None,
envs: vec![SuiEnv {
alias: "localnet".to_string(),
rpc: fullnode_rpc_url,
rpc: fullnode_rpc_url.clone(),
ws: None,
basic_auth: None,
chain_id: None,
Expand Down Expand Up @@ -1542,21 +1542,15 @@ async fn genesis(
client_config.active_address = active_address;
}

// On windows, using 0.0.0.0 will usually yield in an networking error. This localnet ip
// address must bind to 127.0.0.1 if the default 0.0.0.0 is used.
let localnet_ip =
if fullnode_config.json_rpc_address.ip() == IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)) {
"127.0.0.1".to_string()
} else {
fullnode_config.json_rpc_address.ip().to_string()
};
let rpc = format!(
"http://{}:{}",
normalize_bind_addr(fullnode_config.json_rpc_address),
fullnode_config.json_rpc_address.port()
);

client_config.add_env(SuiEnv {
alias: "localnet".to_string(),
rpc: format!(
"http://{}:{}",
localnet_ip,
fullnode_config.json_rpc_address.port()
),
rpc,
ws: None,
basic_auth: None,
chain_id: None,
Expand Down Expand Up @@ -1868,3 +1862,20 @@ pub async fn get_replay_node(context: &WalletContext) -> Result<SR2::Node, anyho
Chain::Unknown => bail!(err_msg),
})
}

/// Converts a socket address to a Url by setting the scheme to HTTP.
fn socket_addr_to_url(addr: SocketAddr) -> Result<Url, anyhow::Error> {
let ip = normalize_bind_addr(addr);
Url::parse(&format!("http://{ip}:{}", addr.port()))
.with_context(|| format!("Failed to parse {addr} into a Url"))
}

/// Resolves an unspecified ip address to a localhost IP address. Particularly on Windows, clients
/// cannot connect to 0.0.0.0 addresses.
fn normalize_bind_addr(addr: SocketAddr) -> IpAddr {
match addr.ip() {
IpAddr::V4(v4) if v4.is_unspecified() => IpAddr::V4(Ipv4Addr::LOCALHOST),
IpAddr::V6(v6) if v6.is_unspecified() => IpAddr::V6(Ipv6Addr::LOCALHOST),
ip => ip,
}
}
Loading