diff --git a/.changelog/unreleased/bug-fixes/2310-wait-for-genesis-time.md b/.changelog/unreleased/bug-fixes/2310-wait-for-genesis-time.md new file mode 100644 index 0000000000..0d8c8ab34f --- /dev/null +++ b/.changelog/unreleased/bug-fixes/2310-wait-for-genesis-time.md @@ -0,0 +1 @@ + - Make the ledger wait for genesis before starting up any processes ([\#2310](https://github.com/anoma/namada/pull/2310)) \ No newline at end of file diff --git a/apps/src/lib/node/ledger/mod.rs b/apps/src/lib/node/ledger/mod.rs index 11bd75aba5..c5188f5c7b 100644 --- a/apps/src/lib/node/ledger/mod.rs +++ b/apps/src/lib/node/ledger/mod.rs @@ -17,6 +17,7 @@ use futures::future::TryFutureExt; use namada::core::ledger::governance::storage::keys as governance_storage; use namada::eth_bridge::ethers::providers::{Http, Provider}; use namada::types::storage::Key; +use namada::types::time::{DateTimeUtc, Utc}; use namada_sdk::tendermint::abci::request::CheckTxKind; use once_cell::unsync::Lazy; use sysinfo::{RefreshKind, System, SystemExt}; @@ -241,6 +242,12 @@ pub fn rollback(config: config::Ledger) -> Result<(), shell::Error> { /// /// All must be alive for correct functioning. async fn run_aux(config: config::Ledger, wasm_dir: PathBuf) { + // wait for genesis time + let genesis_time = DateTimeUtc::try_from(config.genesis_time.clone()) + .expect("Should be able to parse genesis time"); + if let std::ops::ControlFlow::Break(_) = sleep_until(genesis_time).await { + return; + } let setup_data = run_aux_setup(&config, &wasm_dir).await; // Create an `AbortableSpawner` for signalling shut down from the shell or @@ -748,3 +755,36 @@ async fn maybe_start_ethereum_oracle( fn spawn_dummy_task(ready: T) -> task::JoinHandle { tokio::spawn(async { std::future::ready(ready).await }) } + +/// Sleep until the genesis time if necessary. +async fn sleep_until(time: DateTimeUtc) -> std::ops::ControlFlow<()> { + // Sleep until start time if needed + let sleep = async { + if let Ok(sleep_time) = + time.0.signed_duration_since(Utc::now()).to_std() + { + if !sleep_time.is_zero() { + tracing::info!( + "Waiting for ledger genesis time: {:?}, time left: {:?}", + time, + sleep_time + ); + tokio::time::sleep(sleep_time).await + } + } + }; + let shutdown_signal = async { + let (tx, rx) = tokio::sync::oneshot::channel(); + namada_sdk::control_flow::shutdown_send(tx).await; + rx.await + }; + tokio::select! { + _ = shutdown_signal => { + std::ops::ControlFlow::Break(()) + } + _ = sleep => { + tracing::info!("Genesis time reached, starting ledger"); + std::ops::ControlFlow::Continue(()) + } + } +} diff --git a/sdk/src/control_flow/mod.rs b/sdk/src/control_flow/mod.rs index 9b75b6e921..42294d5191 100644 --- a/sdk/src/control_flow/mod.rs +++ b/sdk/src/control_flow/mod.rs @@ -66,7 +66,7 @@ pub fn install_shutdown_signal() -> ShutdownSignal { } #[cfg(unix)] -async fn shutdown_send(tx: oneshot::Sender<()>) { +pub async fn shutdown_send(tx: oneshot::Sender<()>) { use tokio::signal::unix::{signal, SignalKind}; let mut sigterm = signal(SignalKind::terminate()).unwrap(); let mut sighup = signal(SignalKind::hangup()).unwrap(); @@ -107,7 +107,7 @@ async fn shutdown_send(tx: oneshot::Sender<()>) { } #[cfg(windows)] -async fn shutdown_send(tx: oneshot::Sender<()>) { +pub async fn shutdown_send(tx: oneshot::Sender<()>) { let mut sigbreak = tokio::signal::windows::ctrl_break().unwrap(); tokio::select! { signal = tokio::signal::ctrl_c() => {