hopr_api/chain/values.rs
1use std::{error::Error, time::Duration};
2
3pub use hopr_chain_types::ContractAddresses;
4use hopr_crypto_types::prelude::Hash;
5pub use hopr_internal_types::prelude::WinningProbability;
6pub use hopr_primitive_types::balance::HoprBalance;
7use hopr_primitive_types::{
8 balance::{Balance, Currency},
9 prelude::Address,
10};
11
12/// Contains domain separator information.
13#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14pub struct DomainSeparators {
15 /// HOPR Ledger smart contract domain separator.
16 pub ledger: Hash,
17 /// HOPR Node Safe Registry smart contract domain separator.
18 pub safe_registry: Hash,
19 /// HOPR Channels smart contract domain separator.
20 pub channel: Hash,
21}
22
23/// Contains information about the HOPR on-chain network deployment.
24#[derive(Clone, Debug, PartialEq, Eq)]
25pub struct ChainInfo {
26 /// ID of the blockchain network (e.g.: `0x64` for Gnosis Chain)
27 pub chain_id: u64,
28 /// Name of the HOPR network (e.g.: `dufour`)
29 pub hopr_network_name: String,
30 /// Addresses of the deployed HOPR smart contracts.
31 pub contract_addresses: ContractAddresses,
32}
33
34/// Retrieves various on-chain information.
35#[async_trait::async_trait]
36#[auto_impl::auto_impl(&, Box, Arc)]
37pub trait ChainValues {
38 type Error: Error + Send + Sync + 'static;
39
40 /// Returns the native or token currency balance of the given on-chain account.
41 async fn balance<C: Currency, A: Into<Address> + Send>(&self, address: A) -> Result<Balance<C>, Self::Error>;
42 /// Retrieves the domain separators of HOPR smart contracts.
43 async fn domain_separators(&self) -> Result<DomainSeparators, Self::Error>;
44 /// Retrieves the network-set minimum incoming ticket winning probability.
45 async fn minimum_incoming_ticket_win_prob(&self) -> Result<WinningProbability, Self::Error>;
46 /// Retrieves the network-set minimum ticket price.
47 async fn minimum_ticket_price(&self) -> Result<HoprBalance, Self::Error>;
48 /// Retrieves the current key binding fee
49 /// used for new key-binding [announcements](crate::chain::ChainWriteAccountOperations::announce).
50 async fn key_binding_fee(&self) -> Result<HoprBalance, Self::Error>;
51 /// Gets the grace period for channel closure finalization.
52 async fn channel_closure_notice_period(&self) -> Result<Duration, Self::Error>;
53 /// Gets the information about the HOPR network on-chain deployment.
54 async fn chain_info(&self) -> Result<ChainInfo, Self::Error>;
55 /// Convenience function to determine the winning probability and ticket price for outgoing
56 /// tickets.
57 async fn outgoing_ticket_values(
58 &self,
59 cfg_out_wp: Option<WinningProbability>,
60 cfg_out_price: Option<HoprBalance>,
61 ) -> Result<(WinningProbability, HoprBalance), Self::Error> {
62 // This operation hits the cache unless the new value is fetched for the first time
63 // NOTE: as opposed to the winning probability, the ticket price does not have
64 // a reasonable default, and therefore the operation fails
65 let network_ticket_price = self.minimum_ticket_price().await?;
66
67 let outgoing_ticket_price = cfg_out_price.unwrap_or(network_ticket_price);
68
69 // This operation hits the cache unless the new value is fetched for the first time
70 let network_win_prob = self
71 .minimum_incoming_ticket_win_prob()
72 .await
73 .inspect_err(|error| tracing::error!(%error, "failed to determine current network winning probability"))
74 .ok();
75
76 // If no explicit winning probability is configured, use the network value
77 // or 1 if the network value was not determined.
78 // This code does not take the max from those, as it is the upper layer's responsibility
79 // to ensure the configured value is not smaller than the network value.
80 let outgoing_ticket_win_prob = cfg_out_wp.or(network_win_prob).unwrap_or_default(); // Absolute default WinningProbability is 1.0
81
82 Ok((outgoing_ticket_win_prob, outgoing_ticket_price))
83 }
84}