Skip to content

Commit cc421e8

Browse files
authored
linera-service: faucet URL env var (#4710)
## Motivation Quality of life: it's pretty annoying when using `linera net up` to have to repeat the faucet URL all the time. ## Proposal Support setting the faucet URL through an environment variable for the CLI, akin to `LINERA_WALLET` and friends. This reduces the need for repeating the URL a lot when testing on a local network. ## Test Plan Used locally. ## Release Plan - Nothing to do / These changes follow the usual release cycle. ## Links - [reviewer checklist](https://github.com/linera-io/linera-protocol/blob/main/CONTRIBUTING.md#reviewer-checklist)
1 parent 84d2123 commit cc421e8

File tree

9 files changed

+81
-49
lines changed

9 files changed

+81
-49
lines changed

CLI.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -989,7 +989,9 @@ Initialize a wallet from the genesis configuration
989989

990990
###### **Options:**
991991

992-
* `--genesis <GENESIS_CONFIG_PATH>` — The path to the genesis configuration for a Linera deployment. Either this or `--faucet` must be specified
992+
* `--genesis <GENESIS_CONFIG_PATH>` — The path to the genesis configuration for a Linera deployment. Either this or `--faucet` must be specified.
993+
994+
Overrides `--faucet` if provided.
993995
* `--faucet <FAUCET>` — The address of a faucet
994996
* `--testing-prng-seed <TESTING_PRNG_SEED>` — Force this wallet to generate keys using a PRNG and a given seed. USE FOR TESTING ONLY
995997

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

linera-service/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ fs_extra = { workspace = true, optional = true }
8989
futures.workspace = true
9090
heck.workspace = true
9191
http.workspace = true
92+
insta.workspace = true
9293
k8s-openapi = { workspace = true, optional = true }
9394
kube = { workspace = true, optional = true }
9495
linera-base.workspace = true

linera-service/src/cli/command.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ pub enum BenchmarkCommand {
138138
processes: usize,
139139

140140
/// The faucet (which implicitly defines the network)
141-
#[arg(long)]
141+
#[arg(long, env = "LINERA_FAUCET_URL")]
142142
faucet: String,
143143

144144
/// If specified, a directory with a random name will be created in this directory, and the
@@ -1212,11 +1212,13 @@ pub enum WalletCommand {
12121212
Init {
12131213
/// The path to the genesis configuration for a Linera deployment. Either this or `--faucet`
12141214
/// must be specified.
1215+
///
1216+
/// Overrides `--faucet` if provided.
12151217
#[arg(long = "genesis")]
12161218
genesis_config_path: Option<PathBuf>,
12171219

12181220
/// The address of a faucet.
1219-
#[arg(long = "faucet")]
1221+
#[arg(long, env = "LINERA_FAUCET_URL")]
12201222
faucet: Option<String>,
12211223

12221224
/// Force this wallet to generate keys using a PRNG and a given seed. USE FOR
@@ -1228,7 +1230,7 @@ pub enum WalletCommand {
12281230
/// Request a new chain from a faucet and add it to the wallet.
12291231
RequestChain {
12301232
/// The address of a faucet.
1231-
#[arg(long)]
1233+
#[arg(long, env = "LINERA_FAUCET_URL")]
12321234
faucet: String,
12331235

12341236
/// Whether this chain should become the default chain.

linera-service/src/cli/main.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,8 +1589,12 @@ impl Runnable for Job {
15891589
);
15901590
}
15911591

1592-
Wallet(WalletCommand::Init { faucet, .. }) => {
1593-
let Some(faucet_url) = faucet else {
1592+
Wallet(WalletCommand::Init {
1593+
faucet,
1594+
genesis_config_path,
1595+
..
1596+
}) => {
1597+
let (Some(faucet_url), None) = (faucet, genesis_config_path) else {
15941598
return Ok(());
15951599
};
15961600
let Some(network_description) = storage.read_network_description().await? else {
@@ -2448,7 +2452,10 @@ async fn run(options: &ClientOptions) -> Result<i32, Error> {
24482452
} => {
24492453
let start_time = Instant::now();
24502454
let genesis_config: GenesisConfig = match (genesis_config_path, faucet) {
2451-
(Some(genesis_config_path), None) => util::read_json(genesis_config_path)?,
2455+
(None, None) => {
2456+
anyhow::bail!("please specify one of `--faucet` or `--genesis`.")
2457+
}
2458+
(Some(genesis_config_path), _) => util::read_json(genesis_config_path)?,
24522459
(None, Some(url)) => {
24532460
let faucet = cli_wrappers::Faucet::new(url.clone());
24542461
let version_info = faucet
@@ -2474,7 +2481,6 @@ Make sure to use a Linera client compatible with this network.
24742481
.await
24752482
.context("Failed to obtain the genesis configuration from the faucet")?
24762483
}
2477-
(_, _) => bail!("Either --faucet or --genesis must be specified, but not both"),
24782484
};
24792485
let mut keystore = options.create_keystore(*testing_prng_seed)?;
24802486
keystore.persist().await?;

linera-service/src/cli/net_up_utils.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -318,21 +318,21 @@ async fn print_messages_and_create_faucet(
318318
"{}",
319319
format!(
320320
"export LINERA_WALLET=\"{}\"",
321-
client.wallet_path().display()
321+
client.wallet_path().display(),
322322
)
323-
.bold()
323+
.bold(),
324324
);
325325
println!(
326326
"{}",
327327
format!(
328328
"export LINERA_KEYSTORE=\"{}\"",
329-
client.keystore_path().display()
329+
client.keystore_path().display(),
330330
)
331331
.bold()
332332
);
333333
println!(
334334
"{}",
335-
format!("export LINERA_STORAGE=\"{}\"\n", client.storage_path()).bold()
335+
format!("export LINERA_STORAGE=\"{}\"", client.storage_path()).bold(),
336336
);
337337

338338
let wallet = client.load_wallet()?;
@@ -344,16 +344,23 @@ async fn print_messages_and_create_faucet(
344344
assert!(
345345
num_other_initial_chains > faucet_chain_idx,
346346
"num_other_initial_chains must be strictly greater than the faucet chain index if \
347-
with_faucet is true"
347+
with_faucet is true"
348+
);
349+
350+
eprintln!("To connect to this network, you can use the following faucet URL:");
351+
println!(
352+
"{}",
353+
format!("export LINERA_FAUCET_URL=\"http://localhost:{faucet_port}\"").bold(),
348354
);
355+
349356
// This picks a lexicographically faucet_chain_idx-th non-admin chain.
350357
Some(
351358
chains
352359
.into_iter()
353360
.filter(|chain_id| *chain_id != wallet.genesis_admin_chain())
354361
.nth(faucet_chain_idx as usize)
355-
.unwrap(),
356-
) // we checked that there are enough chains above, so this should be safe
362+
.expect("there should be at least one non-admin chain"),
363+
)
357364
} else {
358365
None
359366
};
@@ -365,6 +372,8 @@ async fn print_messages_and_create_faucet(
365372
None
366373
};
367374

375+
println!();
376+
368377
eprintln!(
369378
"\nREADY!\nPress ^C to terminate the local test network and clean the temporary directory."
370379
);

linera-service/src/cli_wrappers/wallet.rs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ use tokio::{
4343
sync::oneshot,
4444
task::JoinHandle,
4545
};
46-
use tracing::{error, info, warn};
4746

4847
use crate::{
4948
cli::command::BenchmarkCommand,
@@ -486,10 +485,10 @@ impl ClientWrapper {
486485
.send()
487486
.await;
488487
if request.is_ok() {
489-
info!("Node service has started");
488+
tracing::info!("Node service has started");
490489
return Ok(NodeService::new(port, child));
491490
} else {
492-
warn!("Waiting for node service to start");
491+
tracing::warn!("Waiting for node service to start");
493492
}
494493
}
495494
bail!("Failed to start node service");
@@ -568,10 +567,10 @@ impl ClientWrapper {
568567
.send()
569568
.await;
570569
if request.is_ok() {
571-
info!("Faucet has started");
570+
tracing::info!("Faucet has started");
572571
return Ok(FaucetService::new(port, child, temp_dir));
573572
} else {
574-
warn!("Waiting for faucet to start");
573+
tracing::debug!("Waiting for faucet to start");
575574
}
576575
}
577576
bail!("Failed to start faucet");
@@ -1120,7 +1119,7 @@ impl ClientWrapper {
11201119

11211120
let contract_size = fs_err::tokio::metadata(&contract).await?.len();
11221121
let service_size = fs_err::tokio::metadata(&service).await?.len();
1123-
info!("Done building application {name}: contract_size={contract_size}, service_size={service_size}");
1122+
tracing::info!("Done building application {name}: contract_size={contract_size}, service_size={service_size}");
11241123

11251124
Ok((contract, service))
11261125
}
@@ -1135,12 +1134,14 @@ impl Drop for ClientWrapper {
11351134
}
11361135

11371136
let Ok(binary_path) = self.binary_path.lock() else {
1138-
error!("Failed to close chains because a thread panicked with a lock to `binary_path`");
1137+
tracing::error!(
1138+
"Failed to close chains because a thread panicked with a lock to `binary_path`"
1139+
);
11391140
return;
11401141
};
11411142

11421143
let Some(binary_path) = binary_path.as_ref() else {
1143-
warn!(
1144+
tracing::warn!(
11441145
"Assuming no chains need to be closed, because the command binary was never \
11451146
resolved and therefore presumably never called"
11461147
);
@@ -1159,17 +1160,17 @@ impl Drop for ClientWrapper {
11591160
.args(["wallet", "show", "--short", "--owned"])
11601161
.output()
11611162
else {
1162-
warn!("Failed to execute `wallet show --short` to list chains to close");
1163+
tracing::warn!("Failed to execute `wallet show --short` to list chains to close");
11631164
return;
11641165
};
11651166

11661167
if !wallet_show_output.status.success() {
1167-
warn!("Failed to list chains in the wallet to close them");
1168+
tracing::warn!("Failed to list chains in the wallet to close them");
11681169
return;
11691170
}
11701171

11711172
let Ok(chain_list_string) = String::from_utf8(wallet_show_output.stdout) else {
1172-
warn!(
1173+
tracing::warn!(
11731174
"Failed to close chains because `linera wallet show --short` \
11741175
returned a non-UTF-8 output"
11751176
);
@@ -1192,8 +1193,8 @@ impl Drop for ClientWrapper {
11921193

11931194
match close_chain_command.args(["close-chain", chain_id]).status() {
11941195
Ok(status) if status.success() => (),
1195-
Ok(failure) => warn!("Failed to close chain {chain_id}: {failure}"),
1196-
Err(error) => warn!("Failed to close chain {chain_id}: {error}"),
1196+
Ok(failure) => tracing::warn!("Failed to close chain {chain_id}: {failure}"),
1197+
Err(error) => tracing::warn!("Failed to close chain {chain_id}: {error}"),
11971198
}
11981199
}
11991200
}
@@ -1412,7 +1413,7 @@ impl NodeService {
14121413
.send()
14131414
.await;
14141415
if matches!(result, Err(ref error) if error.is_timeout()) {
1415-
warn!(
1416+
tracing::warn!(
14161417
"Timeout when sending query {} to the node service",
14171418
truncate_query_output(query)
14181419
);
@@ -1435,7 +1436,7 @@ impl NodeService {
14351436
);
14361437
let value: Value = response.json().await.context("invalid JSON")?;
14371438
if let Some(errors) = value.get("errors") {
1438-
warn!(
1439+
tracing::warn!(
14391440
"Query \"{}\" failed: {}",
14401441
truncate_query_output(query),
14411442
errors
@@ -1617,7 +1618,7 @@ impl<A> ApplicationWrapper<A> {
16171618
let response = match result {
16181619
Ok(response) => response,
16191620
Err(error) if i < MAX_RETRIES => {
1620-
warn!(
1621+
tracing::warn!(
16211622
"Failed to post query \"{}\": {error}; retrying",
16221623
truncate_query_output_serialize(&query),
16231624
);

linera-service/tests/local_net_tests.rs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -712,37 +712,40 @@ async fn test_storage_service_linera_net_up_simple() -> Result<()> {
712712
let mut lines = stderr.lines();
713713

714714
let mut is_ready = false;
715+
eprintln!("waiting for network to be ready");
715716
for line in &mut lines {
716717
let line = line?;
718+
eprintln!("[net up]: {line}");
717719
if line.starts_with("READY!") {
718720
is_ready = true;
719721
break;
720722
}
721723
}
722-
assert!(is_ready, "Unexpected EOF for stderr");
724+
725+
if !is_ready {
726+
assert!(is_ready, "unexpected EOF for stderr");
727+
} else {
728+
eprintln!("network is ready");
729+
}
723730

724731
// Echo faucet stderr for debugging and to empty the buffer.
725732
std::thread::spawn(move || {
726733
for line in lines {
727-
let line = line.unwrap();
728-
eprintln!("{}", line);
734+
eprintln!("[net up] {}", line.unwrap());
729735
}
730736
});
731737

732-
let mut exports = stdout.lines();
733-
assert!(exports
734-
.next()
735-
.unwrap()?
736-
.starts_with("export LINERA_WALLET="));
737-
assert!(exports
738-
.next()
739-
.unwrap()?
740-
.starts_with("export LINERA_KEYSTORE="));
741-
assert!(exports
742-
.next()
743-
.unwrap()?
744-
.starts_with("export LINERA_STORAGE="));
745-
assert_eq!(exports.next().unwrap()?, "");
738+
insta::assert_snapshot!(stdout
739+
.lines()
740+
.map_while(|line| {
741+
println!("{line:?}");
742+
line.unwrap()
743+
.split_once("=")
744+
.map(|x| x.0.to_owned())
745+
.filter(|line| line.starts_with("export"))
746+
})
747+
.collect::<Vec<_>>()
748+
.join("\n"));
746749

747750
// Test faucet.
748751
let faucet = Faucet::new(format!("http://localhost:{}/", port));
@@ -753,7 +756,6 @@ async fn test_storage_service_linera_net_up_simple() -> Result<()> {
753756
.args(["-s", "INT", &child.id().to_string()])
754757
.output()?;
755758

756-
assert!(exports.next().is_none());
757759
assert!(child.wait()?.success());
758760
return Ok(());
759761
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
source: linera-service/tests/local_net_tests.rs
3+
expression: "stdout.lines().map_while(|line|\n{\n println!(\"{line:?}\");\n line.unwrap().split_once(\"=\").map(|x|\n x.0.to_owned()).filter(|line| line.starts_with(\"export\"))\n}).collect::<Vec<_>>().join(\"\\n\")"
4+
---
5+
export LINERA_WALLET
6+
export LINERA_KEYSTORE
7+
export LINERA_STORAGE
8+
export LINERA_FAUCET_URL

0 commit comments

Comments
 (0)