#![allow(clippy::panic)]
use crate::{
rpc::{self, Client},
tx::Tx,
};
use std::{ffi::OsStr, panic, process, str, time::Duration};
use tendermint::Hash;
use tokio::time;
pub const GAIA_DOCKER_IMAGE: &str = "jackzampolin/gaiatest";
pub fn docker_run<A, S, F, R>(args: A, f: F) -> R
where
A: IntoIterator<Item = S>,
S: AsRef<OsStr>,
F: FnOnce() -> R + panic::UnwindSafe,
{
let container_id = exec_docker_command("run", args);
let result = panic::catch_unwind(f);
if result.is_err() {
let logs = exec_docker_command("logs", [&container_id]);
println!("\n---- docker stdout ----");
println!("{}", logs);
}
exec_docker_command("kill", [&container_id]);
match result {
Ok(res) => res,
Err(err) => panic::resume_unwind(err),
}
}
fn exec_docker_command<A, S>(name: &str, args: A) -> String
where
A: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
let output = process::Command::new("docker")
.arg(name)
.args(args)
.stdout(process::Stdio::piped())
.output()
.unwrap_or_else(|err| panic!("error invoking `docker {}`: {}", name, err));
if !output.status.success() {
panic!("`docker {}` exited with error status: {:?}", name, output);
}
str::from_utf8(&output.stdout)
.expect("UTF-8 error decoding docker output")
.trim_end()
.to_owned()
}
pub async fn poll_for_first_block(rpc_client: &rpc::HttpClient) {
rpc_client
.wait_until_healthy(Duration::from_secs(5))
.await
.expect("error waiting for RPC to return healthy responses");
let mut attempts_remaining = 25;
while let Err(e) = rpc_client.latest_block().await {
if !matches!(e.detail(), rpc::error::ErrorDetail::Serde(_)) {
panic!("unexpected error waiting for first block: {:?}", e);
}
if attempts_remaining == 0 {
panic!("timeout waiting for first block");
}
attempts_remaining -= 1;
time::sleep(Duration::from_millis(200)).await;
}
}
pub async fn poll_for_tx(rpc_client: &rpc::HttpClient, tx_hash: Hash) -> Tx {
let attempts = 5;
#[allow(clippy::unwrap_used)]
let tx_hash = tendermint::Hash::Sha256(tx_hash.as_ref().try_into().unwrap());
for _ in 0..attempts {
if let Ok(tx) = Tx::find_by_hash(rpc_client, tx_hash).await {
return tx;
}
}
panic!("couldn't find transaction after {} attempts!", attempts);
}