// Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::nyxd::Gas; use crate::nyxd::{Coin, GasPrice}; use cosmrs::{tx, AccountId}; use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter}; pub mod gas_price; pub type GasAdjustment = f32; pub const DEFAULT_SIMULATED_GAS_MULTIPLIER: GasAdjustment = 1.5; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AutoFeeGrant { pub gas_adjustment: Option, pub payer: Option, pub granter: Option, } impl Display for AutoFeeGrant { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { if let Some(gas_adjustment) = self.gas_adjustment { write!(f, "Feegrant in auto mode with {gas_adjustment} simulated multiplier with {:?} payer and {:?} granter", self.payer, self.granter) } else { write!(f, "Feegrant in auto mode with no custom simulated multiplier with {:?} payer and {:?} granter", self.payer, self.granter) } } } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum Fee { Manual(tx::Fee), Auto(Option), PayerGranterAuto(AutoFeeGrant), } impl Display for Fee { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { Fee::Manual(fee) => { write!(f, "Fee in manual mode with ")?; for fee in &fee.amount { write!(f, "{}{} paid in fees, ", fee.amount, fee.denom)?; } write!(f, "{} set as gas limit, ", fee.gas_limit)?; if let Some(payer) = &fee.payer { write!(f, "{payer} set as payer, ")?; } if let Some(granter) = &fee.granter { write!(f, "{granter} set as granter")?; } Ok(()) } Fee::Auto(Some(multiplier)) => { write!(f, "Fee in auto mode with {multiplier} simulated multiplier") } Fee::Auto(None) => write!(f, "Fee in auto mode with no custom simulated multiplier"), Fee::PayerGranterAuto(auto_feegrant) => write!(f, "{}", auto_feegrant), } } } impl Fee { pub fn manual_with_gas_price(fee: Coin, gas_price: GasPrice) -> Self { let gas_limit = &fee / gas_price; Fee::Manual(tx::Fee::from_amount_and_gas(fee.into(), gas_limit)) } pub fn new_payer_granter_auto( gas_adjustment: Option, payer: Option, granter: Option, ) -> Self { Fee::PayerGranterAuto(AutoFeeGrant { gas_adjustment, payer, granter, }) } pub fn try_get_manual_amount(&self) -> Option> { match self { Fee::Manual(tx_fee) => Some(tx_fee.amount.iter().cloned().map(Into::into).collect()), _ => None, } } } impl From for Fee { fn from(fee: tx::Fee) -> Self { Fee::Manual(fee) } } impl From for Fee { fn from(multiplier: GasAdjustment) -> Self { Fee::Auto(Some(multiplier)) } } impl Default for Fee { fn default() -> Self { Fee::Auto(Some(DEFAULT_SIMULATED_GAS_MULTIPLIER)) } } pub trait GasAdjustable { fn adjust_gas(&self, adjustment: GasAdjustment) -> Self; } impl GasAdjustable for Gas { fn adjust_gas(&self, adjustment: GasAdjustment) -> Self { if adjustment == 1.0 { *self } else { let adjusted = (*self as f32 * adjustment).ceil(); adjusted as u64 } } }