Skip to main content

nym_validator_client/nyxd/fee/
mod.rs

1// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::nyxd::Gas;
5use crate::nyxd::{Coin, GasPrice};
6use cosmrs::{tx, AccountId};
7use serde::{Deserialize, Serialize};
8use std::fmt::{Display, Formatter};
9
10pub mod gas_price;
11
12pub type GasAdjustment = f32;
13
14pub const DEFAULT_SIMULATED_GAS_MULTIPLIER: GasAdjustment = 1.5;
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct AutoFeeGrant {
18    pub gas_adjustment: Option<GasAdjustment>,
19    pub payer: Option<AccountId>,
20    pub granter: Option<AccountId>,
21}
22
23impl Display for AutoFeeGrant {
24    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
25        if let Some(gas_adjustment) = self.gas_adjustment {
26            write!(f, "Feegrant in auto mode with {gas_adjustment} simulated multiplier with {:?} payer and {:?} granter", self.payer, self.granter)
27        } else {
28            write!(f, "Feegrant in auto mode with no custom simulated multiplier with {:?} payer and {:?} granter", self.payer, self.granter)
29        }
30    }
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize)]
34pub enum Fee {
35    Manual(tx::Fee),
36    Auto(Option<GasAdjustment>),
37    PayerGranterAuto(AutoFeeGrant),
38}
39
40impl Display for Fee {
41    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
42        match self {
43            Fee::Manual(fee) => {
44                write!(f, "Fee in manual mode with ")?;
45                for fee in &fee.amount {
46                    write!(f, "{}{} paid in fees, ", fee.amount, fee.denom)?;
47                }
48                write!(f, "{} set as gas limit, ", fee.gas_limit)?;
49                if let Some(payer) = &fee.payer {
50                    write!(f, "{payer} set as payer, ")?;
51                }
52                if let Some(granter) = &fee.granter {
53                    write!(f, "{granter} set as granter")?;
54                }
55                Ok(())
56            }
57            Fee::Auto(Some(multiplier)) => {
58                write!(f, "Fee in auto mode with {multiplier} simulated multiplier")
59            }
60            Fee::Auto(None) => write!(f, "Fee in auto mode with no custom simulated multiplier"),
61            Fee::PayerGranterAuto(auto_feegrant) => write!(f, "{}", auto_feegrant),
62        }
63    }
64}
65
66impl Fee {
67    pub fn manual_with_gas_price(fee: Coin, gas_price: GasPrice) -> Self {
68        let gas_limit = &fee / gas_price;
69
70        Fee::Manual(tx::Fee::from_amount_and_gas(fee.into(), gas_limit))
71    }
72
73    pub fn new_payer_granter_auto(
74        gas_adjustment: Option<GasAdjustment>,
75        payer: Option<AccountId>,
76        granter: Option<AccountId>,
77    ) -> Self {
78        Fee::PayerGranterAuto(AutoFeeGrant {
79            gas_adjustment,
80            payer,
81            granter,
82        })
83    }
84    pub fn try_get_manual_amount(&self) -> Option<Vec<Coin>> {
85        match self {
86            Fee::Manual(tx_fee) => Some(tx_fee.amount.iter().cloned().map(Into::into).collect()),
87            _ => None,
88        }
89    }
90}
91
92impl From<tx::Fee> for Fee {
93    fn from(fee: tx::Fee) -> Self {
94        Fee::Manual(fee)
95    }
96}
97
98impl From<GasAdjustment> for Fee {
99    fn from(multiplier: GasAdjustment) -> Self {
100        Fee::Auto(Some(multiplier))
101    }
102}
103
104impl Default for Fee {
105    fn default() -> Self {
106        Fee::Auto(Some(DEFAULT_SIMULATED_GAS_MULTIPLIER))
107    }
108}
109
110pub trait GasAdjustable {
111    fn adjust_gas(&self, adjustment: GasAdjustment) -> Self;
112}
113
114impl GasAdjustable for Gas {
115    fn adjust_gas(&self, adjustment: GasAdjustment) -> Self {
116        if adjustment == 1.0 {
117            *self
118        } else {
119            let adjusted = (*self as f32 * adjustment).ceil();
120            adjusted as u64
121        }
122    }
123}