|
1 |
| -//! `start` subcommand |
| 1 | +use std::future::Future; |
| 2 | +use std::time::{Duration, SystemTime}; |
2 | 3 |
|
3 |
| -/// App-local prelude includes `app_reader()`/`app_writer()`/`app_config()` |
4 |
| -/// accessors along with logging macros. Customize as you see fit. |
| 4 | +// use crate::application::APPLICATION; |
5 | 5 | use crate::prelude::*;
|
6 | 6 |
|
7 | 7 | use abscissa_core::{Command, Options, Runnable};
|
8 | 8 |
|
9 |
| -/// `start` subcommand |
10 |
| -/// |
11 |
| -/// The `Options` proc macro generates an option parser based on the struct |
12 |
| -/// definition, and is defined in the `gumdrop` crate. See their documentation |
13 |
| -/// for a more comprehensive example: |
14 |
| -/// |
15 |
| -/// <https://docs.rs/gumdrop/> |
| 9 | +use tendermint::lite::types::Header; |
| 10 | + |
| 11 | +use relayer::chain::tendermint::TendermintChain; |
| 12 | +use relayer::chain::Chain; |
| 13 | +use relayer::client::Client; |
| 14 | +use relayer::config::ChainConfig; |
| 15 | +use relayer::store::Store; |
| 16 | + |
16 | 17 | #[derive(Command, Debug, Options)]
|
17 | 18 | pub struct StartCmd {}
|
18 | 19 |
|
19 | 20 | impl Runnable for StartCmd {
|
20 |
| - /// Start the application. |
21 | 21 | fn run(&self) {
|
22 |
| - status_ok!("{}", "Quitting..."); |
| 22 | + let config = app_config().clone(); |
| 23 | + |
| 24 | + // FIXME: This just hangs and never runs the given future |
| 25 | + // abscissa_tokio::run(&APPLICATION, ...).unwrap(); |
| 26 | + |
| 27 | + block_on(async { |
| 28 | + for chain_config in config.chains { |
| 29 | + status_info!( |
| 30 | + "Relayer", |
| 31 | + "Spawning light client for chain {}", |
| 32 | + chain_config.id |
| 33 | + ); |
| 34 | + |
| 35 | + let _handle = tokio::spawn(async move { |
| 36 | + let client = create_client(chain_config).await; |
| 37 | + let trusted_state = client.last_trusted_state().unwrap(); |
| 38 | + |
| 39 | + status_ok!( |
| 40 | + client.chain().id(), |
| 41 | + "Spawned new client now at trusted state: {} at height {}", |
| 42 | + trusted_state.last_header().header().hash(), |
| 43 | + trusted_state.last_header().header().height(), |
| 44 | + ); |
| 45 | + |
| 46 | + update_headers(client).await; |
| 47 | + }); |
| 48 | + } |
| 49 | + |
| 50 | + start_relayer().await |
| 51 | + }) |
| 52 | + } |
| 53 | +} |
| 54 | + |
| 55 | +async fn start_relayer() { |
| 56 | + let mut interval = tokio::time::interval(Duration::from_secs(3)); |
| 57 | + |
| 58 | + loop { |
| 59 | + status_info!("Relayer", "Relayer is running"); |
| 60 | + |
| 61 | + interval.tick().await; |
23 | 62 | }
|
24 | 63 | }
|
| 64 | + |
| 65 | +async fn update_headers<C: Chain, S: Store<C>>(mut client: Client<C, S>) { |
| 66 | + let mut interval = tokio::time::interval(Duration::from_secs(3)); |
| 67 | + |
| 68 | + loop { |
| 69 | + let result = client.update(SystemTime::now()).await; |
| 70 | + |
| 71 | + match result { |
| 72 | + Ok(Some(trusted_state)) => status_ok!( |
| 73 | + client.chain().id(), |
| 74 | + "Updated to trusted state: {} at height {}", |
| 75 | + trusted_state.header().hash(), |
| 76 | + trusted_state.header().height() |
| 77 | + ), |
| 78 | + |
| 79 | + Ok(None) => status_info!(client.chain().id(), "Ignoring update to a previous state"), |
| 80 | + Err(err) => status_info!(client.chain().id(), "Error when updating headers: {}", err), |
| 81 | + } |
| 82 | + |
| 83 | + interval.tick().await; |
| 84 | + } |
| 85 | +} |
| 86 | + |
| 87 | +async fn create_client( |
| 88 | + chain_config: ChainConfig, |
| 89 | +) -> Client<TendermintChain, impl Store<TendermintChain>> { |
| 90 | + let chain = TendermintChain::from_config(chain_config).unwrap(); |
| 91 | + |
| 92 | + let store = relayer::store::persistent(format!("store_{}.db", chain.id())); |
| 93 | + let trust_options = store.get_trust_options().unwrap(); // FIXME: unwrap |
| 94 | + |
| 95 | + Client::new(chain, store, trust_options).await.unwrap() |
| 96 | +} |
| 97 | + |
| 98 | +fn block_on<F: Future>(future: F) -> F::Output { |
| 99 | + tokio::runtime::Builder::new() |
| 100 | + .basic_scheduler() |
| 101 | + .enable_all() |
| 102 | + .build() |
| 103 | + .unwrap() |
| 104 | + .block_on(future) |
| 105 | +} |
0 commit comments