| 492 | } |
| 493 | })?; |
| 494 | |
| 495 | println!("Waiting for all nodes to shut down..."); |
| 496 | for (idx, node_runtime) in node_runtimes.into_iter().enumerate() { |
| 497 | println!("Waiting for node index {} to join...", idx); |
| 498 | match node_runtime.thread.join() { |
| 499 | Ok(_) => println!("Node index {} thread joined successfully", idx), |
| 500 | // A join failure means the node panicked or was killed: a required |
| 501 | // participant going down unexpectedly, so fail the scenario. |
| 502 | Err(e) => { |
| 503 | eprintln!("Node index {} thread join failed: {:?}", idx, e); |
| 504 | std::process::exit(1); |
| 505 | } |
| 506 | } |
| 507 | } |
| 508 | |
| 509 | println!("All nodes shut down cleanly"); |
| 510 | std::process::exit(0); |
| 511 | } |
| 512 | |
| 513 | async fn get_latest_height(rpc_port: u16) -> Result<u64, Box<dyn std::error::Error>> { |
| 514 | let url = format!("http://localhost:{}", rpc_port); |
| 515 | let client = HttpClientBuilder::default().build(&url)?; |
| 516 | let height = client.get_latest_height().await?; |
| 517 | Ok(height) |
| 518 | } |
| 519 | |
| 520 | async fn fetch_latest_checkpoint( |
| 521 | rpc_port: u16, |