deep_space/client/
invariant.rs

1use crate::client::type_urls::MSG_VERIFY_INVARIANT_TYPE_URL;
2use crate::error::CosmosGrpcError;
3use crate::{Coin, Contact, Msg, PrivateKey};
4use cosmos_sdk_proto::cosmos::crisis::v1beta1::MsgVerifyInvariant;
5use cosmos_sdk_proto::cosmos::tx::v1beta1::SimulateResponse;
6use std::time::Duration;
7
8use super::send::TransactionResponse;
9
10impl Contact {
11    /// A utility function which simulates the specified invariant and returns the given SimulationResponse
12    ///
13    /// # Arguments
14    /// * `module_name` - The module containing the invariant to check
15    /// * `invariant_name` - The name of the invariant to check
16    /// * `private_key` - A private key used to sign and send the transaction
17    ///
18    /// # Examples
19    /// ```rust
20    /// use cosmos_sdk_proto::cosmos::bank::v1beta1::MsgSend;
21    /// use cosmos_sdk_proto::cosmos::tx::v1beta1::BroadcastMode;
22    /// use deep_space::{Coin, client::Contact, Fee, MessageArgs, Msg, PrivateKey, CosmosPrivateKey};
23    /// use std::time::Duration;
24    /// let private_key = CosmosPrivateKey::from_secret("mySecret".as_bytes());
25    /// let contact = Contact::new("https:://your-grpc-server", Duration::from_secs(5), "prefix").unwrap();
26    /// // future must be awaited in tokio runtime
27    /// contact.invariant_check("gravity", "module-balance", private_key);
28    /// ```
29    pub async fn invariant_check(
30        &self,
31        module_name: &str,
32        invariant_name: &str,
33        private_key: impl PrivateKey,
34    ) -> Result<SimulateResponse, CosmosGrpcError> {
35        trace!("Creating simulated invariant transaction");
36        let our_address = private_key.to_address(&self.chain_prefix).unwrap();
37
38        let verify = MsgVerifyInvariant {
39            sender: our_address.to_string(),
40            invariant_module_name: module_name.to_string(),
41            invariant_route: invariant_name.to_string(),
42        };
43        let msg = Msg::new(MSG_VERIFY_INVARIANT_TYPE_URL, verify);
44        trace!("Submitting simulation");
45        let block_params = self.get_block_params().await?;
46        self.simulate_tx(&[msg], None, private_key, block_params.max_gas)
47            .await
48    }
49
50    /// A utility function which executes the specified invariant and returns the TxResponse if one is given
51    /// NOTE: In testing this method does not actually halt the chain due to a cosmos-sdk bug
52    ///
53    /// # Arguments
54    /// * `module_name` - The module containing the invariant to check
55    /// * `invariant_name` - The name of the invariant to check
56    /// * `wait_timeout` - The amount of time to wait for the chain to respond
57    /// * `private_key` - A private key used to sign and send the transaction
58    ///
59    /// # Examples
60    /// ```rust
61    /// use cosmos_sdk_proto::cosmos::bank::v1beta1::MsgSend;
62    /// use cosmos_sdk_proto::cosmos::tx::v1beta1::BroadcastMode;
63    /// use deep_space::{Coin, client::Contact, Fee, MessageArgs, Msg, PrivateKey, PublicKey, CosmosPrivateKey};
64    /// use std::time::Duration;
65    /// let private_key = CosmosPrivateKey::from_secret("mySecret".as_bytes());
66    /// let public_key = private_key.to_public_key("cosmospub").unwrap();
67    /// let address = public_key.to_address();
68    /// let coin = Coin {
69    ///     denom: "validatortoken".to_string(),
70    ///     amount: 1u32.into(),
71    /// };
72    /// let contact = Contact::new("https:://your-grpc-server", Duration::from_secs(5), "prefix").unwrap();
73    /// // future must be awaited in tokio runtime
74    /// contact.invariant_halt("gravity", "module-balance", Some(coin), Duration::from_secs(30), private_key);
75    /// ```
76    pub async fn invariant_halt(
77        &self,
78        module_name: &str,
79        invariant_name: &str,
80        fee_coin: Option<Coin>,
81        wait_timeout: Duration,
82        private_key: impl PrivateKey,
83    ) -> Result<TransactionResponse, CosmosGrpcError> {
84        trace!("Creating chain-halting invariant transaction");
85        let our_address = private_key.to_address(&self.chain_prefix).unwrap();
86
87        let verify = MsgVerifyInvariant {
88            sender: our_address.to_string(),
89            invariant_module_name: module_name.to_string(),
90            invariant_route: invariant_name.to_string(),
91        };
92        let msg = Msg::new(MSG_VERIFY_INVARIANT_TYPE_URL, verify);
93        trace!("Submitting chain-halting invariant");
94        self.send_message(
95            &[msg],
96            Some("AAAAAAAHHHHHHH".to_string()),
97            &[fee_coin.unwrap_or_default()],
98            Some(wait_timeout),
99            None,
100            private_key,
101        )
102        .await
103    }
104}