gevulot_rs/
lib.rs

1/// This module contains the base client implementation.
2pub mod base_client;
3/// This module contains various builders for constructing messages.
4pub mod builders;
5/// This module contains the client implementation for Gevulot.
6pub mod gevulot_client;
7/// This module contains the client implementation for managing pins.
8pub mod pin_client;
9/// This module contains the client implementation for sudo functionality.
10pub mod sudo_client;
11/// This module contains the client implementation for managing tasks.
12pub mod task_client;
13/// This module contains the client implementation for managing workers.
14pub mod worker_client;
15/// This module contains the client implementation for managing workflows.
16pub mod workflow_client;
17
18pub mod models;
19pub mod runtime_config;
20
21pub mod error;
22pub mod event_fetcher;
23pub mod events;
24pub mod gov_client;
25/// This module contains the signer implementation.
26mod signer;
27
28/// This module contains the protocol buffer definitions.
29pub mod proto {
30    pub mod cosmos {
31        pub mod base {
32            pub mod query {
33                pub mod v1beta1 {
34                    tonic::include_proto!("cosmos.base.query.v1beta1");
35                }
36            }
37        }
38
39        pub mod app {
40            pub mod v1alpha1 {
41                tonic::include_proto!("cosmos.app.v1alpha1");
42            }
43        }
44    }
45
46    pub mod cosmos_proto {
47        tonic::include_proto!("cosmos_proto");
48    }
49
50    pub mod google {
51        tonic::include_proto!("google.api");
52    }
53
54    pub mod gevulot {
55        #![allow(clippy::module_inception)]
56        pub mod gevulot {
57            tonic::include_proto!("gevulot.gevulot");
58            pub mod module {
59                tonic::include_proto!("gevulot.gevulot.module");
60            }
61        }
62    }
63}
64
65pub use cosmrs::tendermint::abci::Event;
66pub use cosmrs::tendermint::block::Height;
67pub use error::{Error, Result};
68pub use event_fetcher::{EventFetcher, EventHandler};
69pub use events::GevulotEvent;
70pub use gevulot_client::{GevulotClient, GevulotClientBuilder};
71
72#[cfg(test)]
73mod tests {
74    use cosmrs::tendermint::block::Height;
75
76    use self::builders::ByteUnit::{Byte, Gigabyte};
77
78    use super::*;
79
80    /// Helper function to read Alice's seed and address from files.
81    fn alice() -> (String, String) {
82        let seed_path = "../../.dev-node/alice_seed.txt";
83        let seed = std::fs::read_to_string(seed_path).expect("Unable to read seed file");
84        let address_path = "../../.dev-node/alice_address.txt";
85        let address = std::fs::read_to_string(address_path).expect("Unable to read address file");
86        (seed.trim().to_string(), address.trim().to_string())
87    }
88
89    #[tokio::test]
90    async fn test_event_fetching() {
91        pretty_env_logger::init();
92
93        struct EventLogger;
94
95        impl event_fetcher::EventHandler for EventLogger {
96            async fn handle_event(
97                &mut self,
98                event: &crate::Event,
99                block_height: crate::Height,
100            ) -> crate::Result<()> {
101                match events::GevulotEvent::from_cosmos(event, block_height) {
102                    Ok(e) => println!("{:?}", e),
103                    Err(e) => println!("Error: {:?}", e),
104                }
105                Ok(())
106            }
107        }
108
109        let mut fetcher = event_fetcher::EventFetcher::new(
110            "http://127.0.0.1:26657",
111            Some(Height::from(0u32)),
112            tokio::time::Duration::from_secs(5),
113            EventLogger {},
114        );
115
116        fetcher.start_fetching().await.unwrap();
117    }
118
119    /// End-to-end test for the Gevulot client.
120    #[tokio::test]
121    async fn test_e2e() {
122        let (mnemonic, address) = alice();
123
124        let mut cli = GevulotClientBuilder::new()
125            .endpoint("http://127.0.0.1:9090") // default endpoint
126            .gas_price(0.025) // default gas price
127            .gas_multiplier(1.2) // default gas multiplier
128            .mnemonic(mnemonic.as_str())
129            .build()
130            .await
131            .unwrap();
132
133        // Register a worker
134        let worker_msg = builders::MsgCreateWorkerBuilder::default()
135            .creator(address.clone())
136            .name("test_worker".to_string())
137            .cpus(1000)
138            .gpus(1000)
139            .memory((32, Gigabyte).into())
140            .disk((128, Gigabyte).into())
141            .into_message()
142            .expect("Failed to build worker message");
143
144        let worker_id = cli.workers.create(worker_msg).await.unwrap().id;
145
146        // Create a pin
147        let pin_msg = builders::MsgCreatePinBuilder::default()
148            .creator(address.clone())
149            .cid(Some(
150                "QmSWeBJYvDqKUFG3om4gsrKGf379zk8Jq5tYXpDp7Xo".to_string(),
151            ))
152            .bytes((32, Byte).into())
153            .time(3600)
154            .redundancy(1)
155            .name("test".to_string())
156            .into_message()
157            .expect("Failed to build pin message");
158
159        cli.pins.create(pin_msg).await.unwrap();
160
161        // Delete the pin
162        let delete_pin_msg = builders::MsgDeletePinBuilder::default()
163            .creator(address.clone())
164            .cid("QmSWeBJYvDqKUFG3om4gsrKGf379zk8Jq5tYXpDp7Xo".to_string())
165            .into_message()
166            .expect("Failed to build pin message");
167
168        cli.pins.delete(delete_pin_msg).await.unwrap();
169
170        // Announce worker exit
171        let announce_exit_msg = builders::MsgAnnounceWorkerExitBuilder::default()
172            .creator(address.clone())
173            .worker_id(worker_id.clone())
174            .into_message()
175            .expect("Failed to build worker message");
176
177        cli.workers.announce_exit(announce_exit_msg).await.unwrap();
178
179        {
180            // Wait for 10 blocks to be mined
181            let mut base_client = cli.base_client.write().await;
182            let current_block = base_client.current_block().await.unwrap();
183            let current_height = current_block
184                .header
185                .as_ref()
186                .ok_or("Header not found")
187                .unwrap()
188                .height;
189            base_client
190                .wait_for_block(current_height + 10)
191                .await
192                .unwrap();
193        }
194
195        // Delete the worker
196        let delete_worker_msg = builders::MsgDeleteWorkerBuilder::default()
197            .creator(address.clone())
198            .id(worker_id.clone())
199            .into_message()
200            .expect("Failed to build worker message");
201
202        cli.workers.delete(delete_worker_msg).await.unwrap();
203    }
204}