hopli/
win_prob.rs

1//! This module contains arguments and functions to interact with the Winning Probability contract for a privileged account.
2//! It can set the global minimum winning probability and read the current global minimum winning probability.
3//! Some sample commands:
4//! - Set winning probability:
5//! ```text
6//! hopli win-prob set \
7//!     --network anvil-localhost \
8//!     --contracts-root "../ethereum/contracts" \
9//!     --winning-probability 0.5 \
10//!     --private-key ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
11//!     --provider-url "http://localhost:8545"
12//! ```
13//! - Get winning probability:
14//! ```text
15//! hopli win-prob get \
16//!     --network anvil-localhost \
17//!     --contracts-root "../ethereum/contracts" \
18//!     --provider-url "http://localhost:8545"
19//! ```
20use crate::key_pair::ArgEnvReader;
21use crate::{
22    environment_config::NetworkProviderArgs,
23    key_pair::PrivateKeyArgs,
24    utils::{Cmd, HelperErrors},
25};
26use clap::Parser;
27use hopr_bindings::hopr_winning_probability_oracle::HoprWinningProbabilityOracle;
28use hopr_internal_types::prelude::{f64_to_win_prob, win_prob_to_f64};
29use tracing::{debug, info};
30
31/// CLI arguments for `hopli win-prob`
32#[derive(Clone, Debug, Parser)]
33pub enum WinProbSubcommands {
34    /// Set the global minimum ticket winning probability as an owner
35    #[command(visible_alias = "s")]
36    Set {
37        /// Network name, contracts config file root, and customized provider, if available
38        #[command(flatten)]
39        network_provider: NetworkProviderArgs,
40
41        /// New winning probability
42        #[clap(help = "New winning probability", short = 'w', long, default_value_t = 1.0f64)]
43        winning_probability: f64,
44
45        /// Access to the private key of a manager of Network Registry contract
46        #[command(flatten)]
47        private_key: PrivateKeyArgs,
48    },
49
50    /// Read the current global minimum winning probability
51    #[command(visible_alias = "g")]
52    Get {
53        /// Network name, contracts config file root, and customized provider, if available
54        #[command(flatten)]
55        network_provider: NetworkProviderArgs,
56    },
57}
58
59impl WinProbSubcommands {
60    pub async fn execute_set_win_prob(
61        network_provider: NetworkProviderArgs,
62        winning_probability: f64,
63        private_key: PrivateKeyArgs,
64    ) -> Result<(), HelperErrors> {
65        // Read the private key from arguments or the "PRIVATE_KEY" environment variable
66        let signer_private_key = private_key.read("PRIVATE_KEY")?;
67
68        // get RPC provider for the given network and environment
69        let rpc_provider = network_provider.get_provider_with_signer(&signer_private_key).await?;
70        let contract_addresses = network_provider.get_network_details_from_name()?;
71
72        let hopr_win_prob = HoprWinningProbabilityOracle::new(
73            contract_addresses.addresses.winning_probability_oracle,
74            rpc_provider.clone(),
75        );
76
77        // convert the winning probability to the format required by the contract
78        let winning_probability = f64_to_win_prob(winning_probability).map_err(|_| {
79            HelperErrors::ParseError("Failed to convert winning probability to the required format".into())
80        })?;
81
82        // convert the new winning probability
83        let mut win_prob_param = [0u8; 8];
84        win_prob_param[1..].copy_from_slice(&winning_probability);
85        let win_prob_param = u64::from_be_bytes(win_prob_param);
86
87        info!(
88            "Setting the global minimum winning probability to {:?} ({:?} in uint56 format)",
89            winning_probability, win_prob_param
90        );
91
92        hopr_win_prob
93            .set_win_prob(win_prob_param)
94            .send()
95            .await
96            .map_err(|e| HelperErrors::MiddlewareError(format!("Failed in broadcasting transactions {:?}", e)))?
97            .await
98            .map_err(|e| HelperErrors::MiddlewareError(format!("Failed in getting receipt {:?}", e)))?;
99        Ok(())
100    }
101
102    pub async fn execute_get_win_prob(network_provider: NetworkProviderArgs) -> Result<f64, HelperErrors> {
103        // get RPC provider for the given network and environment
104        let rpc_provider = network_provider.get_provider_without_signer().await?;
105        let contract_addresses = network_provider.get_network_details_from_name()?;
106
107        let hopr_win_prob = HoprWinningProbabilityOracle::new(
108            contract_addresses.addresses.winning_probability_oracle,
109            rpc_provider.clone(),
110        );
111
112        // get winning probability from the contract
113        let current_win_prob = hopr_win_prob
114            .current_win_prob()
115            .await
116            .map_err(|e| HelperErrors::MiddlewareError(format!("Failed to get current winning probability: {}", e)))?;
117
118        // convert into f64
119        let mut tmp = [0u8; 7];
120        tmp.copy_from_slice(&current_win_prob.to_be_bytes()[1..]);
121        let current_win_prob_f64 = win_prob_to_f64(&tmp);
122        info!(
123            "Current global minimum winning probability is {:?} ({:?} in uint56 format)",
124            current_win_prob_f64, current_win_prob
125        );
126        Ok(current_win_prob_f64)
127    }
128}
129
130impl Cmd for WinProbSubcommands {
131    /// Run the execute_register function.
132    /// By default, registration is done by manager wallet
133    fn run(self) -> Result<(), HelperErrors> {
134        Ok(())
135    }
136
137    async fn async_run(self) -> Result<(), HelperErrors> {
138        match self {
139            WinProbSubcommands::Set {
140                network_provider,
141                winning_probability,
142                private_key,
143            } => {
144                WinProbSubcommands::execute_set_win_prob(network_provider, winning_probability, private_key).await?;
145            }
146            WinProbSubcommands::Get { network_provider } => {
147                let win_prob = WinProbSubcommands::execute_get_win_prob(network_provider).await?;
148                debug!("Current global minimum winning probability is: {}", win_prob);
149            }
150        }
151        Ok(())
152    }
153}